1.1 --- a/src/sh4/sh4core.in Sat Sep 08 03:12:21 2007 +0000
1.2 +++ b/src/sh4/sh4core.in Wed Sep 12 09:16:47 2007 +0000
1.5 - * $Id: sh4core.in,v 1.3 2007-09-08 03:12:21 nkeynes Exp $
1.6 + * $Id: sh4core.in,v 1.4 2007-09-11 02:14:46 nkeynes Exp $
1.8 * SH4 emulation core, and parent module for all the SH4 peripheral
1.11 sh4r.vbr = 0x00000000;
1.12 sh4r.fpscr = 0x00040001;
1.13 sh4r.sr = 0x700000F0;
1.14 + sh4r.fr_bank = &sh4r.fr[0][0];
1.16 /* Mem reset will do this, but if we want to reset _just_ the SH4... */
1.17 MMIO_WRITE( MMU, EXPEVT, EXC_POWER_RESET );
1.19 MMIO_WRITE(MMU,EXPEVT,x); \
1.20 sh4r.pc = sh4r.vbr + v; \
1.21 sh4r.new_pc = sh4r.pc + 2; \
1.22 - sh4_load_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB ); \
1.23 + sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB ); \
1.24 if( sh4r.in_delay_slot ) { \
1.25 sh4r.in_delay_slot = 0; \
1.28 memcpy( sh4r.r_bank, tmp, sizeof(uint32_t)*8 );
1.31 -static void sh4_load_sr( uint32_t newval )
1.32 +void sh4_write_sr( uint32_t newval )
1.34 if( (newval ^ sh4r.sr) & SR_RB )
1.40 -static uint32_t sh4_read_sr( void )
1.41 +uint32_t sh4_read_sr( void )
1.43 /* synchronize sh4r.sr with the various bitflags */
1.44 sh4r.sr &= SR_MQSTMASK;
1.46 sh4r.ssr = sh4_read_sr();
1.48 sh4r.sgr = sh4r.r[15];
1.49 - sh4_load_sr( sh4r.ssr|SR_BL|SR_MD|SR_RB );
1.50 + sh4_write_sr( sh4r.ssr|SR_BL|SR_MD|SR_RB );
1.51 MMIO_WRITE( MMU, INTEVT, code );
1.52 sh4r.pc = sh4r.vbr + 0x600;
1.53 sh4r.new_pc = sh4r.pc + 2;
1.55 sh4r.in_delay_slot = 1;
1.56 sh4r.pc = sh4r.new_pc;
1.57 sh4r.new_pc = sh4r.spc;
1.58 - sh4_load_sr( sh4r.ssr );
1.59 + sh4_write_sr( sh4r.ssr );
1.66 CHECKWALIGN32( sh4r.r[Rm] );
1.67 - sh4_load_sr( MEM_READ_LONG(sh4r.r[Rm]) );
1.68 + sh4_write_sr( MEM_READ_LONG(sh4r.r[Rm]) );
1.76 - sh4_load_sr( sh4r.r[Rm] );
1.77 + sh4_write_sr( sh4r.r[Rm] );
1.81 @@ -1056,8 +1057,12 @@
1.82 CHECKRALIGN32( sh4r.r[Rm] );
1.83 sh4r.fpscr = MEM_READ_LONG(sh4r.r[Rm]);
1.85 + sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1.87 -LDS Rm, FPSCR {: sh4r.fpscr = sh4r.r[Rm]; :}
1.89 + sh4r.fpscr = sh4r.r[Rm];
1.90 + sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1.92 STC DBR, Rn {: CHECKPRIV(); sh4r.r[Rn] = sh4r.dbr; :}
1.95 @@ -1185,15 +1190,26 @@
1.96 FLDS FRm, FPUL {: CHECKFPUEN(); FPULf = FR(FRm); :}
1.99 - if( IS_FPU_DOUBLEPREC() )
1.100 - DR(FRn) = (float)FPULi;
1.102 + if( IS_FPU_DOUBLEPREC() ) {
1.103 + if( FRn&1 ) { // No, really...
1.104 + dtmp = (double)FPULi;
1.105 + FR(FRn) = *(((float *)&dtmp)+1);
1.107 + DRF(FRn>>1) = (double)FPULi;
1.110 FR(FRn) = (float)FPULi;
1.115 if( IS_FPU_DOUBLEPREC() ) {
1.119 + *(((float *)&dtmp)+1) = FR(FRm);
1.121 + dtmp = DRF(FRm>>1);
1.123 if( dtmp >= MAX_INTF )
1.125 else if( dtmp <= MIN_INTF )
1.126 @@ -1258,7 +1274,11 @@
1.127 FR(FRn) += FR(FRm)*FR(0);
1.130 -FRCHG {: CHECKFPUEN(); sh4r.fpscr ^= FPSCR_FR; :}
1.133 + sh4r.fpscr ^= FPSCR_FR;
1.134 + sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1.136 FSCHG {: CHECKFPUEN(); sh4r.fpscr ^= FPSCR_SZ; :}
1.137 FCNVSD FPUL, FRn {:
1.139 @@ -1302,15 +1322,16 @@
1.141 if( !IS_FPU_DOUBLEPREC() ) {
1.143 + float *xf = &sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][0];
1.144 float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };
1.145 - FR(tmp) = XF(0) * fv[0] + XF(4)*fv[1] +
1.146 - XF(8)*fv[2] + XF(12)*fv[3];
1.147 - FR(tmp+1) = XF(1) * fv[0] + XF(5)*fv[1] +
1.148 - XF(9)*fv[2] + XF(13)*fv[3];
1.149 - FR(tmp+2) = XF(2) * fv[0] + XF(6)*fv[1] +
1.150 - XF(10)*fv[2] + XF(14)*fv[3];
1.151 - FR(tmp+3) = XF(3) * fv[0] + XF(7)*fv[1] +
1.152 - XF(11)*fv[2] + XF(15)*fv[3];
1.153 + FR(tmp) = xf[1] * fv[0] + xf[5]*fv[1] +
1.154 + xf[9]*fv[2] + xf[13]*fv[3];
1.155 + FR(tmp+1) = xf[0] * fv[0] + xf[4]*fv[1] +
1.156 + xf[8]*fv[2] + xf[12]*fv[3];
1.157 + FR(tmp+2) = xf[3] * fv[0] + xf[7]*fv[1] +
1.158 + xf[11]*fv[2] + xf[15]*fv[3];
1.159 + FR(tmp+3) = xf[2] * fv[0] + xf[6]*fv[1] +
1.160 + xf[10]*fv[2] + xf[14]*fv[3];