revision 46:30d123047e16
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 46:30d123047e16 |
parent | 45:f99236f0632e |
child | 47:da09bcb7ce69 |
author | nkeynes |
date | Tue Dec 27 08:42:57 2005 +0000 (18 years ago) |
Implement LDM/STM opcodes
Add a few more unknown aica registers
Add a few more unknown aica registers
src/aica/aica.h | view | annotate | diff | log | ||
src/aica/armcore.c | view | annotate | diff | log | ||
src/aica/armcore.h | view | annotate | diff | log |
1.1 --- a/src/aica/aica.h Tue Dec 27 08:41:22 2005 +00001.2 +++ b/src/aica/aica.h Tue Dec 27 08:42:57 2005 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: aica.h,v 1.3 2005-12-26 11:52:56 nkeynes Exp $1.6 + * $Id: aica.h,v 1.4 2005-12-27 08:42:57 nkeynes Exp $1.7 *1.8 * MMIO definitions for the AICA sound chip. Note that the regions defined1.9 * here are relative to the SH4 memory map (0x00700000 based), rather than1.10 @@ -33,7 +33,13 @@1.11 LONG_PORT( 0x044, CDDA_VOL_R, PORT_MRW, 0, "CDDA Volume right" )1.12 LONG_PORT( 0x800, VOL_MASTER, PORT_MRW, UNDEFINED, "Master volume" )1.13 LONG_PORT( 0x890, AICA_TIMER, PORT_MRW, 0, "IRQ Timer (?)" )1.14 +LONG_PORT( 0x89C, AICA_UNK1, PORT_MRW, 0, "AICA ??? 1" )1.15 +LONG_PORT( 0x8A4, AICA_UNK2, PORT_MRW, 0, "AICA ??? 2" )1.16 +BYTE_PORT( 0x8A8, AICA_UNK3, PORT_MRW, 0, "AICA ??? 3" )1.17 +BYTE_PORT( 0x8AC, AICA_UNK4, PORT_MRW, 0, "AICA ??? 4" )1.18 +BYTE_PORT( 0x8B0, AICA_UNK5, PORT_MRW, 0, "AICA ??? 5" )1.19 LONG_PORT( 0xC00, AICA_RESET,PORT_MRW, 1, "AICA reset" )1.20 +LONG_PORT( 0xD04, AICA_UNK6, PORT_MRW, 0, "AICA ??? 6" )1.21 MMIO_REGION_END1.23 MMIO_REGION_LIST_BEGIN( spu )
2.1 --- a/src/aica/armcore.c Tue Dec 27 08:41:22 2005 +00002.2 +++ b/src/aica/armcore.c Tue Dec 27 08:42:57 2005 +00002.3 @@ -1,5 +1,5 @@2.4 /**2.5 - * $Id: armcore.c,v 1.9 2005-12-26 11:52:56 nkeynes Exp $2.6 + * $Id: armcore.c,v 1.10 2005-12-27 08:42:57 nkeynes Exp $2.7 *2.8 * ARM7TDMI CPU emulation core.2.9 *2.10 @@ -354,7 +354,7 @@2.11 #define PFLAG(ir) (ir&0x01000000)2.12 #define UFLAG(ir) (ir&0x00800000)2.13 #define BFLAG(ir) (ir&0x00400000)2.14 -#define WFLAG(ir) (IR&0x00200000)2.15 +#define WFLAG(ir) (ir&0x00200000)2.16 #define LFLAG(ir) SFLAG(ir)2.17 #define RN(ir) (armr.r[((ir>>16)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))2.18 #define RD(ir) (armr.r[((ir>>12)&0x0F)] + (((ir>>12)&0x0F) == 0x0F ? 4 : 0))2.19 @@ -375,7 +375,7 @@2.20 #define SHIFT(ir) ((ir>>4)&0x07)2.21 #define DISP24(ir) ((ir&0x00FFFFFF))2.22 #define UNDEF(ir) do{ arm_raise_exception( EXC_UNDEFINED ); return TRUE; } while(0)2.23 -#define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", PC-4, ir ); dreamcast_stop(); return FALSE; }while(0)2.24 +#define UNIMP(ir) do{ PC-=4; ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", PC, ir ); dreamcast_stop(); return FALSE; }while(0)2.26 /**2.27 * Determine the value of the shift-operand for a data processing instruction,2.28 @@ -1033,7 +1033,89 @@2.29 }2.30 armr.r[15] = pc + 4 + operand;2.31 } else { /* Load/store multiple */2.32 - UNIMP(ir);2.33 + int prestep, poststep;2.34 + if( PFLAG(ir) ) {2.35 + prestep = 0;2.36 + poststep = UFLAG(ir) ? 4 : -4;2.37 + } else {2.38 + prestep = UFLAG(ir) ? 4 : -4;2.39 + poststep = 0 ;2.40 + }2.41 + operand = RN(ir);2.42 + if( BFLAG(ir) ) {2.43 + /* Actually S - bit 22. Means "make massively complicated" */2.44 + if( LFLAG(ir) && (ir&0x00008000) ) {2.45 + /* LDM (3). Much like normal LDM but also copies SPSR2.46 + * back to CPSR */2.47 + for( tmp=0; tmp < 16; tmp++ ) {2.48 + if( (ir & (1<<tmp)) ) {2.49 + operand += prestep;2.50 + armr.r[tmp] = arm_read_long(operand);2.51 + operand += poststep;2.52 + }2.53 + }2.54 + arm_restore_cpsr();2.55 + if( armr.t ) PC &= 0xFFFFFFFE;2.56 + else PC &= 0xFFFFFFFC;2.57 + } else {2.58 + /* LDM/STM (2). As normal LDM but accesses the User banks2.59 + * instead of the active ones. Aka the truly evil case2.60 + */2.61 + int bank_start;2.62 + if( IS_FIQ_MODE() )2.63 + bank_start = 8;2.64 + else if( IS_EXCEPTION_MODE() )2.65 + bank_start = 13;2.66 + else bank_start = 15;2.67 + for( tmp=0; tmp<bank_start; tmp++ ) {2.68 + if( (ir & (1<<tmp)) ) {2.69 + operand += prestep;2.70 + if( LFLAG(ir) ) {2.71 + armr.r[tmp] = arm_read_long(operand);2.72 + } else {2.73 + arm_write_long( operand, armr.r[tmp] );2.74 + }2.75 + operand += poststep;2.76 + }2.77 + }2.78 + for( ; tmp < 15; tmp ++ ) {2.79 + if( (ir & (1<<tmp)) ) {2.80 + operand += prestep;2.81 + if( LFLAG(ir) ) {2.82 + armr.user_r[tmp-8] = arm_read_long(operand);2.83 + } else {2.84 + arm_write_long( operand, armr.user_r[tmp-8] );2.85 + }2.86 + operand += poststep;2.87 + }2.88 + }2.89 + if( ir & 0x8000 ) {2.90 + operand += prestep;2.91 + if( LFLAG(ir) ) {2.92 + /* Actually can't happen, but anyway... */2.93 + armr.r[15] = arm_read_long(operand);2.94 + } else {2.95 + arm_write_long( operand, armr.r[15]+4 );2.96 + }2.97 + operand += poststep;2.98 + }2.99 + }2.100 + } else {2.101 + /* Normal LDM/STM */2.102 + for( tmp=0; tmp < 16; tmp++ ) {2.103 + if( (ir & (1<<tmp)) ) {2.104 + operand += prestep;2.105 + if( LFLAG(ir) ) {2.106 + armr.r[tmp] = arm_read_long(operand);2.107 + } else {2.108 + arm_write_long( operand, armr.r[tmp] );2.109 + }2.110 + operand += poststep;2.111 + }2.112 + }2.113 + }2.114 + if( WFLAG(ir) )2.115 + LRN(ir) = operand;2.116 }2.117 break;2.118 case 3: /* Copro */
3.1 --- a/src/aica/armcore.h Tue Dec 27 08:41:22 2005 +00003.2 +++ b/src/aica/armcore.h Tue Dec 27 08:42:57 2005 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: armcore.h,v 1.9 2005-12-26 11:47:15 nkeynes Exp $3.6 + * $Id: armcore.h,v 1.10 2005-12-27 08:42:57 nkeynes Exp $3.7 *3.8 * Interface definitions for the ARM CPU emulation core proper.3.9 *3.10 @@ -73,6 +73,7 @@3.12 #define IS_PRIVILEGED_MODE() ((armr.cpsr & CPSR_MODE) != MODE_USER)3.13 #define IS_EXCEPTION_MODE() (IS_PRIVILEGED_MODE() && (armr.cpsr & CPSR_MODE) != MODE_SYS)3.14 +#define IS_FIQ_MODE() ((armr.cpsr & CPSR_MODE) == MODE_FIQ)3.16 extern struct arm_registers armr;
.