diff options
-rw-r--r-- | src/emu/cpu/sh4/sh4.c | 711 | ||||
-rw-r--r-- | src/emu/cpu/sh4/sh4dasm.c | 2 |
2 files changed, 602 insertions, 111 deletions
diff --git a/src/emu/cpu/sh4/sh4.c b/src/emu/cpu/sh4/sh4.c index aacc951245e..61e26701aed 100644 --- a/src/emu/cpu/sh4/sh4.c +++ b/src/emu/cpu/sh4/sh4.c @@ -25,9 +25,12 @@ #include "debugger.h" #include "sh4.h" #include "sh4regs.h" +#include <math.h> /* speed up delay loops, bail out of tight loops */ #define BUSY_LOOP_HACKS 0 +/* work only as described in the datasheet */ +#define DATASHEET_STRICT 0 #define VERBOSE 0 @@ -41,6 +44,19 @@ #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; @@ -84,6 +100,7 @@ typedef struct int is_slave, cpu_number; int cpu_clock, bus_clock, pm_clock; + int fpu_sz, fpu_pr; void (*ftcsr_read_callback)(UINT32 data); } SH4; @@ -270,6 +287,37 @@ int s; } } +static void sh4_swap_fp_registers(void) +{ +int s; +UINT32 z; + + for (s = 0;s <= 15;s++) + { + z = sh4.fr[s]; + sh4.fr[s] = sh4.xf[s]; + sh4.xf[s] = z; + } +} + +#ifdef LSB_FIRST +static void sh4_swap_fp_couples(void) +{ +int s; +UINT32 z; + + for (s = 0;s <= 15;s = s+2) + { + z = sh4.fr[s]; + sh4.fr[s] = sh4.fr[s + 1]; + sh4.fr[s + 1] = z; + z = sh4.xf[s]; + sh4.xf[s] = sh4.xf[s + 1]; + sh4.xf[s + 1] = z; + } +} +#endif + #ifdef MAME_DEBUG static void sh4_syncronize_register_bank(int to) { @@ -415,19 +463,6 @@ int a,irq,z; sh4_exception(message, irq); } -static void sh4_swap_fp_registers(void) -{ -int s; -UINT32 z; - - for (s = 0;s <= 15;s++) - { - z = sh4.fr[s]; - sh4.fr[s] = sh4.xf[s]; - sh4.xf[s] = z; - } -} - /* code cycles t-bit * 0011 nnnn mmmm 1100 1 - * ADD Rm,Rn @@ -2174,6 +2209,12 @@ UINT32 s; sh4.r[m] += 4; if ((s & FR) != (sh4.fpscr & FR)) sh4_swap_fp_registers(); +#ifdef LSB_FIRST + if ((s & PR) != (sh4.fpscr & PR)) + sh4_swap_fp_couples(); +#endif + sh4.fpu_sz = (sh4.fpscr & SZ) ? 1 : 0; + sh4.fpu_pr = (sh4.fpscr & PR) ? 1 : 0; } /* LDC.L @Rm+,DBR */ @@ -2223,6 +2264,12 @@ UINT32 s; sh4.fpscr = sh4.r[m] & 0x003FFFFF; if ((s & FR) != (sh4.fpscr & FR)) sh4_swap_fp_registers(); +#ifdef LSB_FIRST + if ((s & PR) != (sh4.fpscr & PR)) + sh4_swap_fp_couples(); +#endif + sh4.fpu_sz = (sh4.fpscr & SZ) ? 1 : 0; + sh4.fpu_pr = (sh4.fpscr & PR) ? 1 : 0; } /* LDC Rm,DBR */ @@ -2290,11 +2337,11 @@ UINT32 addr,dest,sq; else dest |= (sh4.m[QACR1] & 0x1C) << 24; addr = addr & 0xFFFFFFE0; - for (a = 0;a < 8;a++) + for (a = 0;a < 4;a++) { - program_write_dword_64le(dest, program_read_dword_64le(addr)); - addr += 4; - dest += 4; + program_write_qword_64le(dest, program_read_qword_64le(addr)); + addr += 8; + dest += 8; } } } @@ -2774,20 +2821,24 @@ INLINE void op1110(UINT16 opcode) MOVI(opcode & 0xff, Rn); } +/* FMOV.S @Rm+,FRn PR=0 SZ=0 1111nnnnmmmm1001 */ /* FMOV @Rm+,DRn PR=0 SZ=1 1111nnn0mmmm1001 */ /* FMOV @Rm+,XDn PR=1 1111nnn1mmmm1001 */ -/* FMOV.S @Rm+,FRn PR=0 SZ=0 1111nnnnmmmm1001 */ INLINE void FMOVMRIFR(UINT32 m,UINT32 n) { - if (sh4.fpscr & PR) { /* PR = 1 */ + if (sh4.fpu_pr) { /* PR = 1 */ n = n & 14; sh4.ea = sh4.r[m]; + sh4.r[m] += 8; +#ifdef LSB_FIRST + sh4.xf[n+1] = RL( sh4.ea ); + sh4.xf[n] = RL( sh4.ea+4 ); +#else sh4.xf[n] = RL( sh4.ea ); - sh4.r[m] += 4; - sh4.xf[n+1] = RL( sh4.r[m] ); - sh4.r[m] += 4; + sh4.xf[n+1] = RL( sh4.ea+4 ); +#endif } else { /* PR = 0 */ - if (sh4.fpscr & SZ) { /* SZ = 1 */ + if (sh4.fpu_sz) { /* SZ = 1 */ n = n & 14; sh4.ea = sh4.r[m]; sh4.fr[n] = RL( sh4.ea ); @@ -2802,18 +2853,23 @@ INLINE void FMOVMRIFR(UINT32 m,UINT32 n) } } -/* FMOV XDm,@Rn PR=1 1111nnnnmmm11010 */ /* FMOV.S FRm,@Rn PR=0 SZ=0 1111nnnnmmmm1010 */ /* FMOV DRm,@Rn PR=0 SZ=1 1111nnnnmmm01010 */ +/* FMOV XDm,@Rn PR=1 1111nnnnmmm11010 */ INLINE void FMOVFRMR(UINT32 m,UINT32 n) { - if (sh4.fpscr & PR) { /* PR = 1 */ + if (sh4.fpu_pr) { /* PR = 1 */ m= m & 14; sh4.ea = sh4.r[n]; +#ifdef LSB_FIRST + WL( sh4.ea,sh4.xf[m+1] ); + WL( sh4.ea+4,sh4.xf[m] ); +#else WL( sh4.ea,sh4.xf[m] ); WL( sh4.ea+4,sh4.xf[m+1] ); +#endif } else { /* PR = 0 */ - if (sh4.fpscr & SZ) { /* SZ = 1 */ + if (sh4.fpu_sz) { /* SZ = 1 */ m= m & 14; sh4.ea = sh4.r[n]; WL( sh4.ea,sh4.fr[m] ); @@ -2825,19 +2881,24 @@ INLINE void FMOVFRMR(UINT32 m,UINT32 n) } } -/* FMOV XDm,@-Rn PR=1 1111nnnnmmm11011 */ /* FMOV.S FRm,@-Rn PR=0 SZ=0 1111nnnnmmmm1011 */ /* FMOV DRm,@-Rn PR=0 SZ=1 1111nnnnmmm01011 */ +/* FMOV XDm,@-Rn PR=1 1111nnnnmmm11011 */ INLINE void FMOVFRMDR(UINT32 m,UINT32 n) { - if (sh4.fpscr & PR) { /* PR = 1 */ + if (sh4.fpu_pr) { /* PR = 1 */ m= m & 14; sh4.r[n] -= 8; sh4.ea = sh4.r[n]; +#ifdef LSB_FIRST + WL( sh4.ea,sh4.xf[m+1] ); + WL( sh4.ea+4,sh4.xf[m] ); +#else WL( sh4.ea,sh4.xf[m] ); WL( sh4.ea+4,sh4.xf[m+1] ); +#endif } else { /* PR = 0 */ - if (sh4.fpscr & SZ) { /* SZ = 1 */ + if (sh4.fpu_sz) { /* SZ = 1 */ m= m & 14; sh4.r[n] -= 8; sh4.ea = sh4.r[n]; @@ -2851,30 +2912,23 @@ INLINE void FMOVFRMDR(UINT32 m,UINT32 n) } } -/* FLDI1 FRn 1111nnnn10011101 */ -INLINE void FLDI1(UINT32 n) -{ - sh4.fr[n] = 0x3F800000; -} - -/* FLDI0 FRn 1111nnnn10001101 */ -INLINE void FLDI0(UINT32 n) -{ - sh4.fr[n] = 0; -} - -/* FMOV XDm,@(R0,Rn) PR=1 1111nnnnmmm10111 */ /* FMOV.S FRm,@(R0,Rn) PR=0 SZ=0 1111nnnnmmmm0111 */ /* FMOV DRm,@(R0,Rn) PR=0 SZ=1 1111nnnnmmm00111 */ +/* FMOV XDm,@(R0,Rn) PR=1 1111nnnnmmm10111 */ INLINE void FMOVFRS0(UINT32 m,UINT32 n) { - if (sh4.fpscr & PR) { /* PR = 1 */ + if (sh4.fpu_pr) { /* PR = 1 */ m= m & 14; sh4.ea = sh4.r[0] + sh4.r[n]; +#ifdef LSB_FIRST + WL( sh4.ea,sh4.xf[m+1] ); + WL( sh4.ea+4,sh4.xf[m] ); +#else WL( sh4.ea,sh4.xf[m] ); WL( sh4.ea+4,sh4.xf[m+1] ); +#endif } else { /* PR = 0 */ - if (sh4.fpscr & SZ) { /* SZ = 1 */ + if (sh4.fpu_sz) { /* SZ = 1 */ m= m & 14; sh4.ea = sh4.r[0] + sh4.r[n]; WL( sh4.ea,sh4.fr[m] ); @@ -2886,18 +2940,23 @@ INLINE void FMOVFRS0(UINT32 m,UINT32 n) } } -/* FMOV @(R0,Rm),XDn PR=1 1111nnn1mmmm0110 */ /* FMOV.S @(R0,Rm),FRn PR=0 SZ=0 1111nnnnmmmm0110 */ /* FMOV @(R0,Rm),DRn PR=0 SZ=1 1111nnn0mmmm0110 */ +/* FMOV @(R0,Rm),XDn PR=1 1111nnn1mmmm0110 */ INLINE void FMOVS0FR(UINT32 m,UINT32 n) { - if (sh4.fpscr & PR) { /* PR = 1 */ + if (sh4.fpu_pr) { /* PR = 1 */ n= n & 14; sh4.ea = sh4.r[0] + sh4.r[m]; +#ifdef LSB_FIRST + sh4.xf[n+1] = RL( sh4.ea ); + sh4.xf[n] = RL( sh4.ea+4 ); +#else sh4.xf[n] = RL( sh4.ea ); sh4.xf[n+1] = RL( sh4.ea+4 ); +#endif } else { /* PR = 0 */ - if (sh4.fpscr & SZ) { /* SZ = 1 */ + if (sh4.fpu_sz) { /* SZ = 1 */ n= n & 14; sh4.ea = sh4.r[0] + sh4.r[m]; sh4.fr[n] = RL( sh4.ea ); @@ -2909,18 +2968,26 @@ INLINE void FMOVS0FR(UINT32 m,UINT32 n) } } -/* FMOV @Rm,XDn PR=1 1111nnn1mmmm1000 */ /* FMOV.S @Rm,FRn PR=0 SZ=0 1111nnnnmmmm1000 */ /* FMOV @Rm,DRn PR=0 SZ=1 1111nnn0mmmm1000 */ +/* FMOV @Rm,XDn PR=0 SZ=1 1111nnn1mmmm1000 */ +/* FMOV @Rm,XDn PR=1 1111nnn1mmmm1000 */ +/* FMOV @Rm,DRn PR=1 1111nnn0mmmm1000 */ INLINE void FMOVMRFR(UINT32 m,UINT32 n) { - if (sh4.fpscr & PR) { /* PR = 1 */ +#if DATASHEET_STRICT + if (sh4.fpu_pr) { /* PR = 1 */ n= n & 14; sh4.ea = sh4.r[m]; +#ifdef LSB_FIRST + sh4.xf[n+1] = RL( sh4.ea ); + sh4.xf[n] = RL( sh4.ea+4 ); +#else sh4.xf[n] = RL( sh4.ea ); sh4.xf[n+1] = RL( sh4.ea+4 ); +#endif } else { /* PR = 0 */ - if (sh4.fpscr & SZ) { /* SZ = 1 */ + if (sh4.fpu_sz) { /* SZ = 1 */ n= n & 14; sh4.ea = sh4.r[m]; sh4.fr[n] = RL( sh4.ea ); @@ -2930,6 +2997,126 @@ INLINE void FMOVMRFR(UINT32 m,UINT32 n) sh4.fr[n] = RL( sh4.ea ); } } +#else + if (sh4.fpu_pr) { /* PR = 1 */ + if (n & 1) { + n= n & 14; + sh4.ea = sh4.r[m]; +#ifdef LSB_FIRST + sh4.xf[n+1] = RL( sh4.ea ); + sh4.xf[n] = RL( sh4.ea+4 ); +#else + sh4.xf[n] = RL( sh4.ea ); + sh4.xf[n+1] = RL( sh4.ea+4 ); +#endif + } else { + n= n & 14; + sh4.ea = sh4.r[m]; +#ifdef LSB_FIRST + sh4.fr[n+1] = RL( sh4.ea ); + sh4.fr[n] = RL( sh4.ea+4 ); +#else + sh4.fr[n] = RL( sh4.ea ); + sh4.fr[n+1] = RL( sh4.ea+4 ); +#endif + } + } else { /* PR = 0 */ + if (sh4.fpu_sz) { /* SZ = 1 */ + if (n & 1) { + n= n & 14; + sh4.ea = sh4.r[m]; + sh4.xf[n] = RL( sh4.ea ); + sh4.xf[n+1] = RL( sh4.ea+4 ); + } else { + n= n & 14; + sh4.ea = sh4.r[m]; + sh4.fr[n] = RL( sh4.ea ); + sh4.fr[n+1] = RL( sh4.ea+4 ); + } + } else { /* SZ = 0 */ + sh4.ea = sh4.r[m]; + sh4.fr[n] = RL( sh4.ea ); + } + } +#endif +} + +/* FMOV FRm,FRn PR=0 SZ=0 FRm -> FRn 1111nnnnmmmm1100 */ +/* FMOV DRm,DRn PR=0 SZ=1 DRm -> DRn 1111nnn0mmm01100 */ +/* FMOV XDm,DRn PR=1 XDm -> DRn 1111nnn0mmm11100 */ +/* FMOV DRm,XDn PR=1 DRm -> XDn 1111nnn1mmm01100 */ +/* FMOV XDm,XDn PR=1 XDm -> XDn 1111nnn1mmm11100 */ +INLINE void FMOVFR(UINT32 m,UINT32 n) +{ +#if DATASHEET_STRICT + if (sh4.fpu_pr) { /* PR = 1 */ + if (m & 1) + if (n & 1) { + sh4.xf[n & 14] = sh4.xf[m & 14]; + sh4.xf[n | 1] = sh4.xf[m | 1]; + } else { + sh4.fr[n] = sh4.xf[m & 14]; + sh4.fr[n | 1] = sh4.xf[m | 1]; + } + else { + sh4.xf[n & 14] = sh4.fr[m]; + sh4.xf[n | 1] = sh4.fr[m|1]; // (a&14)+1 -> a|1 + } + } else { /* PR = 0 */ + if (sh4.fpu_sz) { /* SZ = 1 */ + sh4.fr[n] = sh4.fr[m]; + sh4.fr[n+1] = sh4.fr[m+1]; + } else { /* SZ = 0 */ + sh4.fr[n] = sh4.fr[m]; + } + } +#else + if (sh4.fpu_sz == 0) /* SZ = 0 */ + sh4.fr[n] = sh4.fr[m]; + else { /* SZ = 1 or PR = 1 */ + if (m & 1) + if (n & 1) { + sh4.xf[n & 14] = sh4.xf[m & 14]; + sh4.xf[n | 1] = sh4.xf[m | 1]; + } else { + sh4.fr[n] = sh4.xf[m & 14]; + sh4.fr[n | 1] = sh4.xf[m | 1]; + } + else { + if (n & 1) { + sh4.xf[n & 14] = sh4.fr[m]; + sh4.xf[n | 1] = sh4.fr[m | 1]; // (a&14)+1 -> a|1 + } else { + sh4.fr[n] = sh4.fr[m & 14]; + sh4.fr[n | 1] = sh4.fr[m | 1]; + } + } + } +#endif +} + +/* FLDI1 FRn 1111nnnn10011101 */ +INLINE void FLDI1(UINT32 n) +{ + sh4.fr[n] = 0x3F800000; +} + +/* FLDI0 FRn 1111nnnn10001101 */ +INLINE void FLDI0(UINT32 n) +{ + sh4.fr[n] = 0; +} + +/* FLDS FRm,FPUL 1111mmmm00011101 */ +INLINE void FLDS(UINT32 m) +{ + sh4.fpul = sh4.fr[m]; +} + +/* FSTS FPUL,FRn 1111nnnn00001101 */ +INLINE void FSTS(UINT32 n) +{ + sh4.fr[n] = sh4.fpul; } /* FRCHG 1111101111111101 */ @@ -2943,6 +3130,240 @@ INLINE void FRCHG(void) INLINE void FSCHG(void) { sh4.fpscr ^= SZ; + sh4.fpu_sz = (sh4.fpscr & SZ) ? 1 : 0; +} + +/* FTRC FRm,FPUL PR=0 1111mmmm00111101 */ +/* FTRC DRm,FPUL PR=1 1111mmm000111101 */ +INLINE void FTRC(UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + sh4.fpul = (INT32)FP_RFD(n); + } else { /* PR = 0 */ + /* read sh4.fr[n] as float -> truncate -> fpul(32) */ + sh4.fpul = (INT32)FP_RFS(n); + } +} + +/* FLOAT FPUL,FRn PR=0 1111nnnn00101101 */ +/* FLOAT FPUL,DRn PR=1 1111nnn000101101 */ +INLINE void FLOAT(UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + FP_RFD(n) = (double)(INT32)sh4.fpul; + } else { /* PR = 0 */ + FP_RFS(n) = (float)(INT32)sh4.fpul; + } +} + +/* FNEG FRn PR=0 1111nnnn01001101 */ +/* FNEG DRn PR=1 1111nnn001001101 */ +INLINE void FNEG(UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ +#ifdef LSB_FIRST + n = n | 1; // n & 14 + 1 + sh4.fr[n] = sh4.fr[n] ^ 0x80000000; +#else + n = n & 14; + sh4.fr[n] = sh4.fr[n] ^ 0x80000000; +#endif + } else { /* PR = 0 */ + sh4.fr[n] = sh4.fr[n] ^ 0x80000000; + } +} + + +/* FABS FRn PR=0 1111nnnn01011101 */ +/* FABS DRn PR=1 1111nnn001011101 */ +INLINE void FABS(UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ +#ifdef LSB_FIRST + n = n | 1; // n & 14 + 1 + sh4.fr[n] = sh4.fr[n] & 0x7fffffff; +#else + n = n & 14; + sh4.fr[n] = sh4.fr[n] & 0x7fffffff; +#endif + } else { /* PR = 0 */ + sh4.fr[n] = sh4.fr[n] & 0x7fffffff; + } +} + +/* FCMP/EQ FRm,FRn PR=0 1111nnnnmmmm0100 */ +/* FCMP/EQ DRm,DRn PR=1 1111nnn0mmm00100 */ +INLINE void FCMP_EQ(UINT32 m,UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + m = m & 14; + if (FP_RFD(n) == FP_RFD(m)) + sh4.sr |= T; + else + sh4.sr &= ~T; + } else { /* PR = 0 */ + if (FP_RFS(n) == FP_RFS(m)) + sh4.sr |= T; + else + sh4.sr &= ~T; + } +} + +/* FCMP/GT FRm,FRn PR=0 1111nnnnmmmm0101 */ +/* FCMP/GT DRm,DRn PR=1 1111nnn0mmm00101 */ +INLINE void FCMP_GT(UINT32 m,UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + m = m & 14; + if (FP_RFD(n) > FP_RFD(m)) + sh4.sr |= T; + else + sh4.sr &= ~T; + } else { /* PR = 0 */ + if (FP_RFS(n) > FP_RFS(m)) + sh4.sr |= T; + else + sh4.sr &= ~T; + } +} + +/* FCNVDS DRm,FPUL PR=1 1111mmm010111101 */ +INLINE void FCNVDS(UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; +#ifdef LSB_FIRST + if (sh4.fpscr & RM) + sh4.fr[n] &= 0xe0000000; /* round toward zero*/ +#else + if (sh4.fpscr & RM) + sh4.fr[n | 1] &= 0xe0000000; /* round toward zero*/ +#endif + *((float *)&sh4.fpul) = (float)FP_RFD(n); + } +} + +/* FCNVSD FPUL, DRn PR=1 1111nnn010101101 */ +INLINE void FCNVSD(UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + FP_RFD(n) = *((float *)&sh4.fpul); + } +} + +/* FADD FRm,FRn PR=0 1111nnnnmmmm0000 */ +/* FADD DRm,DRn PR=1 1111nnn0mmm00000 */ +INLINE void FADD(UINT32 m,UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + m = m & 14; + FP_RFD(n) = FP_RFD(n) + FP_RFD(m); + } else { /* PR = 0 */ + FP_RFS(n) = FP_RFS(n) + FP_RFS(m); + } +} + +/* FSUB FRm,FRn PR=0 1111nnnnmmmm0001 */ +/* FSUB DRm,DRn PR=1 1111nnn0mmm00001 */ +INLINE void FSUB(UINT32 m,UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + m = m & 14; + FP_RFD(n) = FP_RFD(n) - FP_RFD(m); + } else { /* PR = 0 */ + FP_RFS(n) = FP_RFS(n) - FP_RFS(m); + } +} + + +/* FMUL FRm,FRn PR=0 1111nnnnmmmm0010 */ +/* FMUL DRm,DRn PR=1 1111nnn0mmm00010 */ +INLINE void FMUL(UINT32 m,UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + m = m & 14; + FP_RFD(n) = FP_RFD(n) * FP_RFD(m); + } else { /* PR = 0 */ + FP_RFS(n) = FP_RFS(n) * FP_RFS(m); + } +} + +/* FDIV FRm,FRn PR=0 1111nnnnmmmm0011 */ +/* FDIV DRm,DRn PR=1 1111nnn0mmm00011 */ +INLINE void FDIV(UINT32 m,UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + m = m & 14; + if (FP_RFD(m) == 0) + return; + FP_RFD(n) = FP_RFD(n) / FP_RFD(m); + } else { /* PR = 0 */ + if (FP_RFS(m) == 0) + return; + FP_RFS(n) = FP_RFS(n) / FP_RFS(m); + } +} + +/* FMAC FR0,FRm,FRn PR=0 1111nnnnmmmm1110 */ +INLINE void FMAC(UINT32 m,UINT32 n) +{ + if (sh4.fpu_pr == 0) { /* PR = 0 */ + FP_RFS(n) = (FP_RFS(0) * FP_RFS(m)) + FP_RFS(n); + } +} + +/* FSQRT FRn PR=0 1111nnnn01101101 */ +/* FSQRT DRn PR=1 1111nnnn01101101 */ +INLINE void FSQRT(UINT32 n) +{ + if (sh4.fpu_pr) { /* PR = 1 */ + n = n & 14; + if (FP_RFD(n) < 0) + return; + FP_RFD(n) = sqrt(FP_RFD(n)); + } else { /* PR = 0 */ + if (FP_RFS(n) < 0) + return; + FP_RFS(n) = sqrt(FP_RFS(n)); + } +} + +/* FIPR FVm,FVn PR=0 1111nnmm11101101 */ +INLINE void FIPR(UINT32 n) +{ +UINT32 m; +float ml[4]; +int a; + + m = (n & 3) << 2; + n = n & 12; + for (a = 0;a < 4;a++) + ml[a] = FP_RFS(n+a) * FP_RFS(m+a); + FP_RFS(n+3) = ml[0] + ml[1] + ml[2] + ml[3]; +} + +/* FTRV XMTRX,FVn PR=0 1111nn0111111101 */ +INLINE void FTRV(UINT32 n) +{ +int i,j; +float sum[4]; + + n = n & 12; + for (i = 0;i < 4;i++) { + sum[i] = 0; + for (j=0;j < 4;j++) + sum[i] += FP_XFS((j << 2) + i)*FP_RFS(n + i); + FP_RFS(n + i) = sum[i]; + } } INLINE void op1111(UINT16 opcode) @@ -2950,22 +3371,22 @@ INLINE void op1111(UINT16 opcode) switch (opcode & 0xf) { case 0: - TODO(); + FADD(Rm,Rn); break; case 1: - TODO(); + FSUB(Rm,Rn); break; case 2: - TODO(); + FMUL(Rm,Rn); break; case 3: - TODO(); + FDIV(Rm,Rn); break; case 4: - TODO(); + FCMP_EQ(Rm,Rn); break; case 5: - TODO(); + FCMP_GT(Rm,Rn); break; case 6: FMOVS0FR(Rm,Rn); @@ -2986,31 +3407,31 @@ INLINE void op1111(UINT16 opcode) FMOVFRMDR(Rm,Rn); break; case 12: - TODO(); + FMOVFR(Rm,Rn); break; case 13: switch (opcode & 0xF0) { case 0x00: - TODO(); + FSTS(Rn); break; case 0x10: - TODO(); + FLDS(Rn); break; case 0x20: - TODO(); + FLOAT(Rn); break; case 0x30: - TODO(); + FTRC(Rn); break; case 0x40: - TODO(); + FNEG(Rn); break; case 0x50: - TODO(); + FABS(Rn); break; case 0x60: - TODO(); + FSQRT(Rn); break; case 0x80: FLDI0(Rn); @@ -3019,13 +3440,13 @@ INLINE void op1111(UINT16 opcode) FLDI1(Rn); break; case 0xA0: - TODO(); + FCNVSD(Rn); break; case 0xB0: - TODO(); + FCNVDS(Rn); break; case 0xE0: - TODO(); + FIPR(Rn); break; case 0xF0: if (opcode == 0xF3FD) @@ -3033,12 +3454,12 @@ INLINE void op1111(UINT16 opcode) else if (opcode == 0xFBFD) FRCHG(); else if ((opcode & 0x300) == 0x100) - TODO(); + FTRV(Rn); break; } break; case 14: - TODO(); + FMAC(Rm,Rn); break; } } @@ -3113,6 +3534,8 @@ static void sh4_reset(void) sh4.r[15] = RL(4); sh4.sr = 0x700000f0; sh4.fpscr = 0x00040001; + sh4.fpu_sz = (sh4.fpscr & SZ) ? 1 : 0; + sh4.fpu_pr = (sh4.fpscr & PR) ? 1 : 0; sh4.fpul = 0; sh4.dbr = 0; change_pc(sh4.pc & AM); @@ -3221,9 +3644,7 @@ UINT32 ticks; INLINE attotime sh4_scale_up_mame_time(attotime _time1, UINT32 factor1) { - if (factor1 == 0) - return attotime_zero; - return attotime_mul(_time1, factor1 + 1); + return attotime_add(attotime_mul(_time1, factor1), _time1); } static UINT32 compute_ticks_timer(emu_timer *timer, int hertz, int divisor) @@ -3499,7 +3920,7 @@ static int sh4_dma_transfer(int channel, int timermode, UINT32 chcr, UINT32 *sar switch(size) { - case 1: + case 1: // 8 bit for(;count > 0; count --) { if(incs == 2) @@ -3513,7 +3934,7 @@ static int sh4_dma_transfer(int channel, int timermode, UINT32 chcr, UINT32 *sar dst ++; } break; - case 2: + case 2: // 16 bit src &= ~1; dst &= ~1; for(;count > 0; count --) @@ -3529,7 +3950,7 @@ static int sh4_dma_transfer(int channel, int timermode, UINT32 chcr, UINT32 *sar dst += 2; } break; - case 8: + case 8: // 64 bit src &= ~7; dst &= ~7; for(;count > 0; count --) @@ -3546,7 +3967,7 @@ static int sh4_dma_transfer(int channel, int timermode, UINT32 chcr, UINT32 *sar } break; - case 4: + case 4: // 32 bit src &= ~3; dst &= ~3; for(;count > 0; count --) @@ -4307,7 +4728,7 @@ UINT32 pos,len,siz; } else { if ((s->direction) == 0) { len = s->length; - p32bits = (UINT32 *)(s->buffer); + p32bits = (UINT32 *)(s->buffer); for (pos = 0;pos < len;pos++) { *p32bits = program_read_dword_64le(s->source); p32bits++; @@ -4315,7 +4736,7 @@ UINT32 pos,len,siz; } } else { len = s->length; - p32bits = (UINT32 *)(s->buffer); + p32bits = (UINT32 *)(s->buffer); for (pos = 0;pos < len;pos++) { program_write_dword_64le(s->destination, *p32bits); p32bits++; @@ -4394,6 +4815,40 @@ static void sh4_set_info(UINT32 state, cpuinfo *info) case CPUINFO_STR_REGISTER + SH4_SGR: sh4.sgr = info->i; break; case CPUINFO_STR_REGISTER + SH4_FPSCR: sh4.fpscr = info->i; break; case CPUINFO_STR_REGISTER + SH4_FPUL: sh4.fpul = info->i; break; +#ifdef LSB_FIRST + case CPUINFO_STR_REGISTER + SH4_FR0: sh4.fr[ 0 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR1: sh4.fr[ 1 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR2: sh4.fr[ 2 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR3: sh4.fr[ 3 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR4: sh4.fr[ 4 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR5: sh4.fr[ 5 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR6: sh4.fr[ 6 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR7: sh4.fr[ 7 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR8: sh4.fr[ 8 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR9: sh4.fr[ 9 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR10: sh4.fr[10 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR11: sh4.fr[11 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR12: sh4.fr[12 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR13: sh4.fr[13 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR14: sh4.fr[14 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_FR15: sh4.fr[15 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF0: sh4.xf[ 0 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF1: sh4.xf[ 1 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF2: sh4.xf[ 2 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF3: sh4.xf[ 3 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF4: sh4.xf[ 4 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF5: sh4.xf[ 5 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF6: sh4.xf[ 6 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF7: sh4.xf[ 7 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF8: sh4.xf[ 8 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF9: sh4.xf[ 9 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF10: sh4.xf[10 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF11: sh4.xf[11 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF12: sh4.xf[12 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF13: sh4.xf[13 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF14: sh4.xf[14 ^ sh4.fpu_pr] = info->i; break; + case CPUINFO_STR_REGISTER + SH4_XF15: sh4.xf[15 ^ sh4.fpu_pr] = info->i; break; +#else case CPUINFO_STR_REGISTER + SH4_FR0: sh4.fr[ 0] = info->i; break; case CPUINFO_STR_REGISTER + SH4_FR1: sh4.fr[ 1] = info->i; break; case CPUINFO_STR_REGISTER + SH4_FR2: sh4.fr[ 2] = info->i; break; @@ -4426,6 +4881,7 @@ static void sh4_set_info(UINT32 state, cpuinfo *info) case CPUINFO_STR_REGISTER + SH4_XF13: sh4.xf[13] = info->i; break; case CPUINFO_STR_REGISTER + SH4_XF14: sh4.xf[14] = info->i; break; case CPUINFO_STR_REGISTER + SH4_XF15: sh4.xf[15] = info->i; break; +#endif case CPUINFO_INT_SH4_IRLn_INPUT: sh4_set_irln_input(cpu_getactivecpu(), info->i); break; case CPUINFO_INT_SH4_FRT_INPUT: sh4_set_frt_input(cpu_getactivecpu(), info->i); break; @@ -4599,38 +5055,73 @@ void sh4_get_info(UINT32 state, cpuinfo *info) case CPUINFO_STR_REGISTER + SH4_SGR: sprintf(info->s, "SGR :%08X", sh4.sgr); break; case CPUINFO_STR_REGISTER + SH4_FPSCR: sprintf(info->s, "FPSCR :%08X", sh4.fpscr); break; case CPUINFO_STR_REGISTER + SH4_FPUL: sprintf(info->s, "FPUL :%08X", sh4.fpul); break; - case CPUINFO_STR_REGISTER + SH4_FR0: sprintf(info->s, "FR0 :%08X", sh4.fr[ 0]); break; - case CPUINFO_STR_REGISTER + SH4_FR1: sprintf(info->s, "FR1 :%08X", sh4.fr[ 1]); break; - case CPUINFO_STR_REGISTER + SH4_FR2: sprintf(info->s, "FR2 :%08X", sh4.fr[ 2]); break; - case CPUINFO_STR_REGISTER + SH4_FR3: sprintf(info->s, "FR3 :%08X", sh4.fr[ 3]); break; - case CPUINFO_STR_REGISTER + SH4_FR4: sprintf(info->s, "FR4 :%08X", sh4.fr[ 4]); break; - case CPUINFO_STR_REGISTER + SH4_FR5: sprintf(info->s, "FR5 :%08X", sh4.fr[ 5]); break; - case CPUINFO_STR_REGISTER + SH4_FR6: sprintf(info->s, "FR6 :%08X", sh4.fr[ 6]); break; - case CPUINFO_STR_REGISTER + SH4_FR7: sprintf(info->s, "FR7 :%08X", sh4.fr[ 7]); break; - case CPUINFO_STR_REGISTER + SH4_FR8: sprintf(info->s, "FR8 :%08X", sh4.fr[ 8]); break; - case CPUINFO_STR_REGISTER + SH4_FR9: sprintf(info->s, "FR9 :%08X", sh4.fr[ 9]); break; - case CPUINFO_STR_REGISTER + SH4_FR10: sprintf(info->s, "FR10 :%08X", sh4.fr[10]); break; - case CPUINFO_STR_REGISTER + SH4_FR11: sprintf(info->s, "FR11 :%08X", sh4.fr[11]); break; - case CPUINFO_STR_REGISTER + SH4_FR12: sprintf(info->s, "FR12 :%08X", sh4.fr[12]); break; - case CPUINFO_STR_REGISTER + SH4_FR13: sprintf(info->s, "FR13 :%08X", sh4.fr[13]); break; - case CPUINFO_STR_REGISTER + SH4_FR14: sprintf(info->s, "FR14 :%08X", sh4.fr[14]); break; - case CPUINFO_STR_REGISTER + SH4_FR15: sprintf(info->s, "FR15 :%08X", sh4.fr[15]); break; - case CPUINFO_STR_REGISTER + SH4_XF0: sprintf(info->s, "XF0 :%08X", sh4.xf[ 0]); break; - case CPUINFO_STR_REGISTER + SH4_XF1: sprintf(info->s, "XF1 :%08X", sh4.xf[ 1]); break; - case CPUINFO_STR_REGISTER + SH4_XF2: sprintf(info->s, "XF2 :%08X", sh4.xf[ 2]); break; - case CPUINFO_STR_REGISTER + SH4_XF3: sprintf(info->s, "XF3 :%08X", sh4.xf[ 3]); break; - case CPUINFO_STR_REGISTER + SH4_XF4: sprintf(info->s, "XF4 :%08X", sh4.xf[ 4]); break; - case CPUINFO_STR_REGISTER + SH4_XF5: sprintf(info->s, "XF5 :%08X", sh4.xf[ 5]); break; - case CPUINFO_STR_REGISTER + SH4_XF6: sprintf(info->s, "XF6 :%08X", sh4.xf[ 6]); break; - case CPUINFO_STR_REGISTER + SH4_XF7: sprintf(info->s, "XF7 :%08X", sh4.xf[ 7]); break; - case CPUINFO_STR_REGISTER + SH4_XF8: sprintf(info->s, "XF8 :%08X", sh4.xf[ 8]); break; - case CPUINFO_STR_REGISTER + SH4_XF9: sprintf(info->s, "XF9 :%08X", sh4.xf[ 9]); break; - case CPUINFO_STR_REGISTER + SH4_XF10: sprintf(info->s, "XF10 :%08X", sh4.xf[10]); break; - case CPUINFO_STR_REGISTER + SH4_XF11: sprintf(info->s, "XF11 :%08X", sh4.xf[11]); break; - case CPUINFO_STR_REGISTER + SH4_XF12: sprintf(info->s, "XF12 :%08X", sh4.xf[12]); break; - case CPUINFO_STR_REGISTER + SH4_XF13: sprintf(info->s, "XF13 :%08X", sh4.xf[13]); break; - case CPUINFO_STR_REGISTER + SH4_XF14: sprintf(info->s, "XF14 :%08X", sh4.xf[14]); break; - case CPUINFO_STR_REGISTER + SH4_XF15: sprintf(info->s, "XF15 :%08X", sh4.xf[15]); break; +#ifdef LSB_FIRST + case CPUINFO_STR_REGISTER + SH4_FR0: sprintf(info->s, "FR0 :%08X %01.4e", FP_RS2( 0),(double)FP_RFS2( 0)); break; + case CPUINFO_STR_REGISTER + SH4_FR1: sprintf(info->s, "FR1 :%08X %01.2e", FP_RS2( 1),(double)FP_RFS2( 1)); break; + case CPUINFO_STR_REGISTER + SH4_FR2: sprintf(info->s, "FR2 :%08X %01.2e", FP_RS2( 2),(double)FP_RFS2( 2)); break; + case CPUINFO_STR_REGISTER + SH4_FR3: sprintf(info->s, "FR3 :%08X %01.2e", FP_RS2( 3),(double)FP_RFS2( 3)); break; + case CPUINFO_STR_REGISTER + SH4_FR4: sprintf(info->s, "FR4 :%08X %01.2e", FP_RS2( 4),(double)FP_RFS2( 4)); break; + case CPUINFO_STR_REGISTER + SH4_FR5: sprintf(info->s, "FR5 :%08X %01.2e", FP_RS2( 5),(double)FP_RFS2( 5)); break; + case CPUINFO_STR_REGISTER + SH4_FR6: sprintf(info->s, "FR6 :%08X %01.2e", FP_RS2( 6),(double)FP_RFS2( 6)); break; + case CPUINFO_STR_REGISTER + SH4_FR7: sprintf(info->s, "FR7 :%08X %01.2e", FP_RS2( 7),(double)FP_RFS2( 7)); break; + case CPUINFO_STR_REGISTER + SH4_FR8: sprintf(info->s, "FR8 :%08X %01.2e", FP_RS2( 8),(double)FP_RFS2( 8)); break; + case CPUINFO_STR_REGISTER + SH4_FR9: sprintf(info->s, "FR9 :%08X %01.2e", FP_RS2( 9),(double)FP_RFS2( 9)); break; + case CPUINFO_STR_REGISTER + SH4_FR10: sprintf(info->s, "FR10 :%08X %01.2e", FP_RS2(10),(double)FP_RFS2(10)); break; + case CPUINFO_STR_REGISTER + SH4_FR11: sprintf(info->s, "FR11 :%08X %01.2e", FP_RS2(11),(double)FP_RFS2(11)); break; + case CPUINFO_STR_REGISTER + SH4_FR12: sprintf(info->s, "FR12 :%08X %01.2e", FP_RS2(12),(double)FP_RFS2(12)); break; + case CPUINFO_STR_REGISTER + SH4_FR13: sprintf(info->s, "FR13 :%08X %01.2e", FP_RS2(13),(double)FP_RFS2(13)); break; + case CPUINFO_STR_REGISTER + SH4_FR14: sprintf(info->s, "FR14 :%08X %01.2e", FP_RS2(14),(double)FP_RFS2(14)); break; + case CPUINFO_STR_REGISTER + SH4_FR15: sprintf(info->s, "FR15 :%08X %01.2e", FP_RS2(15),(double)FP_RFS2(15)); break; + case CPUINFO_STR_REGISTER + SH4_XF0: sprintf(info->s, "XF0 :%08X %01.2e", FP_XS2( 0),(double)FP_XFS2( 0)); break; + case CPUINFO_STR_REGISTER + SH4_XF1: sprintf(info->s, "XF1 :%08X %01.2e", FP_XS2( 1),(double)FP_XFS2( 1)); break; + case CPUINFO_STR_REGISTER + SH4_XF2: sprintf(info->s, "XF2 :%08X %01.2e", FP_XS2( 2),(double)FP_XFS2( 2)); break; + case CPUINFO_STR_REGISTER + SH4_XF3: sprintf(info->s, "XF3 :%08X %01.2e", FP_XS2( 3),(double)FP_XFS2( 3)); break; + case CPUINFO_STR_REGISTER + SH4_XF4: sprintf(info->s, "XF4 :%08X %01.2e", FP_XS2( 4),(double)FP_XFS2( 4)); break; + case CPUINFO_STR_REGISTER + SH4_XF5: sprintf(info->s, "XF5 :%08X %01.2e", FP_XS2( 5),(double)FP_XFS2( 5)); break; + case CPUINFO_STR_REGISTER + SH4_XF6: sprintf(info->s, "XF6 :%08X %01.2e", FP_XS2( 6),(double)FP_XFS2( 6)); break; + case CPUINFO_STR_REGISTER + SH4_XF7: sprintf(info->s, "XF7 :%08X %01.2e", FP_XS2( 7),(double)FP_XFS2( 7)); break; + case CPUINFO_STR_REGISTER + SH4_XF8: sprintf(info->s, "XF8 :%08X %01.2e", FP_XS2( 8),(double)FP_XFS2( 8)); break; + case CPUINFO_STR_REGISTER + SH4_XF9: sprintf(info->s, "XF9 :%08X %01.2e", FP_XS2( 9),(double)FP_XFS2( 9)); break; + case CPUINFO_STR_REGISTER + SH4_XF10: sprintf(info->s, "XF10 :%08X %01.2e", FP_XS2(10),(double)FP_XFS2(10)); break; + case CPUINFO_STR_REGISTER + SH4_XF11: sprintf(info->s, "XF11 :%08X %01.2e", FP_XS2(11),(double)FP_XFS2(11)); break; + case CPUINFO_STR_REGISTER + SH4_XF12: sprintf(info->s, "XF12 :%08X %01.2e", FP_XS2(12),(double)FP_XFS2(12)); break; + case CPUINFO_STR_REGISTER + SH4_XF13: sprintf(info->s, "XF13 :%08X %01.2e", FP_XS2(13),(double)FP_XFS2(13)); break; + case CPUINFO_STR_REGISTER + SH4_XF14: sprintf(info->s, "XF14 :%08X %01.2e", FP_XS2(14),(double)FP_XFS2(14)); break; + case CPUINFO_STR_REGISTER + SH4_XF15: sprintf(info->s, "XF15 :%08X %01.2e", FP_XS2(15),(double)FP_XFS2(15)); break; +#else + case CPUINFO_STR_REGISTER + SH4_FR0: sprintf(info->s, "FR0 :%08X %01.4e", FP_RS( 0),(double)FP_RFS( 0)); break; + case CPUINFO_STR_REGISTER + SH4_FR1: sprintf(info->s, "FR1 :%08X %01.2e", FP_RS( 1),(double)FP_RFS( 1)); break; + case CPUINFO_STR_REGISTER + SH4_FR2: sprintf(info->s, "FR2 :%08X %01.2e", FP_RS( 2),(double)FP_RFS( 2)); break; + case CPUINFO_STR_REGISTER + SH4_FR3: sprintf(info->s, "FR3 :%08X %01.2e", FP_RS( 3),(double)FP_RFS( 3)); break; + case CPUINFO_STR_REGISTER + SH4_FR4: sprintf(info->s, "FR4 :%08X %01.2e", FP_RS( 4),(double)FP_RFS( 4)); break; + case CPUINFO_STR_REGISTER + SH4_FR5: sprintf(info->s, "FR5 :%08X %01.2e", FP_RS( 5),(double)FP_RFS( 5)); break; + case CPUINFO_STR_REGISTER + SH4_FR6: sprintf(info->s, "FR6 :%08X %01.2e", FP_RS( 6),(double)FP_RFS( 6)); break; + case CPUINFO_STR_REGISTER + SH4_FR7: sprintf(info->s, "FR7 :%08X %01.2e", FP_RS( 7),(double)FP_RFS( 7)); break; + case CPUINFO_STR_REGISTER + SH4_FR8: sprintf(info->s, "FR8 :%08X %01.2e", FP_RS( 8),(double)FP_RFS( 8)); break; + case CPUINFO_STR_REGISTER + SH4_FR9: sprintf(info->s, "FR9 :%08X %01.2e", FP_RS( 9),(double)FP_RFS( 9)); break; + case CPUINFO_STR_REGISTER + SH4_FR10: sprintf(info->s, "FR10 :%08X %01.2e", FP_RS(10),(double)FP_RFS(10)); break; + case CPUINFO_STR_REGISTER + SH4_FR11: sprintf(info->s, "FR11 :%08X %01.2e", FP_RS(11),(double)FP_RFS(11)); break; + case CPUINFO_STR_REGISTER + SH4_FR12: sprintf(info->s, "FR12 :%08X %01.2e", FP_RS(12),(double)FP_RFS(12)); break; + case CPUINFO_STR_REGISTER + SH4_FR13: sprintf(info->s, "FR13 :%08X %01.2e", FP_RS(13),(double)FP_RFS(13)); break; + case CPUINFO_STR_REGISTER + SH4_FR14: sprintf(info->s, "FR14 :%08X %01.2e", FP_RS(14),(double)FP_RFS(14)); break; + case CPUINFO_STR_REGISTER + SH4_FR15: sprintf(info->s, "FR15 :%08X %01.2e", FP_RS(15),(double)FP_RFS(15)); break; + case CPUINFO_STR_REGISTER + SH4_XF0: sprintf(info->s, "XF0 :%08X %01.2e", FP_XS( 0),(double)FP_XFS( 0)); break; + case CPUINFO_STR_REGISTER + SH4_XF1: sprintf(info->s, "XF1 :%08X %01.2e", FP_XS( 1),(double)FP_XFS( 1)); break; + case CPUINFO_STR_REGISTER + SH4_XF2: sprintf(info->s, "XF2 :%08X %01.2e", FP_XS( 2),(double)FP_XFS( 2)); break; + case CPUINFO_STR_REGISTER + SH4_XF3: sprintf(info->s, "XF3 :%08X %01.2e", FP_XS( 3),(double)FP_XFS( 3)); break; + case CPUINFO_STR_REGISTER + SH4_XF4: sprintf(info->s, "XF4 :%08X %01.2e", FP_XS( 4),(double)FP_XFS( 4)); break; + case CPUINFO_STR_REGISTER + SH4_XF5: sprintf(info->s, "XF5 :%08X %01.2e", FP_XS( 5),(double)FP_XFS( 5)); break; + case CPUINFO_STR_REGISTER + SH4_XF6: sprintf(info->s, "XF6 :%08X %01.2e", FP_XS( 6),(double)FP_XFS( 6)); break; + case CPUINFO_STR_REGISTER + SH4_XF7: sprintf(info->s, "XF7 :%08X %01.2e", FP_XS( 7),(double)FP_XFS( 7)); break; + case CPUINFO_STR_REGISTER + SH4_XF8: sprintf(info->s, "XF8 :%08X %01.2e", FP_XS( 8),(double)FP_XFS( 8)); break; + case CPUINFO_STR_REGISTER + SH4_XF9: sprintf(info->s, "XF9 :%08X %01.2e", FP_XS( 9),(double)FP_XFS( 9)); break; + case CPUINFO_STR_REGISTER + SH4_XF10: sprintf(info->s, "XF10 :%08X %01.2e", FP_XS(10),(double)FP_XFS(10)); break; + case CPUINFO_STR_REGISTER + SH4_XF11: sprintf(info->s, "XF11 :%08X %01.2e", FP_XS(11),(double)FP_XFS(11)); break; + case CPUINFO_STR_REGISTER + SH4_XF12: sprintf(info->s, "XF12 :%08X %01.2e", FP_XS(12),(double)FP_XFS(12)); break; + case CPUINFO_STR_REGISTER + SH4_XF13: sprintf(info->s, "XF13 :%08X %01.2e", FP_XS(13),(double)FP_XFS(13)); break; + case CPUINFO_STR_REGISTER + SH4_XF14: sprintf(info->s, "XF14 :%08X %01.2e", FP_XS(14),(double)FP_XFS(14)); break; + case CPUINFO_STR_REGISTER + SH4_XF15: sprintf(info->s, "XF15 :%08X %01.2e", FP_XS(15),(double)FP_XFS(15)); break; +#endif case CPUINFO_PTR_SH4_FTCSR_READ_CALLBACK: info->f = (genf*)sh4.ftcsr_read_callback; break; } diff --git a/src/emu/cpu/sh4/sh4dasm.c b/src/emu/cpu/sh4/sh4dasm.c index 6a33d45f101..1b8ece6dee7 100644 --- a/src/emu/cpu/sh4/sh4dasm.c +++ b/src/emu/cpu/sh4/sh4dasm.c @@ -543,7 +543,7 @@ static UINT32 op1000(char *buffer, UINT32 pc, UINT16 opcode) sprintf(buffer, "MOV.B @($%02X,%s),R0", (opcode & 15), regname[Rm]); break; case 5: - sprintf(buffer, "MOV.W @($%02X,%s),R0", (opcode & 15), regname[Rm]); + sprintf(buffer, "MOV.W @($%02X,%s),R0", (opcode & 15) * 2, regname[Rm]); break; case 8: sprintf(buffer, "CMP/EQ #$%02X,R0", (opcode & 0xff)); |