Search
lxdream.org :: lxdream :: r46:30d123047e16
lxdream 0.9.1
released Jun 29
Download Now
changeset46:30d123047e16
parent45:f99236f0632e
child47:da09bcb7ce69
authornkeynes
dateTue Dec 27 08:42:57 2005 +0000 (18 years ago)
Implement LDM/STM opcodes
Add a few more unknown aica registers
src/aica/aica.h
src/aica/armcore.c
src/aica/armcore.h
1.1 --- a/src/aica/aica.h Tue Dec 27 08:41:22 2005 +0000
1.2 +++ b/src/aica/aica.h Tue Dec 27 08:42:57 2005 +0000
1.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 defined
1.9 * here are relative to the SH4 memory map (0x00700000 based), rather than
1.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_END
1.22
1.23 MMIO_REGION_LIST_BEGIN( spu )
2.1 --- a/src/aica/armcore.c Tue Dec 27 08:41:22 2005 +0000
2.2 +++ b/src/aica/armcore.c Tue Dec 27 08:42:57 2005 +0000
2.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.25
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 SPSR
2.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 banks
2.59 + * instead of the active ones. Aka the truly evil case
2.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 +0000
3.2 +++ b/src/aica/armcore.h Tue Dec 27 08:42:57 2005 +0000
3.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.11
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.15
3.16 extern struct arm_registers armr;
3.17
.