# HG changeset patch # User nkeynes # Date 1135672977 0 # Node ID 30d123047e16ebfb2457536050f242dd73b06a82 # Parent f99236f0632e634cf84d90644bc0f898d7631d07 Implement LDM/STM opcodes Add a few more unknown aica registers --- a/src/aica/aica.h Tue Dec 27 08:41:22 2005 +0000 +++ b/src/aica/aica.h Tue Dec 27 08:42:57 2005 +0000 @@ -1,5 +1,5 @@ /** - * $Id: aica.h,v 1.3 2005-12-26 11:52:56 nkeynes Exp $ + * $Id: aica.h,v 1.4 2005-12-27 08:42:57 nkeynes Exp $ * * MMIO definitions for the AICA sound chip. Note that the regions defined * here are relative to the SH4 memory map (0x00700000 based), rather than @@ -33,7 +33,13 @@ LONG_PORT( 0x044, CDDA_VOL_R, PORT_MRW, 0, "CDDA Volume right" ) LONG_PORT( 0x800, VOL_MASTER, PORT_MRW, UNDEFINED, "Master volume" ) LONG_PORT( 0x890, AICA_TIMER, PORT_MRW, 0, "IRQ Timer (?)" ) +LONG_PORT( 0x89C, AICA_UNK1, PORT_MRW, 0, "AICA ??? 1" ) +LONG_PORT( 0x8A4, AICA_UNK2, PORT_MRW, 0, "AICA ??? 2" ) +BYTE_PORT( 0x8A8, AICA_UNK3, PORT_MRW, 0, "AICA ??? 3" ) +BYTE_PORT( 0x8AC, AICA_UNK4, PORT_MRW, 0, "AICA ??? 4" ) +BYTE_PORT( 0x8B0, AICA_UNK5, PORT_MRW, 0, "AICA ??? 5" ) LONG_PORT( 0xC00, AICA_RESET,PORT_MRW, 1, "AICA reset" ) +LONG_PORT( 0xD04, AICA_UNK6, PORT_MRW, 0, "AICA ??? 6" ) MMIO_REGION_END MMIO_REGION_LIST_BEGIN( spu ) --- a/src/aica/armcore.c Tue Dec 27 08:41:22 2005 +0000 +++ b/src/aica/armcore.c Tue Dec 27 08:42:57 2005 +0000 @@ -1,5 +1,5 @@ /** - * $Id: armcore.c,v 1.9 2005-12-26 11:52:56 nkeynes Exp $ + * $Id: armcore.c,v 1.10 2005-12-27 08:42:57 nkeynes Exp $ * * ARM7TDMI CPU emulation core. * @@ -354,7 +354,7 @@ #define PFLAG(ir) (ir&0x01000000) #define UFLAG(ir) (ir&0x00800000) #define BFLAG(ir) (ir&0x00400000) -#define WFLAG(ir) (IR&0x00200000) +#define WFLAG(ir) (ir&0x00200000) #define LFLAG(ir) SFLAG(ir) #define RN(ir) (armr.r[((ir>>16)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0)) #define RD(ir) (armr.r[((ir>>12)&0x0F)] + (((ir>>12)&0x0F) == 0x0F ? 4 : 0)) @@ -375,7 +375,7 @@ #define SHIFT(ir) ((ir>>4)&0x07) #define DISP24(ir) ((ir&0x00FFFFFF)) #define UNDEF(ir) do{ arm_raise_exception( EXC_UNDEFINED ); return TRUE; } while(0) -#define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", PC-4, ir ); dreamcast_stop(); return FALSE; }while(0) +#define UNIMP(ir) do{ PC-=4; ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", PC, ir ); dreamcast_stop(); return FALSE; }while(0) /** * Determine the value of the shift-operand for a data processing instruction, @@ -1033,7 +1033,89 @@ } armr.r[15] = pc + 4 + operand; } else { /* Load/store multiple */ - UNIMP(ir); + int prestep, poststep; + if( PFLAG(ir) ) { + prestep = 0; + poststep = UFLAG(ir) ? 4 : -4; + } else { + prestep = UFLAG(ir) ? 4 : -4; + poststep = 0 ; + } + operand = RN(ir); + if( BFLAG(ir) ) { + /* Actually S - bit 22. Means "make massively complicated" */ + if( LFLAG(ir) && (ir&0x00008000) ) { + /* LDM (3). Much like normal LDM but also copies SPSR + * back to CPSR */ + for( tmp=0; tmp < 16; tmp++ ) { + if( (ir & (1<