Search
lxdream.org :: lxdream/src/sh4/sh4core.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.c
changeset 232:9c8ef78376ed
prev229:f27eb26ccdd2
next235:880bff11df92
author nkeynes
date Tue Sep 26 11:09:13 2006 +0000 (14 years ago)
permissions -rw-r--r--
last change Add CHECKSLOTILLEGAL() checks around a few banned delay-slot instructions
that were missing it
Change CHECKPRIV() to raise slot-illegal on a delay-slot instruction rather
than general-illegal (as per the manual)
Convert UNDEF() to do the real exception rather than halting the machine
Remove a couple of superfluous alignment checks
file annotate diff log raw
1.1 --- a/src/sh4/sh4core.c Mon Sep 25 11:19:42 2006 +0000
1.2 +++ b/src/sh4/sh4core.c Tue Sep 26 11:09:13 2006 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: sh4core.c,v 1.32 2006-09-25 11:19:42 nkeynes Exp $
1.6 + * $Id: sh4core.c,v 1.33 2006-09-26 11:09:13 nkeynes Exp $
1.7 *
1.8 * SH4 emulation core, and parent module for all the SH4 peripheral
1.9 * modules.
1.10 @@ -204,7 +204,7 @@
1.11 sh4r.new_pc = pc+2;
1.12 }
1.13
1.14 -#define UNDEF(ir) do{ ERROR( "Raising exception on undefined instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)
1.15 +#define UNDEF(ir) if( sh4r.in_delay_slot ) { RAISE( EXC_SLOT_ILLEGAL, EXV_ILLEGAL, -2 ); } else { RAISE( EXC_ILLEGAL, EXV_ILLEGAL, 0 ); }
1.16 #define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)
1.17
1.18 #if(SH4_CALLTRACE == 1)
1.19 @@ -266,9 +266,11 @@
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 + sh4r.in_delay_slot = 0; \
1.24 } \
1.25 return TRUE; } while(0)
1.26 -
1.27 +#define RAISE_SLOTILLEGAL() RAISE( EXC_SLOT_ILLEGAL, EXV_ILLEGAL, -2 )
1.28 +#define RAISE_ILLEGAL() RAISE( EXC_ILLEGAL, EXV_ILLEGAL, 0 )
1.29
1.30 #define MEM_READ_BYTE( addr ) sh4_read_byte(addr)
1.31 #define MEM_READ_WORD( addr ) sh4_read_word(addr)
1.32 @@ -284,7 +286,7 @@
1.33 #define MEM_FP_WRITE( addr, reg ) sh4_write_float( addr, reg );
1.34
1.35 #define CHECK( x, c, v ) if( !x ) RAISE( c, v, 0 )
1.36 -#define CHECKPRIV() CHECK( IS_SH4_PRIVMODE(), EXC_ILLEGAL, EXV_ILLEGAL )
1.37 +#define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) { if( sh4r.in_delay_slot ) { RAISE_SLOTILLEGAL(); } else { RAISE_ILLEGAL(); } }
1.38 #define CHECKRALIGN16(addr) if( (addr)&0x01 ) RAISE( EXC_READ_ADDR_ERR, EXV_TRAP, 0 )
1.39 #define CHECKRALIGN32(addr) if( (addr)&0x03 ) RAISE( EXC_READ_ADDR_ERR, EXV_TRAP, 0 )
1.40 #define CHECKWALIGN16(addr) if( (addr)&0x01 ) RAISE( EXC_WRITE_ADDR_ERR, EXV_TRAP, 0 )
1.41 @@ -462,8 +464,8 @@
1.42 case 3:
1.43 switch( (ir&0x00F0)>>4 ) {
1.44 case 0: /* BSRF Rn */
1.45 + CHECKSLOTILLEGAL();
1.46 CHECKDEST( pc + 4 + RN(ir) );
1.47 - CHECKSLOTILLEGAL();
1.48 sh4r.in_delay_slot = 1;
1.49 sh4r.pr = sh4r.pc + 4;
1.50 sh4r.pc = sh4r.new_pc;
1.51 @@ -471,8 +473,8 @@
1.52 TRACE_CALL( pc, sh4r.new_pc );
1.53 return TRUE;
1.54 case 2: /* BRAF Rn */
1.55 + CHECKSLOTILLEGAL();
1.56 CHECKDEST( pc + 4 + RN(ir) );
1.57 - CHECKSLOTILLEGAL();
1.58 sh4r.in_delay_slot = 1;
1.59 sh4r.pc = sh4r.new_pc;
1.60 sh4r.new_pc = pc + 4 + RN(ir);
1.61 @@ -578,8 +580,8 @@
1.62 case 11:
1.63 switch( (ir&0x0FF0)>>4 ) {
1.64 case 0: /* RTS */
1.65 + CHECKSLOTILLEGAL();
1.66 CHECKDEST( sh4r.pr );
1.67 - CHECKSLOTILLEGAL();
1.68 sh4r.in_delay_slot = 1;
1.69 sh4r.pc = sh4r.new_pc;
1.70 sh4r.new_pc = sh4r.pr;
1.71 @@ -820,6 +822,7 @@
1.72 RN(ir) += 4;
1.73 break;
1.74 case 0x07: /* LDC.L [Rn++], SR */
1.75 + CHECKSLOTILLEGAL();
1.76 CHECKPRIV();
1.77 CHECKWALIGN32( RN(ir) );
1.78 sh4_load_sr( MEM_READ_LONG(RN(ir)) );
1.79 @@ -845,6 +848,7 @@
1.80 TRACE_CALL( pc, sh4r.new_pc );
1.81 return TRUE;
1.82 case 0x0E: /* LDC Rn, SR */
1.83 + CHECKSLOTILLEGAL();
1.84 CHECKPRIV();
1.85 sh4_load_sr( RN(ir) );
1.86 break;
1.87 @@ -1225,14 +1229,14 @@
1.88 break;
1.89 case 9: /* 1001xxxxxxxxxxxx */
1.90 /* MOV.W [disp8*2 + pc + 4], Rn */
1.91 + CHECKSLOTILLEGAL();
1.92 tmp = pc + 4 + (DISP8(ir)<<1);
1.93 - CHECKRALIGN16( tmp );
1.94 RN(ir) = MEM_READ_WORD( tmp );
1.95 break;
1.96 case 10:/* 1010dddddddddddd */
1.97 /* BRA disp12 */
1.98 + CHECKSLOTILLEGAL()
1.99 CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 )
1.100 - CHECKSLOTILLEGAL()
1.101 sh4r.in_delay_slot = 1;
1.102 sh4r.pc = sh4r.new_pc;
1.103 sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);
1.104 @@ -1282,6 +1286,7 @@
1.105 R0 = MEM_READ_LONG( tmp );
1.106 break;
1.107 case 7: /* MOVA disp8 + pc&~3 + 4, R0 */
1.108 + CHECKSLOTILLEGAL();
1.109 R0 = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;
1.110 break;
1.111 case 8: /* TST imm8, R0 */
1.112 @@ -1315,8 +1320,8 @@
1.113 break;
1.114 case 13:/* 1101nnnndddddddd */
1.115 /* MOV.L [disp8*4 + pc&~3 + 4], Rn */
1.116 + CHECKSLOTILLEGAL();
1.117 tmp = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;
1.118 - CHECKRALIGN32( tmp );
1.119 RN(ir) = MEM_READ_LONG( tmp );
1.120 break;
1.121 case 14:/* 1110nnnniiiiiiii */
.