Search
lxdream.org :: lxdream/src/aica/armcore.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armcore.c
changeset 86:f151e63f9754
prev81:1c1d53584da4
next431:248dd77a9e44
author nkeynes
date Wed Jan 03 09:00:17 2007 +0000 (17 years ago)
permissions -rw-r--r--
last change Adjust timers when they're read rather than waiting until the next time
slice. Also temporarily cut the CPU time by 4.
Initialize the FRQCR register to 0x0E0A for convenience
view annotate diff log raw
     1 /**
     2  * $Id: armcore.c,v 1.20 2006-01-22 22:40:05 nkeynes Exp $
     3  * 
     4  * ARM7TDMI CPU emulation core.
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #define MODULE aica_module
    20 #include "dream.h"
    21 #include "mem.h"
    22 #include "aica/armcore.h"
    23 #include "aica/aica.h"
    25 #define STM_R15_OFFSET 12
    27 struct arm_registers armr;
    29 void arm_set_mode( int mode );
    31 uint32_t arm_exceptions[][2] = {{ MODE_SVC, 0x00000000 },
    32 				{ MODE_UND, 0x00000004 },
    33 				{ MODE_SVC, 0x00000008 },
    34 				{ MODE_ABT, 0x0000000C },
    35 				{ MODE_ABT, 0x00000010 },
    36 				{ MODE_IRQ, 0x00000018 },
    37 				{ MODE_FIQ, 0x0000001C } };
    39 #define EXC_RESET 0
    40 #define EXC_UNDEFINED 1
    41 #define EXC_SOFTWARE 2
    42 #define EXC_PREFETCH_ABORT 3
    43 #define EXC_DATA_ABORT 4
    44 #define EXC_IRQ 5
    45 #define EXC_FAST_IRQ 6
    47 uint32_t arm_cpu_freq = ARM_BASE_RATE;
    48 uint32_t arm_cpu_period = 1000 / ARM_BASE_RATE;
    50 #define CYCLES_PER_SAMPLE ((ARM_BASE_RATE * 1000000) / AICA_SAMPLE_RATE)
    52 static struct breakpoint_struct arm_breakpoints[MAX_BREAKPOINTS];
    53 static int arm_breakpoint_count = 0;
    55 void arm_set_breakpoint( uint32_t pc, int type )
    56 {
    57     arm_breakpoints[arm_breakpoint_count].address = pc;
    58     arm_breakpoints[arm_breakpoint_count].type = type;
    59     arm_breakpoint_count++;
    60 }
    62 gboolean arm_clear_breakpoint( uint32_t pc, int type )
    63 {
    64     int i;
    66     for( i=0; i<arm_breakpoint_count; i++ ) {
    67 	if( arm_breakpoints[i].address == pc && 
    68 	    arm_breakpoints[i].type == type ) {
    69 	    while( ++i < arm_breakpoint_count ) {
    70 		arm_breakpoints[i-1].address = arm_breakpoints[i].address;
    71 		arm_breakpoints[i-1].type = arm_breakpoints[i].type;
    72 	    }
    73 	    arm_breakpoint_count--;
    74 	    return TRUE;
    75 	}
    76     }
    77     return FALSE;
    78 }
    80 int arm_get_breakpoint( uint32_t pc )
    81 {
    82     int i;
    83     for( i=0; i<arm_breakpoint_count; i++ ) {
    84 	if( arm_breakpoints[i].address == pc )
    85 	    return arm_breakpoints[i].type;
    86     }
    87     return 0;
    88 }
    90 uint32_t arm_run_slice( uint32_t num_samples )
    91 {
    92     int i,j,k;
    94     if( !armr.running )
    95 	return num_samples;
    97     for( i=0; i<num_samples; i++ ) {
    98 	for( j=0; j < CYCLES_PER_SAMPLE; j++ ) {
    99 	    armr.icount++;
   100 	    if( !arm_execute_instruction() )
   101 		return i;
   102 #ifdef ENABLE_DEBUG_MODE
   103 	    for( k=0; k<arm_breakpoint_count; k++ ) {
   104 		if( arm_breakpoints[k].address == armr.r[15] ) {
   105 		    dreamcast_stop();
   106 		    if( arm_breakpoints[k].type == BREAK_ONESHOT )
   107 			arm_clear_breakpoint( armr.r[15], BREAK_ONESHOT );
   108 		    return i;
   109 		}
   110 	    }
   111 #endif	
   112 	}
   114 	k = MMIO_READ( AICA2, AICA_TCR );
   115 	if( k & 0x40 ) {
   116 	    uint8_t val = MMIO_READ( AICA2, AICA_TIMER );
   117 	    val++;
   118 	    if( val == 0 ) {
   119 		aica_event( AICA_EVENT_TIMER );
   120 		MMIO_WRITE( AICA2, AICA_TCR, k & ~0x40 );
   121 	    }
   122 	    MMIO_WRITE( AICA2, AICA_TIMER, val );
   123 	}
   124 	if( !dreamcast_is_running() )
   125 	    break;
   126     }
   128     return i;
   129 }
   131 void arm_save_state( FILE *f )
   132 {
   133     fwrite( &armr, sizeof(armr), 1, f );
   134 }
   136 int arm_load_state( FILE *f )
   137 {
   138     fread( &armr, sizeof(armr), 1, f );
   139     return 0;
   140 }
   142 /* Exceptions */
   143 void arm_reset( void )
   144 {
   145     /* Wipe all processor state */
   146     memset( &armr, 0, sizeof(armr) );
   148     armr.cpsr = MODE_SVC | CPSR_I | CPSR_F;
   149     armr.r[15] = 0x00000000;
   150     armr.running = TRUE;
   151 }
   153 #define SET_CPSR_CONTROL   0x00010000
   154 #define SET_CPSR_EXTENSION 0x00020000
   155 #define SET_CPSR_STATUS    0x00040000
   156 #define SET_CPSR_FLAGS     0x00080000
   158 uint32_t arm_get_cpsr( void )
   159 {
   160     /* write back all flags to the cpsr */
   161     armr.cpsr = armr.cpsr & CPSR_COMPACT_MASK;
   162     if( armr.n ) armr.cpsr |= CPSR_N;
   163     if( armr.z ) armr.cpsr |= CPSR_Z;
   164     if( armr.c ) armr.cpsr |= CPSR_C;
   165     if( armr.v ) armr.cpsr |= CPSR_V;
   166     if( armr.t ) armr.cpsr |= CPSR_T;  
   167     return armr.cpsr;
   168 }
   170 /**
   171  * Return a pointer to the specified register in the user bank,
   172  * regardless of the active bank
   173  */
   174 static uint32_t *arm_user_reg( int reg )
   175 {
   176     if( IS_EXCEPTION_MODE() ) {
   177 	if( reg == 13 || reg == 14 )
   178 	    return &armr.user_r[reg-8];
   179 	if( IS_FIQ_MODE() ) {
   180 	    if( reg >= 8 || reg <= 12 )
   181 		return &armr.user_r[reg-8];
   182 	}
   183     }
   184     return &armr.r[reg];
   185 }
   187 #define USER_R(n) *arm_user_reg(n)
   189 /**
   190  * Set the CPSR to the specified value.
   191  *
   192  * @param value values to set in CPSR
   193  * @param fields set of mask values to define which sections of the 
   194  *   CPSR to set (one of the SET_CPSR_* values above)
   195  */
   196 void arm_set_cpsr( uint32_t value, uint32_t fields )
   197 {
   198     if( IS_PRIVILEGED_MODE() ) {
   199 	if( fields & SET_CPSR_CONTROL ) {
   200 	    int mode = value & CPSR_MODE;
   201 	    arm_set_mode( mode );
   202 	    armr.t = ( value & CPSR_T ); /* Technically illegal to change */
   203 	    armr.cpsr = (armr.cpsr & 0xFFFFFF00) | (value & 0x000000FF);
   204 	}
   206 	/* Middle 16 bits not currently defined */
   207     }
   208     if( fields & SET_CPSR_FLAGS ) {
   209 	/* Break flags directly out of given value - don't bother writing
   210 	 * back to CPSR 
   211 	 */
   212 	armr.n = ( value & CPSR_N );
   213 	armr.z = ( value & CPSR_Z );
   214 	armr.c = ( value & CPSR_C );
   215 	armr.v = ( value & CPSR_V );
   216     }
   217 }
   219 void arm_set_spsr( uint32_t value, uint32_t fields )
   220 {
   221     /* Only defined if we actually have an SPSR register */
   222     if( IS_EXCEPTION_MODE() ) {
   223 	if( fields & SET_CPSR_CONTROL ) {
   224 	    armr.spsr = (armr.spsr & 0xFFFFFF00) | (value & 0x000000FF);
   225 	}
   227 	/* Middle 16 bits not currently defined */
   229 	if( fields & SET_CPSR_FLAGS ) {
   230 	    armr.spsr = (armr.spsr & 0x00FFFFFF) | (value & 0xFF000000);
   231 	}
   232     }
   233 }
   235 /**
   236  * Raise an ARM exception (other than reset, which uses arm_reset().
   237  * @param exception one of the EXC_* exception codes defined above.
   238  */
   239 void arm_raise_exception( int exception )
   240 {
   241     int mode = arm_exceptions[exception][0];
   242     uint32_t spsr = arm_get_cpsr();
   243     arm_set_mode( mode );
   244     armr.spsr = spsr;
   245     armr.r[14] = armr.r[15] + 4;
   246     armr.cpsr = (spsr & 0xFFFFFF00) | mode | CPSR_I; 
   247     if( mode == MODE_FIQ )
   248 	armr.cpsr |= CPSR_F;
   249     armr.r[15] = arm_exceptions[exception][1];
   250 }
   252 void arm_restore_cpsr( void )
   253 {
   254     int spsr = armr.spsr;
   255     int mode = spsr & CPSR_MODE;
   256     arm_set_mode( mode );
   257     armr.cpsr = spsr;
   258     armr.n = ( spsr & CPSR_N );
   259     armr.z = ( spsr & CPSR_Z );
   260     armr.c = ( spsr & CPSR_C );
   261     armr.v = ( spsr & CPSR_V );
   262     armr.t = ( spsr & CPSR_T );
   263 }
   267 /**
   268  * Change the current executing ARM mode to the requested mode.
   269  * Saves any required registers to banks and restores those for the
   270  * correct mode. (Note does not actually update CPSR at the moment).
   271  */
   272 void arm_set_mode( int targetMode )
   273 {
   274     int currentMode = armr.cpsr & CPSR_MODE;
   275     if( currentMode == targetMode )
   276 	return;
   278     switch( currentMode ) {
   279     case MODE_USER:
   280     case MODE_SYS:
   281 	armr.user_r[5] = armr.r[13];
   282 	armr.user_r[6] = armr.r[14];
   283 	break;
   284     case MODE_SVC:
   285 	armr.svc_r[0] = armr.r[13];
   286 	armr.svc_r[1] = armr.r[14];
   287 	armr.svc_r[2] = armr.spsr;
   288 	break;
   289     case MODE_ABT:
   290 	armr.abt_r[0] = armr.r[13];
   291 	armr.abt_r[1] = armr.r[14];
   292 	armr.abt_r[2] = armr.spsr;
   293 	break;
   294     case MODE_UND:
   295 	armr.und_r[0] = armr.r[13];
   296 	armr.und_r[1] = armr.r[14];
   297 	armr.und_r[2] = armr.spsr;
   298 	break;
   299     case MODE_IRQ:
   300 	armr.irq_r[0] = armr.r[13];
   301 	armr.irq_r[1] = armr.r[14];
   302 	armr.irq_r[2] = armr.spsr;
   303 	break;
   304     case MODE_FIQ:
   305 	armr.fiq_r[0] = armr.r[8];
   306 	armr.fiq_r[1] = armr.r[9];
   307 	armr.fiq_r[2] = armr.r[10];
   308 	armr.fiq_r[3] = armr.r[11];
   309 	armr.fiq_r[4] = armr.r[12];
   310 	armr.fiq_r[5] = armr.r[13];
   311 	armr.fiq_r[6] = armr.r[14];
   312 	armr.fiq_r[7] = armr.spsr;
   313 	armr.r[8] = armr.user_r[0];
   314 	armr.r[9] = armr.user_r[1];
   315 	armr.r[10] = armr.user_r[2];
   316 	armr.r[11] = armr.user_r[3];
   317 	armr.r[12] = armr.user_r[4];
   318 	break;
   319     }
   321     switch( targetMode ) {
   322     case MODE_USER:
   323     case MODE_SYS:
   324 	armr.r[13] = armr.user_r[5];
   325 	armr.r[14] = armr.user_r[6];
   326 	break;
   327     case MODE_SVC:
   328 	armr.r[13] = armr.svc_r[0];
   329 	armr.r[14] = armr.svc_r[1];
   330 	armr.spsr = armr.svc_r[2];
   331 	break;
   332     case MODE_ABT:
   333 	armr.r[13] = armr.abt_r[0];
   334 	armr.r[14] = armr.abt_r[1];
   335 	armr.spsr = armr.abt_r[2];
   336 	break;
   337     case MODE_UND:
   338 	armr.r[13] = armr.und_r[0];
   339 	armr.r[14] = armr.und_r[1];
   340 	armr.spsr = armr.und_r[2];
   341 	break;
   342     case MODE_IRQ:
   343 	armr.r[13] = armr.irq_r[0];
   344 	armr.r[14] = armr.irq_r[1];
   345 	armr.spsr = armr.irq_r[2];
   346 	break;
   347     case MODE_FIQ:
   348 	armr.user_r[0] = armr.r[8];
   349 	armr.user_r[1] = armr.r[9];
   350 	armr.user_r[2] = armr.r[10];
   351 	armr.user_r[3] = armr.r[11];
   352 	armr.user_r[4] = armr.r[12];
   353 	armr.r[8] = armr.fiq_r[0];
   354 	armr.r[9] = armr.fiq_r[1];
   355 	armr.r[10] = armr.fiq_r[2];
   356 	armr.r[11] = armr.fiq_r[3];
   357 	armr.r[12] = armr.fiq_r[4];
   358 	armr.r[13] = armr.fiq_r[5];
   359 	armr.r[14] = armr.fiq_r[6];
   360 	armr.spsr = armr.fiq_r[7];
   361 	break;
   362     }
   363 }
   365 /* Page references are as per ARM DDI 0100E (June 2000) */
   367 #define MEM_READ_BYTE( addr ) arm_read_byte(addr)
   368 #define MEM_READ_WORD( addr ) arm_read_word(addr)
   369 #define MEM_READ_LONG( addr ) arm_read_long(addr)
   370 #define MEM_WRITE_BYTE( addr, val ) arm_write_byte(addr, val)
   371 #define MEM_WRITE_WORD( addr, val ) arm_write_word(addr, val)
   372 #define MEM_WRITE_LONG( addr, val ) arm_write_long(addr, val)
   375 #define IS_NOTBORROW( result, op1, op2 ) (op2 > op1 ? 0 : 1)
   376 #define IS_CARRY( result, op1, op2 ) (result < op1 ? 1 : 0)
   377 #define IS_SUBOVERFLOW( result, op1, op2 ) (((op1^op2) & (result^op1)) >> 31)
   378 #define IS_ADDOVERFLOW( result, op1, op2 ) (((op1&op2) & (result^op1)) >> 31)
   380 #define PC armr.r[15]
   382 /* Instruction fields */
   383 #define COND(ir) (ir>>28)
   384 #define GRP(ir) ((ir>>26)&0x03)
   385 #define OPCODE(ir) ((ir>>20)&0x1F)
   386 #define IFLAG(ir) (ir&0x02000000)
   387 #define SFLAG(ir) (ir&0x00100000)
   388 #define PFLAG(ir) (ir&0x01000000)
   389 #define UFLAG(ir) (ir&0x00800000)
   390 #define BFLAG(ir) (ir&0x00400000)
   391 #define WFLAG(ir) (ir&0x00200000)
   392 #define LFLAG(ir) SFLAG(ir)
   393 #define RN(ir) (armr.r[((ir>>16)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))
   394 #define RD(ir) (armr.r[((ir>>12)&0x0F)] + (((ir>>12)&0x0F) == 0x0F ? 4 : 0))
   395 #define RDn(ir) ((ir>>12)&0x0F)
   396 #define RS(ir) (armr.r[((ir>>8)&0x0F)] + (((ir>>8)&0x0F) == 0x0F ? 4 : 0))
   397 #define RM(ir) (armr.r[(ir&0x0F)] + (((ir&0x0F) == 0x0F ? 4 : 0)) )
   398 #define LRN(ir) armr.r[((ir>>16)&0x0F)]
   399 #define LRD(ir) armr.r[((ir>>12)&0x0F)]
   400 #define LRS(ir) armr.r[((ir>>8)&0x0F)]
   401 #define LRM(ir) armr.r[(ir&0x0F)]
   403 #define IMM8(ir) (ir&0xFF)
   404 #define IMM12(ir) (ir&0xFFF)
   405 #define SHIFTIMM(ir) ((ir>>7)&0x1F)
   406 #define IMMROT(ir) ((ir>>7)&0x1E)
   407 #define ROTIMM12(ir) ROTATE_RIGHT_LONG(IMM8(ir),IMMROT(ir))
   408 #define SIGNEXT24(n) ((n&0x00800000) ? (n|0xFF000000) : (n&0x00FFFFFF))
   409 #define SHIFT(ir) ((ir>>4)&0x07)
   410 #define DISP24(ir) ((ir&0x00FFFFFF))
   411 #define UNDEF(ir) do{ arm_raise_exception( EXC_UNDEFINED ); return TRUE; } while(0)
   412 #define UNIMP(ir) do{ PC-=4; ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", PC, ir ); dreamcast_stop(); return FALSE; }while(0)
   414 /**
   415  * Determine the value of the shift-operand for a data processing instruction,
   416  * without determing a value for shift_C (optimized form for instructions that
   417  * don't require shift_C ).
   418  * @see s5.1 Addressing Mode 1 - Data-processing operands (p A5-2, 218)
   419  */
   420 static uint32_t arm_get_shift_operand( uint32_t ir )
   421 {
   422 	uint32_t operand, tmp;
   423 	if( IFLAG(ir) == 0 ) {
   424 		operand = RM(ir);
   425 		switch(SHIFT(ir)) {
   426 		case 0: /* (Rm << imm) */
   427 			operand = operand << SHIFTIMM(ir);
   428 			break;
   429 		case 1: /* (Rm << Rs) */
   430 			tmp = RS(ir)&0xFF;
   431 			if( tmp > 31 ) operand = 0;
   432 			else operand = operand << tmp;
   433 			break;
   434 		case 2: /* (Rm >> imm) */
   435 			operand = operand >> SHIFTIMM(ir);
   436 			break;
   437 		case 3: /* (Rm >> Rs) */
   438 			tmp = RS(ir) & 0xFF;
   439 			if( tmp > 31 ) operand = 0;
   440 			else operand = operand >> ir;
   441 			break;
   442 		case 4: /* (Rm >>> imm) */
   443 			tmp = SHIFTIMM(ir);
   444 			if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
   445 			else operand = ((int32_t)operand) >> tmp;
   446 			break;
   447 		case 5: /* (Rm >>> Rs) */
   448 			tmp = RS(ir) & 0xFF;
   449 			if( tmp > 31 ) operand = ((int32_t)operand) >> 31;
   450 			else operand = ((int32_t)operand) >> tmp;
   451 			break;
   452 		case 6:
   453 			tmp = SHIFTIMM(ir);
   454 			if( tmp == 0 ) /* RRX aka rotate with carry */
   455 				operand = (operand >> 1) | (armr.c<<31);
   456 			else
   457 				operand = ROTATE_RIGHT_LONG(operand,tmp);
   458 			break;
   459 		case 7:
   460 			tmp = RS(ir)&0x1F;
   461 			operand = ROTATE_RIGHT_LONG(operand,tmp);
   462 			break;
   463 		}
   464 	} else {
   465 		operand = IMM8(ir);
   466 		tmp = IMMROT(ir);
   467 		operand = ROTATE_RIGHT_LONG(operand, tmp);
   468 	}
   469 	return operand;
   470 }
   472 /**
   473  * Determine the value of the shift-operand for a data processing instruction,
   474  * and set armr.shift_c accordingly.
   475  * @see s5.1 Addressing Mode 1 - Data-processing operands (p A5-2, 218)
   476  */
   477 static uint32_t arm_get_shift_operand_s( uint32_t ir )
   478 {
   479 	uint32_t operand, tmp;
   480 	if( IFLAG(ir) == 0 ) {
   481 		operand = RM(ir);
   482 		switch(SHIFT(ir)) {
   483 		case 0: /* (Rm << imm) */
   484 			tmp = SHIFTIMM(ir);
   485 			if( tmp == 0 ) { /* Rm */
   486 				armr.shift_c = armr.c;
   487 			} else { /* Rm << imm */
   488 				armr.shift_c = (operand >> (32-tmp)) & 0x01;
   489 				operand = operand << tmp;
   490 			}
   491 			break;
   492 		case 1: /* (Rm << Rs) */
   493 			tmp = RS(ir)&0xFF;
   494 			if( tmp == 0 ) {
   495 				armr.shift_c = armr.c;
   496 			} else {
   497 				if( tmp <= 32 )
   498 					armr.shift_c = (operand >> (32-tmp)) & 0x01;
   499 				else armr.shift_c = 0;
   500 				if( tmp < 32 )
   501 					operand = operand << tmp;
   502 				else operand = 0;
   503 			}
   504 			break;
   505 		case 2: /* (Rm >> imm) */
   506 			tmp = SHIFTIMM(ir);
   507 			if( tmp == 0 ) {
   508 				armr.shift_c = operand >> 31;
   509 				operand = 0;
   510 			} else {
   511 				armr.shift_c = (operand >> (tmp-1)) & 0x01;
   512 				operand = RM(ir) >> tmp;
   513 			}
   514 			break;
   515 		case 3: /* (Rm >> Rs) */
   516 			tmp = RS(ir) & 0xFF;
   517 			if( tmp == 0 ) {
   518 				armr.shift_c = armr.c;
   519 			} else {
   520 				if( tmp <= 32 )
   521 					armr.shift_c = (operand >> (tmp-1))&0x01;
   522 				else armr.shift_c = 0;
   523 				if( tmp < 32 )
   524 					operand = operand >> tmp;
   525 				else operand = 0;
   526 			}
   527 			break;
   528 		case 4: /* (Rm >>> imm) */
   529 			tmp = SHIFTIMM(ir);
   530 			if( tmp == 0 ) {
   531 				armr.shift_c = operand >> 31;
   532 				operand = -armr.shift_c;
   533 			} else {
   534 				armr.shift_c = (operand >> (tmp-1)) & 0x01;
   535 				operand = ((int32_t)operand) >> tmp;
   536 			}
   537 			break;
   538 		case 5: /* (Rm >>> Rs) */
   539 			tmp = RS(ir) & 0xFF;
   540 			if( tmp == 0 ) {
   541 				armr.shift_c = armr.c;
   542 			} else {
   543 				if( tmp < 32 ) {
   544 					armr.shift_c = (operand >> (tmp-1))&0x01;
   545 					operand = ((int32_t)operand) >> tmp;
   546 				} else {
   547 					armr.shift_c = operand >> 31;
   548 					operand = ((int32_t)operand) >> 31;
   549 				}
   550 			}
   551 			break;
   552 		case 6:
   553 			tmp = SHIFTIMM(ir);
   554 			if( tmp == 0 ) { /* RRX aka rotate with carry */
   555 				armr.shift_c = operand&0x01;
   556 				operand = (operand >> 1) | (armr.c<<31);
   557 			} else {
   558 				armr.shift_c = operand>>(tmp-1);
   559 				operand = ROTATE_RIGHT_LONG(operand,tmp);
   560 			}
   561 			break;
   562 		case 7:
   563 			tmp = RS(ir)&0xFF;
   564 			if( tmp == 0 ) {
   565 				armr.shift_c = armr.c;
   566 			} else {
   567 				tmp &= 0x1F;
   568 				if( tmp == 0 ) {
   569 					armr.shift_c = operand>>31;
   570 				} else {
   571 					armr.shift_c = (operand>>(tmp-1))&0x1;
   572 					operand = ROTATE_RIGHT_LONG(operand,tmp);
   573 				}
   574 			}
   575 			break;
   576 		}
   577 	} else {
   578 		operand = IMM8(ir);
   579 		tmp = IMMROT(ir);
   580 		if( tmp == 0 ) {
   581 			armr.shift_c = armr.c;
   582 		} else {
   583 			operand = ROTATE_RIGHT_LONG(operand, tmp);
   584 			armr.shift_c = operand>>31;
   585 		}
   586 	}
   587 	return operand;
   588 }
   590 /**
   591  * Another variant of the shifter code for index-based memory addressing.
   592  * Distinguished by the fact that it doesn't support register shifts, and
   593  * ignores the I flag (WTF do the load/store instructions use the I flag to
   594  * mean the _exact opposite_ of what it means for the data processing 
   595  * instructions ???)
   596  */
   597 static uint32_t arm_get_address_index( uint32_t ir )
   598 {
   599 	uint32_t operand = RM(ir);
   600 	uint32_t tmp;
   602 	switch(SHIFT(ir)) {
   603 	case 0: /* (Rm << imm) */
   604 		operand = operand << SHIFTIMM(ir);
   605 		break;
   606 	case 2: /* (Rm >> imm) */
   607 		operand = operand >> SHIFTIMM(ir);
   608 		break;
   609 	case 4: /* (Rm >>> imm) */
   610 		tmp = SHIFTIMM(ir);
   611 		if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
   612 		else operand = ((int32_t)operand) >> tmp;
   613 		break;
   614 	case 6:
   615 		tmp = SHIFTIMM(ir);
   616 		if( tmp == 0 ) /* RRX aka rotate with carry */
   617 			operand = (operand >> 1) | (armr.c<<31);
   618 		else
   619 			operand = ROTATE_RIGHT_LONG(operand,tmp);
   620 		break;
   621 	default: UNIMP(ir);
   622 	}
   623 	return operand;	
   624 }
   626 /**
   627  * Determine the address operand of a load/store instruction, including
   628  * applying any pre/post adjustments to the address registers.
   629  * @see s5.2 Addressing Mode 2 - Load and Store Word or Unsigned Byte
   630  * @param The instruction word.
   631  * @return The calculated address
   632  */
   633 static uint32_t arm_get_address_operand( uint32_t ir )
   634 {
   635 	uint32_t addr;
   637 	/* I P U . W */
   638 	switch( (ir>>21)&0x1D ) {
   639 	case 0: /* Rn -= imm offset (post-indexed) [5.2.8 A5-28] */
   640 	case 1:
   641 		addr = RN(ir);
   642 		LRN(ir) = addr - IMM12(ir);
   643 		break;
   644 	case 4: /* Rn += imm offsett (post-indexed) [5.2.8 A5-28] */
   645 	case 5:
   646 		addr = RN(ir);
   647 		LRN(ir) = addr + IMM12(ir);
   648 		break;
   649 	case 8: /* Rn - imm offset  [5.2.2 A5-20] */
   650 		addr = RN(ir) - IMM12(ir);
   651 		break;
   652 	case 9: /* Rn -= imm offset (pre-indexed)  [5.2.5 A5-24] */
   653 		addr = RN(ir) - IMM12(ir);
   654 		LRN(ir) = addr;
   655 		break;
   656 	case 12: /* Rn + imm offset  [5.2.2 A5-20] */
   657 		addr = RN(ir) + IMM12(ir);
   658 		break;
   659 	case 13: /* Rn += imm offset  [5.2.5 A5-24 ] */
   660 		addr = RN(ir) + IMM12(ir);
   661 		LRN(ir) = addr;
   662 		break;
   663 	case 16: /* Rn -= Rm (post-indexed)  [5.2.10 A5-32 ] */
   664 	case 17:
   665 		addr = RN(ir);
   666 		LRN(ir) = addr - arm_get_address_index(ir);
   667 		break;
   668 	case 20: /* Rn += Rm (post-indexed)  [5.2.10 A5-32 ] */
   669 	case 21:
   670 		addr = RN(ir);
   671 		LRN(ir) = addr - arm_get_address_index(ir);
   672 		break;
   673 	case 24: /* Rn - Rm  [5.2.4 A5-23] */
   674 		addr = RN(ir) - arm_get_address_index(ir);
   675 		break;
   676 	case 25: /* RN -= Rm (pre-indexed)  [5.2.7 A5-26] */
   677 		addr = RN(ir) - arm_get_address_index(ir);
   678 		LRN(ir) = addr;
   679 		break;
   680 	case 28: /* Rn + Rm  [5.2.4 A5-23] */
   681 		addr = RN(ir) + arm_get_address_index(ir);
   682 		break;
   683 	case 29: /* RN += Rm (pre-indexed) [5.2.7 A5-26] */
   684 		addr = RN(ir) + arm_get_address_index(ir);
   685 		LRN(ir) = addr;
   686 		break;
   687 	}
   688 	return addr;
   689 }
   691 gboolean arm_execute_instruction( void ) 
   692 {
   693     uint32_t pc;
   694     uint32_t ir;
   695     uint32_t operand, operand2, tmp, tmp2, cond;
   696     int i;
   698     tmp = armr.int_pending & (~armr.cpsr);
   699     if( tmp ) {
   700 	if( tmp & CPSR_F ) {
   701 	    arm_raise_exception( EXC_FAST_IRQ );
   702 	} else {
   703 	    arm_raise_exception( EXC_IRQ );
   704 	}
   705     }
   707     ir = MEM_READ_LONG(PC);
   708     pc = PC + 4;
   709     PC = pc;
   711     /** 
   712      * Check the condition bits first - if the condition fails return 
   713      * immediately without actually looking at the rest of the instruction.
   714      */
   715     switch( COND(ir) ) {
   716     case 0: /* EQ */ 
   717 	cond = armr.z;
   718 	break;
   719     case 1: /* NE */
   720 	cond = !armr.z;
   721 	break;
   722     case 2: /* CS/HS */
   723 	cond = armr.c;
   724 	break;
   725     case 3: /* CC/LO */
   726 	cond = !armr.c;
   727 	break;
   728     case 4: /* MI */
   729 	cond = armr.n;
   730 	break;
   731     case 5: /* PL */
   732 	cond = !armr.n;
   733 	break;
   734     case 6: /* VS */
   735 	cond = armr.v;
   736 	break;
   737     case 7: /* VC */
   738 	cond = !armr.v;
   739 	break;
   740     case 8: /* HI */
   741 	cond = armr.c && !armr.z;
   742 	break;
   743     case 9: /* LS */
   744 	cond = (!armr.c) || armr.z;
   745 	break;
   746     case 10: /* GE */
   747 	cond = (armr.n == armr.v);
   748 	break;
   749     case 11: /* LT */
   750 	cond = (armr.n != armr.v);
   751 	break;
   752     case 12: /* GT */
   753 	cond = (!armr.z) && (armr.n == armr.v);
   754 	break;
   755     case 13: /* LE */
   756 	cond = armr.z || (armr.n != armr.v);
   757 	break;
   758     case 14: /* AL */
   759 	cond = 1;
   760 	break;
   761     case 15: /* (NV) */
   762 	cond = 0;
   763 	UNDEF(ir);
   764     }
   765     if( cond ) {
   767     /**
   768      * Condition passed, now for the actual instructions...
   769      */
   770     switch( GRP(ir) ) {
   771     case 0:
   772 	if( (ir & 0x0D900000) == 0x01000000 ) {
   773 	    /* Instructions that aren't actual data processing even though
   774 	     * they sit in the DP instruction block.
   775 	     */
   776 	    switch( ir & 0x0FF000F0 ) {
   777 	    case 0x01200010: /* BX Rd */
   778 		armr.t = ir & 0x01;
   779 		armr.r[15] = RM(ir) & 0xFFFFFFFE;
   780 		break;
   781 	    case 0x01000000: /* MRS Rd, CPSR */
   782 		LRD(ir) = arm_get_cpsr();
   783 		break;
   784 	    case 0x01400000: /* MRS Rd, SPSR */
   785 		LRD(ir) = armr.spsr;
   786 		break;
   787 	    case 0x01200000: /* MSR CPSR, Rd */
   788 		arm_set_cpsr( RM(ir), ir );
   789 		break;
   790 	    case 0x01600000: /* MSR SPSR, Rd */
   791 		arm_set_spsr( RM(ir), ir );
   792 		break;
   793 	    case 0x03200000: /* MSR CPSR, imm */
   794 		arm_set_cpsr( ROTIMM12(ir), ir );
   795 		break;
   796 	    case 0x03600000: /* MSR SPSR, imm */
   797 		arm_set_spsr( ROTIMM12(ir), ir );
   798 		break;
   799 	    default:
   800 		UNIMP(ir);
   801 	    }
   802 	} else if( (ir & 0x0E000090) == 0x00000090 ) {
   803 	    /* Neither are these */
   804 	    switch( (ir>>5)&0x03 ) {
   805 	    case 0:
   806 		/* Arithmetic extension area */
   807 		switch(OPCODE(ir)) {
   808 		case 0: /* MUL */
   809 		    LRN(ir) = RM(ir) * RS(ir);
   810 		    break;
   811 		case 1: /* MULS */
   812 		    tmp = RM(ir) * RS(ir);
   813 		    LRN(ir) = tmp;
   814 		    armr.n = tmp>>31;
   815 		    armr.z = (tmp == 0);
   816 		    break;
   817 		case 2: /* MLA */
   818 		    LRN(ir) = RM(ir) * RS(ir) + RD(ir);
   819 		    break;
   820 		case 3: /* MLAS */
   821 		    tmp = RM(ir) * RS(ir) + RD(ir);
   822 		    LRN(ir) = tmp;
   823 		    armr.n = tmp>>31;
   824 		    armr.z = (tmp == 0);
   825 		    break;
   826 		case 8: /* UMULL */
   827 		case 9: /* UMULLS */
   828 		case 10: /* UMLAL */
   829 		case 11: /* UMLALS */
   830 		case 12: /* SMULL */
   831 		case 13: /* SMULLS */
   832 		case 14: /* SMLAL */
   833 		case 15: /* SMLALS */
   834 		    UNIMP(ir);
   835 		    break;
   836 		case 16: /* SWP */
   837 		    tmp = arm_read_long( RN(ir) );
   838 		    switch( RN(ir) & 0x03 ) {
   839 		    case 1:
   840 			tmp = ROTATE_RIGHT_LONG(tmp, 8);
   841 			break;
   842 		    case 2:
   843 			tmp = ROTATE_RIGHT_LONG(tmp, 16);
   844 			break;
   845 		    case 3:
   846 			tmp = ROTATE_RIGHT_LONG(tmp, 24);
   847 			break;
   848 		    }
   849 		    arm_write_long( RN(ir), RM(ir) );
   850 		    LRD(ir) = tmp;
   851 		    break;
   852 		case 20: /* SWPB */
   853 		    tmp = arm_read_byte( RN(ir) );
   854 		    arm_write_byte( RN(ir), RM(ir) );
   855 		    LRD(ir) = tmp;
   856 		    break;
   857 		default:
   858 		    UNIMP(ir);
   859 		}
   860 		break;
   861 	    case 1:
   862 		if( LFLAG(ir) ) {
   863 		    /* LDRH */
   864 		} else {
   865 		    /* STRH */
   866 		}
   867 		UNIMP(ir);
   868 		break;
   869 	    case 2:
   870 		if( LFLAG(ir) ) {
   871 		    /* LDRSB */
   872 		} else {
   873 		}
   874 		UNIMP(ir);
   875 		break;
   876 	    case 3:
   877 		if( LFLAG(ir) ) {
   878 		    /* LDRSH */
   879 		} else {
   880 		}
   881 		UNIMP(ir);
   882 		break;
   883 	    }
   884 	} else {
   885 	    /* Data processing */
   887 	    switch(OPCODE(ir)) {
   888 	    case 0: /* AND Rd, Rn, operand */
   889 		LRD(ir) = RN(ir) & arm_get_shift_operand(ir);
   890 		break;
   891 	    case 1: /* ANDS Rd, Rn, operand */
   892 		operand = arm_get_shift_operand_s(ir) & RN(ir);
   893 		LRD(ir) = operand;
   894 		if( RDn(ir) == 15 ) {
   895 		    arm_restore_cpsr();
   896 		} else {
   897 		    armr.n = operand>>31;
   898 		    armr.z = (operand == 0);
   899 		    armr.c = armr.shift_c;
   900 		}
   901 		break;
   902 	    case 2: /* EOR Rd, Rn, operand */
   903 		LRD(ir) = RN(ir) ^ arm_get_shift_operand(ir);
   904 		break;
   905 	    case 3: /* EORS Rd, Rn, operand */
   906 		operand = arm_get_shift_operand_s(ir) ^ RN(ir);
   907 		LRD(ir) = operand;
   908 		if( RDn(ir) == 15 ) {
   909 		    arm_restore_cpsr();
   910 		} else {
   911 		    armr.n = operand>>31;
   912 		    armr.z = (operand == 0);
   913 		    armr.c = armr.shift_c;
   914 		}
   915 		break;
   916 	    case 4: /* SUB Rd, Rn, operand */
   917 		LRD(ir) = RN(ir) - arm_get_shift_operand(ir);
   918 		break;
   919 	    case 5: /* SUBS Rd, Rn, operand */
   920 		operand = RN(ir);
   921 		operand2 = arm_get_shift_operand(ir);
   922 		tmp = operand - operand2;
   923 		LRD(ir) = tmp;
   924 		if( RDn(ir) == 15 ) {
   925 		    arm_restore_cpsr();
   926 		} else {
   927 		    armr.n = tmp>>31;
   928 		    armr.z = (tmp == 0);
   929 		    armr.c = IS_NOTBORROW(tmp,operand,operand2);
   930 		    armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
   931 		}
   932 		break;
   933 	    case 6: /* RSB Rd, operand, Rn */
   934 		LRD(ir) = arm_get_shift_operand(ir) - RN(ir);
   935 		break;
   936 	    case 7: /* RSBS Rd, operand, Rn */
   937 		operand = arm_get_shift_operand(ir);
   938 		operand2 = RN(ir);
   939 		tmp = operand - operand2;
   940 		LRD(ir) = tmp;
   941 		if( RDn(ir) == 15 ) {
   942 		    arm_restore_cpsr();
   943 		} else {
   944 		    armr.n = tmp>>31;
   945 		    armr.z = (tmp == 0);
   946 		    armr.c = IS_NOTBORROW(tmp,operand,operand2);
   947 		    armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
   948 		}
   949 		break;
   950 	    case 8: /* ADD Rd, Rn, operand */
   951 		LRD(ir) = RN(ir) + arm_get_shift_operand(ir);
   952 		break;
   953 	    case 9: /* ADDS Rd, Rn, operand */
   954 		operand = arm_get_shift_operand(ir);
   955 		operand2 = RN(ir);
   956 		tmp = operand + operand2;
   957 		LRD(ir) = tmp;
   958 		if( RDn(ir) == 15 ) {
   959 		    arm_restore_cpsr();
   960 		} else {
   961 		    armr.n = tmp>>31;
   962 		    armr.z = (tmp == 0);
   963 		    armr.c = IS_CARRY(tmp,operand,operand2);
   964 		    armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
   965 		}
   966 		break;			
   967 	    case 10: /* ADC */
   968 		LRD(ir) = RN(ir) + arm_get_shift_operand(ir) + 
   969 		    (armr.c ? 1 : 0);
   970 		break;
   971 	    case 11: /* ADCS */
   972 		operand = arm_get_shift_operand(ir);
   973 		operand2 = RN(ir);
   974 		tmp = operand + operand2;
   975 		tmp2 = tmp + armr.c ? 1 : 0;
   976 		LRD(ir) = tmp2;
   977 		if( RDn(ir) == 15 ) {
   978 		    arm_restore_cpsr();
   979 		} else {
   980 		    armr.n = tmp >> 31;
   981 		    armr.z = (tmp == 0 );
   982 		    armr.c = IS_CARRY(tmp,operand,operand2) ||
   983 			(tmp2 < tmp);
   984 		    armr.v = IS_ADDOVERFLOW(tmp,operand, operand2) ||
   985 			((tmp&0x80000000) != (tmp2&0x80000000));
   986 		}
   987 		break;
   988 	    case 12: /* SBC */
   989 		LRD(ir) = RN(ir) - arm_get_shift_operand(ir) - 
   990 		    (armr.c ? 0 : 1);
   991 		break;
   992 	    case 13: /* SBCS */
   993 		operand = RN(ir);
   994 		operand2 = arm_get_shift_operand(ir);
   995 		tmp = operand - operand2;
   996 		tmp2 = tmp - (armr.c ? 0 : 1);
   997 		if( RDn(ir) == 15 ) {
   998 		    arm_restore_cpsr();
   999 		} else {
  1000 		    armr.n = tmp >> 31;
  1001 		    armr.z = (tmp == 0 );
  1002 		    armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
  1003 			(tmp2<tmp);
  1004 		    armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
  1005 			((tmp&0x80000000) != (tmp2&0x80000000));
  1007 		break;
  1008 	    case 14: /* RSC */
  1009 		LRD(ir) = arm_get_shift_operand(ir) - RN(ir) -
  1010 		    (armr.c ? 0 : 1);
  1011 		break;
  1012 	    case 15: /* RSCS */
  1013 		operand = arm_get_shift_operand(ir);
  1014 		operand2 = RN(ir);
  1015 		tmp = operand - operand2;
  1016 		tmp2 = tmp - (armr.c ? 0 : 1);
  1017 		if( RDn(ir) == 15 ) {
  1018 		    arm_restore_cpsr();
  1019 		} else {
  1020 		    armr.n = tmp >> 31;
  1021 		    armr.z = (tmp == 0 );
  1022 		    armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
  1023 			(tmp2<tmp);
  1024 		    armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
  1025 			((tmp&0x80000000) != (tmp2&0x80000000));
  1027 		break;
  1028 	    case 17: /* TST Rn, operand */
  1029 		operand = arm_get_shift_operand_s(ir) & RN(ir);
  1030 		armr.n = operand>>31;
  1031 		armr.z = (operand == 0);
  1032 		armr.c = armr.shift_c;
  1033 		break;
  1034 	    case 19: /* TEQ Rn, operand */
  1035 		operand = arm_get_shift_operand_s(ir) ^ RN(ir);
  1036 		armr.n = operand>>31;
  1037 		armr.z = (operand == 0);
  1038 		armr.c = armr.shift_c;
  1039 		break;				
  1040 	    case 21: /* CMP Rn, operand */
  1041 		operand = RN(ir);
  1042 		operand2 = arm_get_shift_operand(ir);
  1043 		tmp = operand - operand2;
  1044 		armr.n = tmp>>31;
  1045 		armr.z = (tmp == 0);
  1046 		armr.c = IS_NOTBORROW(tmp,operand,operand2);
  1047 		armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
  1048 		break;
  1049 	    case 23: /* CMN Rn, operand */
  1050 		operand = RN(ir);
  1051 		operand2 = arm_get_shift_operand(ir);
  1052 		tmp = operand + operand2;
  1053 		armr.n = tmp>>31;
  1054 		armr.z = (tmp == 0);
  1055 		armr.c = IS_CARRY(tmp,operand,operand2);
  1056 		armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
  1057 		break;
  1058 	    case 24: /* ORR Rd, Rn, operand */
  1059 		LRD(ir) = RN(ir) | arm_get_shift_operand(ir);
  1060 		break;
  1061 	    case 25: /* ORRS Rd, Rn, operand */
  1062 		operand = arm_get_shift_operand_s(ir) | RN(ir);
  1063 		LRD(ir) = operand;
  1064 		if( RDn(ir) == 15 ) {
  1065 		    arm_restore_cpsr();
  1066 		} else {
  1067 		    armr.n = operand>>31;
  1068 		    armr.z = (operand == 0);
  1069 		    armr.c = armr.shift_c;
  1071 		break;
  1072 	    case 26: /* MOV Rd, operand */
  1073 		LRD(ir) = arm_get_shift_operand(ir);
  1074 		break;
  1075 	    case 27: /* MOVS Rd, operand */
  1076 		operand = arm_get_shift_operand_s(ir);
  1077 		LRD(ir) = operand;
  1078 		if( RDn(ir) == 15 ) {
  1079 		    arm_restore_cpsr();
  1080 		} else {
  1081 		    armr.n = operand>>31;
  1082 		    armr.z = (operand == 0);
  1083 		    armr.c = armr.shift_c;
  1085 		break;
  1086 	    case 28: /* BIC Rd, Rn, operand */
  1087 		LRD(ir) = RN(ir) & (~arm_get_shift_operand(ir));
  1088 		break;
  1089 	    case 29: /* BICS Rd, Rn, operand */
  1090 		operand = RN(ir) & (~arm_get_shift_operand_s(ir));
  1091 		LRD(ir) = operand;
  1092 		if( RDn(ir) == 15 ) {
  1093 		    arm_restore_cpsr();
  1094 		} else {
  1095 		    armr.n = operand>>31;
  1096 		    armr.z = (operand == 0);
  1097 		    armr.c = armr.shift_c;
  1099 		break;
  1100 	    case 30: /* MVN Rd, operand */
  1101 		LRD(ir) = ~arm_get_shift_operand(ir);
  1102 		break;
  1103 	    case 31: /* MVNS Rd, operand */
  1104 		operand = ~arm_get_shift_operand_s(ir);
  1105 		LRD(ir) = operand;
  1106 		if( RDn(ir) == 15 ) {
  1107 		    arm_restore_cpsr();
  1108 		} else {
  1109 		    armr.n = operand>>31;
  1110 		    armr.z = (operand == 0);
  1111 		    armr.c = armr.shift_c;
  1113 		break;
  1114 	    default:
  1115 		UNIMP(ir);
  1118 	break;
  1119     case 1: /* Load/store */
  1120 	operand = arm_get_address_operand(ir);
  1121 	switch( (ir>>20)&0x17 ) {
  1122 	case 0: case 16: case 18: /* STR Rd, address */
  1123 	    arm_write_long( operand, RD(ir) );
  1124 	    break;
  1125 	case 1: case 17: case 19: /* LDR Rd, address */
  1126 	    LRD(ir) = arm_read_long(operand);
  1127 	    break;
  1128 	case 2: /* STRT Rd, address */
  1129 	    arm_write_long_user( operand, RD(ir) );
  1130 	    break;
  1131 	case 3: /* LDRT Rd, address */
  1132 	    LRD(ir) = arm_read_long_user( operand );
  1133 	    break;
  1134 	case 4: case 20: case 22: /* STRB Rd, address */
  1135 	    arm_write_byte( operand, RD(ir) );
  1136 	    break;
  1137 	case 5: case 21: case 23: /* LDRB Rd, address */
  1138 	    LRD(ir) = arm_read_byte( operand );
  1139 	    break;
  1140 	case 6: /* STRBT Rd, address */
  1141 	    arm_write_byte_user( operand, RD(ir) );
  1142 	    break;
  1143 	case 7: /* LDRBT Rd, address */
  1144 	    LRD(ir) = arm_read_byte_user( operand );
  1145 	    break;
  1147 	break;
  1148     case 2: /* Load/store multiple, branch*/
  1149 	if( (ir & 0x02000000) == 0x02000000 ) { /* B[L] imm24 */
  1150 	    operand = (SIGNEXT24(ir&0x00FFFFFF) << 2);
  1151 	    if( (ir & 0x01000000) == 0x01000000 ) { 
  1152 		armr.r[14] = pc; /* BL */
  1154 	    armr.r[15] = pc + 4 + operand;
  1155 	} else { /* Load/store multiple */
  1156 	    gboolean needRestore = FALSE;
  1157 	    operand = RN(ir);
  1159 	    switch( (ir & 0x01D00000) >> 20 ) {
  1160 	    case 0: /* STMDA */
  1161 		if( ir & 0x8000 ) {
  1162 		    arm_write_long( operand, armr.r[15]+4 );
  1163 		    operand -= 4;
  1165 		for( i=14; i>= 0; i-- ) {
  1166 		    if( (ir & (1<<i)) ) {
  1167 			arm_write_long( operand, armr.r[i] );
  1168 			operand -= 4;
  1171 		break;
  1172 	    case 1: /* LDMDA */
  1173 		for( i=15; i>= 0; i-- ) {
  1174 		    if( (ir & (1<<i)) ) {
  1175 			armr.r[i] = arm_read_long( operand );
  1176 			operand -= 4;
  1179 		break;
  1180 	    case 4: /* STMDA (S) */
  1181 		if( ir & 0x8000 ) {
  1182 		    arm_write_long( operand, armr.r[15]+4 );
  1183 		    operand -= 4;
  1185 		for( i=14; i>= 0; i-- ) {
  1186 		    if( (ir & (1<<i)) ) {
  1187 			arm_write_long( operand, USER_R(i) );
  1188 			operand -= 4;
  1191 		break;
  1192 	    case 5: /* LDMDA (S) */
  1193 		if( (ir&0x00008000) ) { /* Load PC */
  1194 		    for( i=15; i>= 0; i-- ) {
  1195 			if( (ir & (1<<i)) ) {
  1196 			    armr.r[i] = arm_read_long( operand );
  1197 			    operand -= 4;
  1200 		    needRestore = TRUE;
  1201 		} else {
  1202 		    for( i=15; i>= 0; i-- ) {
  1203 			if( (ir & (1<<i)) ) {
  1204 			    USER_R(i) = arm_read_long( operand );
  1205 			    operand -= 4;
  1209 		break;
  1210 	    case 8: /* STMIA */
  1211 		for( i=0; i< 15; i++ ) {
  1212 		    if( (ir & (1<<i)) ) {
  1213 			arm_write_long( operand, armr.r[i] );
  1214 			operand += 4;
  1217 		if( ir & 0x8000 ) {
  1218 		    arm_write_long( operand, armr.r[15]+4 );
  1219 		    operand += 4;
  1221 		break;
  1222 	    case 9: /* LDMIA */
  1223 		for( i=0; i< 16; i++ ) {
  1224 		    if( (ir & (1<<i)) ) {
  1225 			armr.r[i] = arm_read_long( operand );
  1226 			operand += 4;
  1229 		break;
  1230 	    case 12: /* STMIA (S) */
  1231 		for( i=0; i< 15; i++ ) {
  1232 		    if( (ir & (1<<i)) ) {
  1233 			arm_write_long( operand, USER_R(i) );
  1234 			operand += 4;
  1237 		if( ir & 0x8000 ) {
  1238 		    arm_write_long( operand, armr.r[15]+4 );
  1239 		    operand += 4;
  1241 		break;
  1242 	    case 13: /* LDMIA (S) */
  1243 		if( (ir&0x00008000) ) { /* Load PC */
  1244 		    for( i=0; i < 16; i++ ) {
  1245 			if( (ir & (1<<i)) ) {
  1246 			    armr.r[i] = arm_read_long( operand );
  1247 			    operand += 4;
  1250 		    needRestore = TRUE;
  1251 		} else {
  1252 		    for( i=0; i < 16; i++ ) {
  1253 			if( (ir & (1<<i)) ) {
  1254 			    USER_R(i) = arm_read_long( operand );
  1255 			    operand += 4;
  1259 		break;
  1260 	    case 16: /* STMDB */
  1261 		if( ir & 0x8000 ) {
  1262 		    operand -= 4;
  1263 		    arm_write_long( operand, armr.r[15]+4 );
  1265 		for( i=14; i>= 0; i-- ) {
  1266 		    if( (ir & (1<<i)) ) {
  1267 			operand -= 4;
  1268 			arm_write_long( operand, armr.r[i] );
  1271 		break;
  1272 	    case 17: /* LDMDB */
  1273 		for( i=15; i>= 0; i-- ) {
  1274 		    if( (ir & (1<<i)) ) {
  1275 			operand -= 4;
  1276 			armr.r[i] = arm_read_long( operand );
  1279 		break;
  1280 	    case 20: /* STMDB (S) */
  1281 		if( ir & 0x8000 ) {
  1282 		    operand -= 4;
  1283 		    arm_write_long( operand, armr.r[15]+4 );
  1285 		for( i=14; i>= 0; i-- ) {
  1286 		    if( (ir & (1<<i)) ) {
  1287 			operand -= 4;
  1288 			arm_write_long( operand, USER_R(i) );
  1291 		break;
  1292 	    case 21: /* LDMDB (S) */
  1293 		if( (ir&0x00008000) ) { /* Load PC */
  1294 		    for( i=15; i>= 0; i-- ) {
  1295 			if( (ir & (1<<i)) ) {
  1296 			    operand -= 4;
  1297 			    armr.r[i] = arm_read_long( operand );
  1300 		    needRestore = TRUE;
  1301 		} else {
  1302 		    for( i=15; i>= 0; i-- ) {
  1303 			if( (ir & (1<<i)) ) {
  1304 			    operand -= 4;
  1305 			    USER_R(i) = arm_read_long( operand );
  1309 		break;
  1310 	    case 24: /* STMIB */
  1311 		for( i=0; i< 15; i++ ) {
  1312 		    if( (ir & (1<<i)) ) {
  1313 			operand += 4;
  1314 			arm_write_long( operand, armr.r[i] );
  1317 		if( ir & 0x8000 ) {
  1318 		    operand += 4;
  1319 		    arm_write_long( operand, armr.r[15]+4 );
  1321 		break;
  1322 	    case 25: /* LDMIB */
  1323 		for( i=0; i< 16; i++ ) {
  1324 		    if( (ir & (1<<i)) ) {
  1325 			operand += 4;
  1326 			armr.r[i] = arm_read_long( operand );
  1329 		break;
  1330 	    case 28: /* STMIB (S) */
  1331 		for( i=0; i< 15; i++ ) {
  1332 		    if( (ir & (1<<i)) ) {
  1333 			operand += 4;
  1334 			arm_write_long( operand, USER_R(i) );
  1337 		if( ir & 0x8000 ) {
  1338 		    operand += 4;
  1339 		    arm_write_long( operand, armr.r[15]+4 );
  1341 		break;
  1342 	    case 29: /* LDMIB (S) */
  1343 		if( (ir&0x00008000) ) { /* Load PC */
  1344 		    for( i=0; i < 16; i++ ) {
  1345 			if( (ir & (1<<i)) ) {
  1346 			    operand += 4;
  1347 			    armr.r[i] = arm_read_long( operand );
  1350 		    needRestore = TRUE;
  1351 		} else {
  1352 		    for( i=0; i < 16; i++ ) {
  1353 			if( (ir & (1<<i)) ) {
  1354 			    operand += 4;
  1355 			    USER_R(i) = arm_read_long( operand );
  1359 		break;
  1362 	    if( WFLAG(ir) ) 
  1363 		LRN(ir) = operand;
  1364 	    if( needRestore ) 
  1365 		arm_restore_cpsr();
  1367 	break;
  1368     case 3: /* Copro */
  1369 	if( (ir & 0x0F000000) == 0x0F000000 ) { /* SWI */
  1370 	    arm_raise_exception( EXC_SOFTWARE );
  1371 	} else {
  1372 	    UNIMP(ir);
  1374 	break;
  1379     if( armr.r[15] >= 0x00200000 ) {
  1380 	armr.running = FALSE;
  1381 	ERROR( "ARM Halted: BRANCH to invalid address %08X at %08X", armr.r[15], pc );
  1382 	return FALSE;
  1384     return TRUE;
.