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