Search
lxdream.org :: lxdream :: r81:1c1d53584da4
lxdream 0.9.1
released Jun 29
Download Now
changeset81:1c1d53584da4
parent80:1d59b19eb505
child82:81a4acf75f10
authornkeynes
dateTue 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
src/aica/armcore.c
1.1 --- a/src/aica/armcore.c Mon Jan 16 11:23:28 2006 +0000
1.2 +++ b/src/aica/armcore.c Tue Jan 17 12:53:39 2006 +0000
1.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.16
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.176
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 }
.