revision 81:1c1d53584da4
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 81:1c1d53584da4 |
parent | 80:1d59b19eb505 |
child | 82:81a4acf75f10 |
author | nkeynes |
date | Tue Jan 17 12:53:39 2006 +0000 (18 years ago) |
Fix LDM/STM instructions (yes, again, but for sure this time)
Add debug check - if PC leaves ram halt immediately
Add debug check - if PC leaves ram halt immediately
1.1 --- a/src/aica/armcore.c Mon Jan 16 11:23:28 2006 +00001.2 +++ b/src/aica/armcore.c Tue Jan 17 12:53:39 2006 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: armcore.c,v 1.18 2006-01-16 11:23:28 nkeynes Exp $1.6 + * $Id: armcore.c,v 1.19 2006-01-17 12:53:39 nkeynes Exp $1.7 *1.8 * ARM7TDMI CPU emulation core.1.9 *1.10 @@ -1149,11 +1149,16 @@1.11 }1.12 armr.r[15] = pc + 4 + operand;1.13 } else { /* Load/store multiple */1.14 + gboolean needRestore = FALSE;1.15 operand = RN(ir);1.17 switch( (ir & 0x01D00000) >> 20 ) {1.18 case 0: /* STMDA */1.19 - for( i=15; i>= 0; i-- ) {1.20 + if( ir & 0x8000 ) {1.21 + arm_write_long( operand, armr.r[15]+4 );1.22 + operand -= 4;1.23 + }1.24 + for( i=14; i>= 0; i-- ) {1.25 if( (ir & (1<<i)) ) {1.26 arm_write_long( operand, armr.r[i] );1.27 operand -= 4;1.28 @@ -1169,7 +1174,11 @@1.29 }1.30 break;1.31 case 4: /* STMDA (S) */1.32 - for( i=15; i>= 0; i-- ) {1.33 + if( ir & 0x8000 ) {1.34 + arm_write_long( operand, armr.r[15]+4 );1.35 + operand -= 4;1.36 + }1.37 + for( i=14; i>= 0; i-- ) {1.38 if( (ir & (1<<i)) ) {1.39 arm_write_long( operand, USER_R(i) );1.40 operand -= 4;1.41 @@ -1184,7 +1193,7 @@1.42 operand -= 4;1.43 }1.44 }1.45 - arm_restore_cpsr();1.46 + needRestore = TRUE;1.47 } else {1.48 for( i=15; i>= 0; i-- ) {1.49 if( (ir & (1<<i)) ) {1.50 @@ -1195,12 +1204,16 @@1.51 }1.52 break;1.53 case 8: /* STMIA */1.54 - for( i=0; i< 16; i++ ) {1.55 + for( i=0; i< 15; i++ ) {1.56 if( (ir & (1<<i)) ) {1.57 arm_write_long( operand, armr.r[i] );1.58 operand += 4;1.59 }1.60 }1.61 + if( ir & 0x8000 ) {1.62 + arm_write_long( operand, armr.r[15]+4 );1.63 + operand += 4;1.64 + }1.65 break;1.66 case 9: /* LDMIA */1.67 for( i=0; i< 16; i++ ) {1.68 @@ -1211,12 +1224,16 @@1.69 }1.70 break;1.71 case 12: /* STMIA (S) */1.72 - for( i=0; i< 16; i++ ) {1.73 + for( i=0; i< 15; i++ ) {1.74 if( (ir & (1<<i)) ) {1.75 arm_write_long( operand, USER_R(i) );1.76 operand += 4;1.77 }1.78 }1.79 + if( ir & 0x8000 ) {1.80 + arm_write_long( operand, armr.r[15]+4 );1.81 + operand += 4;1.82 + }1.83 break;1.84 case 13: /* LDMIA (S) */1.85 if( (ir&0x00008000) ) { /* Load PC */1.86 @@ -1226,7 +1243,7 @@1.87 operand += 4;1.88 }1.89 }1.90 - arm_restore_cpsr();1.91 + needRestore = TRUE;1.92 } else {1.93 for( i=0; i < 16; i++ ) {1.94 if( (ir & (1<<i)) ) {1.95 @@ -1237,7 +1254,11 @@1.96 }1.97 break;1.98 case 16: /* STMDB */1.99 - for( i=15; i>= 0; i-- ) {1.100 + if( ir & 0x8000 ) {1.101 + operand -= 4;1.102 + arm_write_long( operand, armr.r[15]+4 );1.103 + }1.104 + for( i=14; i>= 0; i-- ) {1.105 if( (ir & (1<<i)) ) {1.106 operand -= 4;1.107 arm_write_long( operand, armr.r[i] );1.108 @@ -1253,7 +1274,11 @@1.109 }1.110 break;1.111 case 20: /* STMDB (S) */1.112 - for( i=15; i>= 0; i-- ) {1.113 + if( ir & 0x8000 ) {1.114 + operand -= 4;1.115 + arm_write_long( operand, armr.r[15]+4 );1.116 + }1.117 + for( i=14; i>= 0; i-- ) {1.118 if( (ir & (1<<i)) ) {1.119 operand -= 4;1.120 arm_write_long( operand, USER_R(i) );1.121 @@ -1268,7 +1293,7 @@1.122 armr.r[i] = arm_read_long( operand );1.123 }1.124 }1.125 - arm_restore_cpsr();1.126 + needRestore = TRUE;1.127 } else {1.128 for( i=15; i>= 0; i-- ) {1.129 if( (ir & (1<<i)) ) {1.130 @@ -1279,12 +1304,16 @@1.131 }1.132 break;1.133 case 24: /* STMIB */1.134 - for( i=0; i< 16; i++ ) {1.135 + for( i=0; i< 15; i++ ) {1.136 if( (ir & (1<<i)) ) {1.137 operand += 4;1.138 arm_write_long( operand, armr.r[i] );1.139 }1.140 }1.141 + if( ir & 0x8000 ) {1.142 + operand += 4;1.143 + arm_write_long( operand, armr.r[15]+4 );1.144 + }1.145 break;1.146 case 25: /* LDMIB */1.147 for( i=0; i< 16; i++ ) {1.148 @@ -1295,12 +1324,16 @@1.149 }1.150 break;1.151 case 28: /* STMIB (S) */1.152 - for( i=0; i< 16; i++ ) {1.153 + for( i=0; i< 15; i++ ) {1.154 if( (ir & (1<<i)) ) {1.155 operand += 4;1.156 arm_write_long( operand, USER_R(i) );1.157 }1.158 }1.159 + if( ir & 0x8000 ) {1.160 + operand += 4;1.161 + arm_write_long( operand, armr.r[15]+4 );1.162 + }1.163 break;1.164 case 29: /* LDMIB (S) */1.165 if( (ir&0x00008000) ) { /* Load PC */1.166 @@ -1310,7 +1343,7 @@1.167 armr.r[i] = arm_read_long( operand );1.168 }1.169 }1.170 - arm_restore_cpsr();1.171 + needRestore = TRUE;1.172 } else {1.173 for( i=0; i < 16; i++ ) {1.174 if( (ir & (1<<i)) ) {1.175 @@ -1324,6 +1357,8 @@1.177 if( WFLAG(ir) )1.178 LRN(ir) = operand;1.179 + if( needRestore )1.180 + arm_restore_cpsr();1.181 }1.182 break;1.183 case 3: /* Copro */1.184 @@ -1334,5 +1369,10 @@1.185 }1.186 break;1.187 }1.188 + if( armr.r[15] > 0x00200000 ) {1.189 + dreamcast_stop();1.190 + ERROR( "BRANCH to fishkill at %08X", pc );1.191 + return FALSE;1.192 + }1.193 return TRUE;1.194 }
.