Added ARM CPU to memory system interface.
This commit is contained in:
parent
6886803593
commit
35168b3e01
|
@ -39,6 +39,15 @@
|
|||
|
||||
#define ROM_MASK 3
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
//#define PROFILE_MEMORY_ACCESS 1
|
||||
#define EARLY_MEMORY_ACCESS 1
|
||||
|
||||
#define INTERNAL_DTCM_READ 1
|
||||
#define INTERNAL_DTCM_WRITE 1
|
||||
|
||||
//#define LOG_CARD
|
||||
//#define LOG_GPU
|
||||
//#define LOG_DMA
|
||||
|
@ -551,10 +560,12 @@ char txt[80];
|
|||
|
||||
u8 FASTCALL MMU_read8(u32 proc, u32 adr)
|
||||
{
|
||||
#ifdef INTERNAL_DTCM_READ
|
||||
if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==MMU.DTCMRegion))
|
||||
{
|
||||
return ARM9Mem.ARM9_DTCM[adr&0x3FFF];
|
||||
}
|
||||
#endif
|
||||
|
||||
// CFlash reading, Mic
|
||||
if ((adr>=0x9000000)&&(adr<0x9900000))
|
||||
|
@ -578,11 +589,13 @@ u8 FASTCALL MMU_read8(u32 proc, u32 adr)
|
|||
|
||||
u16 FASTCALL MMU_read16(u32 proc, u32 adr)
|
||||
{
|
||||
#ifdef INTERNAL_DTCM_READ
|
||||
if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
|
||||
{
|
||||
/* Returns data from DTCM (ARM9 only) */
|
||||
return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
// CFlash reading, Mic
|
||||
if ((adr>=0x08800000)&&(adr<0x09900000))
|
||||
|
@ -646,11 +659,13 @@ u16 FASTCALL MMU_read16(u32 proc, u32 adr)
|
|||
|
||||
u32 FASTCALL MMU_read32(u32 proc, u32 adr)
|
||||
{
|
||||
#ifdef INTERNAL_DTCM_READ
|
||||
if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
|
||||
{
|
||||
/* Returns data from DTCM (ARM9 only) */
|
||||
return T1ReadLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
// CFlash reading, Mic
|
||||
if ((adr>=0x9000000)&&(adr<0x9900000))
|
||||
|
@ -806,12 +821,14 @@ u32 FASTCALL MMU_read32(u32 proc, u32 adr)
|
|||
|
||||
void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val)
|
||||
{
|
||||
#ifdef INTERNAL_DTCM_WRITE
|
||||
if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
|
||||
{
|
||||
/* Writes data in DTCM (ARM9 only) */
|
||||
ARM9Mem.ARM9_DTCM[adr&0x3FFF] = val;
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
|
||||
// CFlash writing, Mic
|
||||
if ((adr>=0x9000000)&&(adr<0x9900000)) {
|
||||
|
@ -1178,12 +1195,14 @@ u16 partie = 1;
|
|||
|
||||
void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
|
||||
{
|
||||
#ifdef INTERNAL_DTCM_WRITE
|
||||
if((proc == ARMCPU_ARM9) && ((adr & ~0x3FFF) == MMU.DTCMRegion))
|
||||
{
|
||||
/* Writes in DTCM (ARM9 only) */
|
||||
T1WriteWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// CFlash writing, Mic
|
||||
if ((adr>=0x08800000)&&(adr<0x09900000))
|
||||
|
@ -1797,11 +1816,13 @@ void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
|
|||
|
||||
void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val)
|
||||
{
|
||||
#ifdef INTERNAL_DTCM_WRITE
|
||||
if((proc==ARMCPU_ARM9)&((adr&(~0x3FFF))==MMU.DTCMRegion))
|
||||
{
|
||||
T1WriteLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
|
||||
// CFlash writing, Mic
|
||||
if ((adr>=0x9000000)&&(adr<0x9900000)) {
|
||||
|
@ -2974,3 +2995,493 @@ void FASTCALL MMU_write32_acl(u32 proc, u32 adr, u32 val)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
|
||||
#define PROFILE_PREFETCH 0
|
||||
#define PROFILE_READ 1
|
||||
#define PROFILE_WRITE 2
|
||||
|
||||
struct mem_access_profile {
|
||||
u64 num_accesses;
|
||||
u32 address_mask;
|
||||
u32 masked_value;
|
||||
};
|
||||
|
||||
#define PROFILE_NUM_MEM_ACCESS_PROFILES 4
|
||||
|
||||
static u64 profile_num_accesses[2][3];
|
||||
static u64 profile_unknown_addresses[2][3];
|
||||
static struct mem_access_profile
|
||||
profile_memory_accesses[2][3][PROFILE_NUM_MEM_ACCESS_PROFILES];
|
||||
|
||||
static void
|
||||
setup_profiling( void) {
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < 2; i++) {
|
||||
int access_type;
|
||||
|
||||
for ( access_type = 0; access_type < 3; access_type++) {
|
||||
profile_num_accesses[i][access_type] = 0;
|
||||
profile_unknown_addresses[i][access_type] = 0;
|
||||
|
||||
/*
|
||||
* Setup the access testing structures
|
||||
*/
|
||||
profile_memory_accesses[i][access_type][0].address_mask = 0x0e000000;
|
||||
profile_memory_accesses[i][access_type][0].masked_value = 0x00000000;
|
||||
profile_memory_accesses[i][access_type][0].num_accesses = 0;
|
||||
|
||||
/* main memory */
|
||||
profile_memory_accesses[i][access_type][1].address_mask = 0x0f000000;
|
||||
profile_memory_accesses[i][access_type][1].masked_value = 0x02000000;
|
||||
profile_memory_accesses[i][access_type][1].num_accesses = 0;
|
||||
|
||||
/* shared memory */
|
||||
profile_memory_accesses[i][access_type][2].address_mask = 0x0f800000;
|
||||
profile_memory_accesses[i][access_type][2].masked_value = 0x03000000;
|
||||
profile_memory_accesses[i][access_type][2].num_accesses = 0;
|
||||
|
||||
/* arm7 memory */
|
||||
profile_memory_accesses[i][access_type][3].address_mask = 0x0f800000;
|
||||
profile_memory_accesses[i][access_type][3].masked_value = 0x03800000;
|
||||
profile_memory_accesses[i][access_type][3].num_accesses = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
profile_memory_access( int arm9, u32 adr, int access_type) {
|
||||
static int first = 1;
|
||||
int mem_profile;
|
||||
int address_found = 0;
|
||||
|
||||
if ( first) {
|
||||
setup_profiling();
|
||||
first = 0;
|
||||
}
|
||||
|
||||
profile_num_accesses[arm9][access_type] += 1;
|
||||
|
||||
for ( mem_profile = 0;
|
||||
mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES &&
|
||||
!address_found;
|
||||
mem_profile++) {
|
||||
if ( (adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask) ==
|
||||
profile_memory_accesses[arm9][access_type][mem_profile].masked_value) {
|
||||
/*printf( "adr %08x mask %08x res %08x expected %08x\n",
|
||||
adr,
|
||||
profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
|
||||
adr & profile_memory_accesses[arm9][access_type][mem_profile].address_mask,
|
||||
profile_memory_accesses[arm9][access_type][mem_profile].masked_value);*/
|
||||
address_found = 1;
|
||||
profile_memory_accesses[arm9][access_type][mem_profile].num_accesses += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !address_found) {
|
||||
profile_unknown_addresses[arm9][access_type] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *access_type_strings[] = {
|
||||
"prefetch",
|
||||
"read ",
|
||||
"write "
|
||||
};
|
||||
|
||||
void
|
||||
print_memory_profiling( void) {
|
||||
int arm;
|
||||
|
||||
printf("------ Memory access profile ------\n");
|
||||
|
||||
for ( arm = 0; arm < 2; arm++) {
|
||||
int access_type;
|
||||
|
||||
for ( access_type = 0; access_type < 3; access_type++) {
|
||||
int mem_profile;
|
||||
printf("ARM%c: num of %s %lld\n",
|
||||
arm ? '9' : '7',
|
||||
access_type_strings[access_type],
|
||||
profile_num_accesses[arm][access_type]);
|
||||
|
||||
for ( mem_profile = 0;
|
||||
mem_profile < PROFILE_NUM_MEM_ACCESS_PROFILES;
|
||||
mem_profile++) {
|
||||
printf( "address %08x: %lld\n",
|
||||
profile_memory_accesses[arm][access_type][mem_profile].masked_value,
|
||||
profile_memory_accesses[arm][access_type][mem_profile].num_accesses);
|
||||
}
|
||||
|
||||
printf( "unknown addresses %lld\n",
|
||||
profile_unknown_addresses[arm][access_type]);
|
||||
|
||||
printf( "\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("------ End of Memory access profile ------\n\n");
|
||||
}
|
||||
#else
|
||||
void
|
||||
print_memory_profiling( void) {
|
||||
}
|
||||
#endif /* End of PROFILE_MEMORY_ACCESS area */
|
||||
|
||||
static u16 FASTCALL
|
||||
arm9_prefetch16( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 1, adr, PROFILE_PREFETCH);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
if((adr & ~0x3FFF) == MMU.DTCMRegion)
|
||||
{
|
||||
/* Returns data from DTCM (ARM9 only) */
|
||||
return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
|
||||
}
|
||||
/* access to main memory */
|
||||
if ( (adr & 0x0f000000) == 0x02000000) {
|
||||
return T1ReadWord( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
|
||||
adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return MMU_read16( ARMCPU_ARM9, adr);
|
||||
}
|
||||
static u32 FASTCALL
|
||||
arm9_prefetch32( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 1, adr, PROFILE_PREFETCH);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
if((adr & ~0x3FFF) == MMU.DTCMRegion)
|
||||
{
|
||||
/* Returns data from DTCM (ARM9 only) */
|
||||
return T1ReadLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
|
||||
}
|
||||
/* access to main memory */
|
||||
if ( (adr & 0x0f000000) == 0x02000000) {
|
||||
return T1ReadLong( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
|
||||
adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return MMU_read32( ARMCPU_ARM9, adr);
|
||||
}
|
||||
|
||||
static u8 FASTCALL
|
||||
arm9_read8( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 1, adr, PROFILE_READ);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
if( (adr&(~0x3FFF)) == MMU.DTCMRegion)
|
||||
{
|
||||
return ARM9Mem.ARM9_DTCM[adr&0x3FFF];
|
||||
}
|
||||
/* access to main memory */
|
||||
if ( (adr & 0x0f000000) == 0x02000000) {
|
||||
return MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF]
|
||||
[adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]];
|
||||
}
|
||||
#endif
|
||||
|
||||
return MMU_read8( ARMCPU_ARM9, adr);
|
||||
}
|
||||
static u16 FASTCALL
|
||||
arm9_read16( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 1, adr, PROFILE_READ);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
if((adr & ~0x3FFF) == MMU.DTCMRegion)
|
||||
{
|
||||
/* Returns data from DTCM (ARM9 only) */
|
||||
return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
|
||||
}
|
||||
|
||||
/* access to main memory */
|
||||
if ( (adr & 0x0f000000) == 0x02000000) {
|
||||
return T1ReadWord( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
|
||||
adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return MMU_read16( ARMCPU_ARM9, adr);
|
||||
}
|
||||
static u32 FASTCALL
|
||||
arm9_read32( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 1, adr, PROFILE_READ);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
if((adr & ~0x3FFF) == MMU.DTCMRegion)
|
||||
{
|
||||
/* Returns data from DTCM (ARM9 only) */
|
||||
return T1ReadLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF);
|
||||
}
|
||||
/* access to main memory */
|
||||
if ( (adr & 0x0f000000) == 0x02000000) {
|
||||
return T1ReadLong( MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF],
|
||||
adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return MMU_read32( ARMCPU_ARM9, adr);
|
||||
}
|
||||
|
||||
|
||||
static void FASTCALL
|
||||
arm9_write8(void *data, u32 adr, u8 val) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 1, adr, PROFILE_WRITE);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
if( (adr & ~0x3FFF) == MMU.DTCMRegion)
|
||||
{
|
||||
/* Writes data in DTCM (ARM9 only) */
|
||||
ARM9Mem.ARM9_DTCM[adr&0x3FFF] = val;
|
||||
return ;
|
||||
}
|
||||
/* main memory */
|
||||
if ( (adr & 0x0f000000) == 0x02000000) {
|
||||
MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF]
|
||||
[adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]] = val;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
MMU_write8( ARMCPU_ARM9, adr, val);
|
||||
}
|
||||
static void FASTCALL
|
||||
arm9_write16(void *data, u32 adr, u16 val) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 1, adr, PROFILE_WRITE);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
if((adr & ~0x3FFF) == MMU.DTCMRegion)
|
||||
{
|
||||
/* Writes in DTCM (ARM9 only) */
|
||||
T1WriteWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
|
||||
return;
|
||||
}
|
||||
/* main memory */
|
||||
if ( (adr & 0x0f000000) == 0x02000000) {
|
||||
T1WriteWord( MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF],
|
||||
adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF], val);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
MMU_write16( ARMCPU_ARM9, adr, val);
|
||||
}
|
||||
static void FASTCALL
|
||||
arm9_write32(void *data, u32 adr, u32 val) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 1, adr, PROFILE_WRITE);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
if((adr & ~0x3FFF) == MMU.DTCMRegion)
|
||||
{
|
||||
/* Writes in DTCM (ARM9 only) */
|
||||
T1WriteLong(ARM9Mem.ARM9_DTCM, adr & 0x3FFF, val);
|
||||
return;
|
||||
}
|
||||
/* main memory */
|
||||
if ( (adr & 0x0f000000) == 0x02000000) {
|
||||
T1WriteLong( MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF],
|
||||
adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF], val);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
MMU_write32( ARMCPU_ARM9, adr, val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static u16 FASTCALL
|
||||
arm7_prefetch16( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 0, adr, PROFILE_PREFETCH);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
/* ARM7 private memory */
|
||||
if ( (adr & 0x0f800000) == 0x03800000) {
|
||||
T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF],
|
||||
adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return MMU_read16( ARMCPU_ARM7, adr);
|
||||
}
|
||||
static u32 FASTCALL
|
||||
arm7_prefetch32( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 0, adr, PROFILE_PREFETCH);
|
||||
#endif
|
||||
|
||||
#ifdef EARLY_MEMORY_ACCESS
|
||||
/* ARM7 private memory */
|
||||
if ( (adr & 0x0f800000) == 0x03800000) {
|
||||
T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF],
|
||||
adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return MMU_read32( ARMCPU_ARM7, adr);
|
||||
}
|
||||
|
||||
static u8 FASTCALL
|
||||
arm7_read8( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 0, adr, PROFILE_READ);
|
||||
#endif
|
||||
|
||||
return MMU_read8( ARMCPU_ARM7, adr);
|
||||
}
|
||||
static u16 FASTCALL
|
||||
arm7_read16( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 0, adr, PROFILE_READ);
|
||||
#endif
|
||||
|
||||
return MMU_read16( ARMCPU_ARM7, adr);
|
||||
}
|
||||
static u32 FASTCALL
|
||||
arm7_read32( void *data, u32 adr) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 0, adr, PROFILE_READ);
|
||||
#endif
|
||||
|
||||
return MMU_read32( ARMCPU_ARM7, adr);
|
||||
}
|
||||
|
||||
|
||||
static void FASTCALL
|
||||
arm7_write8(void *data, u32 adr, u8 val) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 0, adr, PROFILE_WRITE);
|
||||
#endif
|
||||
|
||||
MMU_write8( ARMCPU_ARM7, adr, val);
|
||||
}
|
||||
static void FASTCALL
|
||||
arm7_write16(void *data, u32 adr, u16 val) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 0, adr, PROFILE_WRITE);
|
||||
#endif
|
||||
|
||||
MMU_write16( ARMCPU_ARM7, adr, val);
|
||||
}
|
||||
static void FASTCALL
|
||||
arm7_write32(void *data, u32 adr, u32 val) {
|
||||
#ifdef PROFILE_MEMORY_ACCESS
|
||||
profile_memory_access( 0, adr, PROFILE_WRITE);
|
||||
#endif
|
||||
|
||||
MMU_write32( ARMCPU_ARM7, adr, val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* the base memory interfaces
|
||||
*/
|
||||
struct armcpu_memory_iface arm9_base_memory_iface = {
|
||||
#ifdef __GNUC__
|
||||
.prefetch32 = arm9_prefetch32,
|
||||
.prefetch16 = arm9_prefetch16,
|
||||
|
||||
.read8 = arm9_read8,
|
||||
.read16 = arm9_read16,
|
||||
.read32 = arm9_read32,
|
||||
|
||||
.write8 = arm9_write8,
|
||||
.write16 = arm9_write16,
|
||||
.write32 = arm9_write32
|
||||
#else
|
||||
arm9_prefetch32,
|
||||
arm9_prefetch16,
|
||||
|
||||
arm9_read8,
|
||||
arm9_read16,
|
||||
arm9_read32,
|
||||
|
||||
arm9_write8,
|
||||
arm9_write16,
|
||||
arm9_write32
|
||||
#endif
|
||||
};
|
||||
|
||||
struct armcpu_memory_iface arm7_base_memory_iface = {
|
||||
#ifdef __GNUC__
|
||||
.prefetch32 = arm7_prefetch32,
|
||||
.prefetch16 = arm7_prefetch16,
|
||||
|
||||
.read8 = arm7_read8,
|
||||
.read16 = arm7_read16,
|
||||
.read32 = arm7_read32,
|
||||
|
||||
.write8 = arm7_write8,
|
||||
.write16 = arm7_write16,
|
||||
.write32 = arm7_write32
|
||||
#else
|
||||
arm7_prefetch32,
|
||||
arm7_prefetch16,
|
||||
|
||||
arm7_read8,
|
||||
arm7_read16,
|
||||
arm7_read32,
|
||||
|
||||
arm7_write8,
|
||||
arm7_write16,
|
||||
arm7_write32
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* The direct memory interface for the ARM9.
|
||||
* This avoids the ARM9 protection unit when accessing
|
||||
* memory.
|
||||
*/
|
||||
struct armcpu_memory_iface arm9_direct_memory_iface = {
|
||||
#ifdef __GNUC__
|
||||
/* the prefetch is not used */
|
||||
.prefetch32 = NULL,
|
||||
.prefetch16 = NULL,
|
||||
|
||||
.read8 = arm9_read8,
|
||||
.read16 = arm9_read16,
|
||||
.read32 = arm9_read32,
|
||||
|
||||
.write8 = arm9_write8,
|
||||
.write16 = arm9_write16,
|
||||
.write32 = arm9_write32
|
||||
#else
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
arm9_read8,
|
||||
arm9_read16,
|
||||
arm9_read32,
|
||||
|
||||
arm9_write8,
|
||||
arm9_write16,
|
||||
arm9_write32
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -104,6 +104,32 @@ typedef struct {
|
|||
extern MMU_struct MMU;
|
||||
|
||||
|
||||
struct armcpu_memory_iface {
|
||||
/** the 32 bit instruction prefetch */
|
||||
u32 FASTCALL (*prefetch32)( void *data, u32 adr);
|
||||
|
||||
/** the 16 bit instruction prefetch */
|
||||
u16 FASTCALL (*prefetch16)( void *data, u32 adr);
|
||||
|
||||
/** read 8 bit data value */
|
||||
u8 FASTCALL (*read8)( void *data, u32 adr);
|
||||
/** read 16 bit data value */
|
||||
u16 FASTCALL (*read16)( void *data, u32 adr);
|
||||
/** read 32 bit data value */
|
||||
u32 FASTCALL (*read32)( void *data, u32 adr);
|
||||
|
||||
/** write 8 bit data value */
|
||||
void FASTCALL (*write8)( void *data, u32 adr, u8 val);
|
||||
/** write 16 bit data value */
|
||||
void FASTCALL (*write16)( void *data, u32 adr, u16 val);
|
||||
/** write 32 bit data value */
|
||||
void FASTCALL (*write32)( void *data, u32 adr, u32 val);
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void mmu_select_savetype(int type, int *bmemtype, u32 *bmemsize) {
|
||||
if (type<0 || type > 5) return;
|
||||
*bmemtype=save_types[type][0];
|
||||
|
@ -164,6 +190,15 @@ void FASTCALL MMU_writeXX(u32 proc, u32 adr, u32 val, u8 nbbytes);
|
|||
|
||||
void FASTCALL MMU_doDMA(u32 proc, u32 num);
|
||||
|
||||
|
||||
/*
|
||||
* The base ARM memory interfaces
|
||||
*/
|
||||
extern struct armcpu_memory_iface arm9_base_memory_iface;
|
||||
extern struct armcpu_memory_iface arm7_base_memory_iface;
|
||||
extern struct armcpu_memory_iface arm9_direct_memory_iface;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "MMU.h"
|
||||
#include "cflash.h"
|
||||
|
||||
#include "MMU.h"
|
||||
#include "cflash.h"
|
||||
#include "ROMReader.h"
|
||||
|
||||
NDSSystem nds;
|
||||
|
@ -56,7 +58,10 @@ calc_CRC16( u32 start, u8 *data, int count) {
|
|||
return crc;
|
||||
}
|
||||
|
||||
int NDS_Init(void) {
|
||||
int NDS_Init( struct armcpu_memory_iface *arm9_mem_if,
|
||||
struct armcpu_ctrl_iface **arm9_ctrl_iface,
|
||||
struct armcpu_memory_iface *arm7_mem_if,
|
||||
struct armcpu_ctrl_iface **arm7_ctrl_iface) {
|
||||
nds.ARM9Cycle = 0;
|
||||
nds.ARM7Cycle = 0;
|
||||
nds.cycles = 0;
|
||||
|
@ -68,8 +73,8 @@ int NDS_Init(void) {
|
|||
if (Screen_Init(GFXCORE_DUMMY) != 0)
|
||||
return -1;
|
||||
|
||||
armcpu_new(&NDS_ARM7,1);
|
||||
armcpu_new(&NDS_ARM9,0);
|
||||
armcpu_new(&NDS_ARM7,1, arm7_mem_if, arm7_ctrl_iface);
|
||||
armcpu_new(&NDS_ARM9,0, arm9_mem_if, arm9_ctrl_iface);
|
||||
|
||||
if (SPU_Init(SNDCORE_DUMMY, 735) != 0)
|
||||
return -1;
|
||||
|
@ -212,7 +217,8 @@ enum
|
|||
ROM_DSGBA
|
||||
};
|
||||
|
||||
int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize)
|
||||
int NDS_LoadROM( const char *filename, int bmtype, u32 bmsize,
|
||||
const char *cflash_disk_image_file)
|
||||
{
|
||||
int i;
|
||||
int type;
|
||||
|
@ -283,7 +289,7 @@ int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize)
|
|||
* so the current one should be ok */
|
||||
strncpy(szRomPath, ".", 512); /* "." is shorter then 512, yet strcpy should be avoided */
|
||||
cflash_close();
|
||||
cflash_init();
|
||||
cflash_init( cflash_disk_image_file);
|
||||
|
||||
strncpy(szRomBaseName, filename,512);
|
||||
|
||||
|
@ -742,3 +748,656 @@ int NDS_LoadFirmware(const char *filename)
|
|||
|
||||
return i;
|
||||
}
|
||||
|
||||
#define INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF))
|
||||
u32
|
||||
NDS_exec(s32 nb, BOOL force)
|
||||
{
|
||||
nb += nds.cycles;//(nds.cycles>>26)<<26;
|
||||
|
||||
for(; (nb >= nds.cycles) && ((force)||(execute)); )
|
||||
{
|
||||
if(nds.ARM9Cycle<=nds.cycles)
|
||||
{
|
||||
#ifdef LOG_ARM9
|
||||
if(logcount==3){
|
||||
if(NDS_ARM9.CPSR.bits.T)
|
||||
des_thumb_instructions_set[(NDS_ARM9.instruction)>>6](NDS_ARM9.instruct_adr, NDS_ARM9.instruction, logbuf);
|
||||
else
|
||||
des_arm_instructions_set[INDEX(NDS_ARM9.instruction)](NDS_ARM9.instruct_adr, NDS_ARM9.instruction, logbuf);
|
||||
sprintf(logbuf, "%s\t%08X\n\t R00: %08X, R01: %08X, R02: %08X, R03: %08X, R04: %08X, R05: %08X, R06: %08X, R07: %08X,\n\t R08: %08X, R09: %08X, R10: %08X, R11: %08X, R12: %08X, R13: %08X, R14: %08X, R15: %08X,\n\t CPSR: %08X , SPSR: %08X",
|
||||
logbuf, NDS_ARM9.instruction, NDS_ARM9.R[0], NDS_ARM9.R[1], NDS_ARM9.R[2], NDS_ARM9.R[3], NDS_ARM9.R[4], NDS_ARM9.R[5], NDS_ARM9.R[6], NDS_ARM9.R[7],
|
||||
NDS_ARM9.R[8], NDS_ARM9.R[9], NDS_ARM9.R[10], NDS_ARM9.R[11], NDS_ARM9.R[12], NDS_ARM9.R[13], NDS_ARM9.R[14], NDS_ARM9.R[15],
|
||||
NDS_ARM9.CPSR, NDS_ARM9.SPSR);
|
||||
LOG(logbuf);
|
||||
}
|
||||
#endif
|
||||
if(NDS_ARM9.waitIRQ)
|
||||
nds.ARM9Cycle += 100;
|
||||
else
|
||||
//nds.ARM9Cycle += NDS_ARM9.exec();
|
||||
nds.ARM9Cycle += armcpu_exec(&NDS_ARM9);
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_WIFI
|
||||
|
||||
if((nds.ARM7Cycle % 0x3F03) == 0)
|
||||
{
|
||||
/* 3F03 arm7 cyles = ~1usec */
|
||||
WIFI_usTrigger(&wifiMac) ;
|
||||
}
|
||||
#endif
|
||||
if(nds.ARM7Cycle<=nds.cycles)
|
||||
{
|
||||
#ifdef LOG_ARM7
|
||||
if(logcount==1){
|
||||
if(NDS_ARM7.CPSR.bits.T)
|
||||
des_thumb_instructions_set[(NDS_ARM7.instruction)>>6](NDS_ARM7.instruct_adr, NDS_ARM7.instruction, logbuf);
|
||||
else
|
||||
des_arm_instructions_set[INDEX(NDS_ARM7.instruction)](NDS_ARM7.instruct_adr, NDS_ARM7.instruction, logbuf);
|
||||
sprintf(logbuf, "%s\n\t R00: %08X, R01: %08X, R02: %08X, R03: %08X, R04: %08X, R05: %08X, R06: %08X, R07: %08X,\n\t R08: %08X, R09: %08X, R10: %08X, R11: %08X, R12: %08X, R13: %08X, R14: %08X, R15: %08X,\n\t CPSR: %08X , SPSR: %08X",
|
||||
logbuf, NDS_ARM7.R[0], NDS_ARM7.R[1], NDS_ARM7.R[2], NDS_ARM7.R[3], NDS_ARM7.R[4], NDS_ARM7.R[5], NDS_ARM7.R[6], NDS_ARM7.R[7],
|
||||
NDS_ARM7.R[8], NDS_ARM7.R[9], NDS_ARM7.R[10], NDS_ARM7.R[11], NDS_ARM7.R[12], NDS_ARM7.R[13], NDS_ARM7.R[14], NDS_ARM7.R[15],
|
||||
NDS_ARM7.CPSR, NDS_ARM7.SPSR);
|
||||
LOG(logbuf);
|
||||
}
|
||||
#endif
|
||||
if(NDS_ARM7.waitIRQ)
|
||||
nds.ARM7Cycle += 100;
|
||||
else
|
||||
//nds.ARM7Cycle += (NDS_ARM7.exec()<<1);
|
||||
nds.ARM7Cycle += (armcpu_exec(&NDS_ARM7)<<1);
|
||||
}
|
||||
nds.cycles = (nds.ARM9Cycle<nds.ARM7Cycle)?nds.ARM9Cycle : nds.ARM7Cycle;
|
||||
|
||||
//debug();
|
||||
|
||||
if(nds.cycles>=nds.nextHBlank)
|
||||
{
|
||||
if(!nds.lignerendu)
|
||||
{
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 2);
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 2);
|
||||
NDS_ARM9HBlankInt();
|
||||
NDS_ARM7HBlankInt();
|
||||
|
||||
if(nds.VCount<192)
|
||||
{
|
||||
GPU_ligne(&MainScreen, nds.VCount);
|
||||
GPU_ligne(&SubScreen, nds.VCount);
|
||||
|
||||
if(MMU.DMAStartTime[0][0] == 2)
|
||||
MMU_doDMA(0, 0);
|
||||
if(MMU.DMAStartTime[0][1] == 2)
|
||||
MMU_doDMA(0, 1);
|
||||
if(MMU.DMAStartTime[0][2] == 2)
|
||||
MMU_doDMA(0, 2);
|
||||
if(MMU.DMAStartTime[0][3] == 2)
|
||||
MMU_doDMA(0, 3);
|
||||
}
|
||||
nds.lignerendu = TRUE;
|
||||
}
|
||||
if(nds.cycles>=nds.nextHBlank+1092)
|
||||
{
|
||||
u32 vmatch;
|
||||
|
||||
++nds.VCount;
|
||||
nds.nextHBlank += 4260;
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFD);
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFD);
|
||||
|
||||
if(MMU.DMAStartTime[0][0] == 3)
|
||||
MMU_doDMA(0, 0);
|
||||
if(MMU.DMAStartTime[0][1] == 3)
|
||||
MMU_doDMA(0, 1);
|
||||
if(MMU.DMAStartTime[0][2] == 3)
|
||||
MMU_doDMA(0, 2);
|
||||
if(MMU.DMAStartTime[0][3] == 3)
|
||||
MMU_doDMA(0, 3);
|
||||
|
||||
// Main memory display
|
||||
if(MMU.DMAStartTime[0][0] == 4)
|
||||
{
|
||||
MMU_doDMA(0, 0);
|
||||
MMU.DMAStartTime[0][0] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[0][1] == 4)
|
||||
{
|
||||
MMU_doDMA(0, 1);
|
||||
MMU.DMAStartTime[0][1] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[0][2] == 4)
|
||||
{
|
||||
MMU_doDMA(0, 2);
|
||||
MMU.DMAStartTime[0][2] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[0][3] == 4)
|
||||
{
|
||||
MMU_doDMA(0, 3);
|
||||
MMU.DMAStartTime[0][3] = 0;
|
||||
}
|
||||
|
||||
if(MMU.DMAStartTime[1][0] == 4)
|
||||
{
|
||||
MMU_doDMA(1, 0);
|
||||
MMU.DMAStartTime[1][0] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[1][1] == 4)
|
||||
{
|
||||
MMU_doDMA(1, 1);
|
||||
MMU.DMAStartTime[0][1] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[1][2] == 4)
|
||||
{
|
||||
MMU_doDMA(1, 2);
|
||||
MMU.DMAStartTime[1][2] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[1][3] == 4)
|
||||
{
|
||||
MMU_doDMA(1, 3);
|
||||
MMU.DMAStartTime[1][3] = 0;
|
||||
}
|
||||
|
||||
nds.lignerendu = FALSE;
|
||||
if(nds.VCount==192)
|
||||
{
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 1);
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 1);
|
||||
NDS_ARM9VBlankInt();
|
||||
NDS_ARM7VBlankInt();
|
||||
|
||||
if(MMU.DMAStartTime[0][0] == 1)
|
||||
MMU_doDMA(0, 0);
|
||||
if(MMU.DMAStartTime[0][1] == 1)
|
||||
MMU_doDMA(0, 1);
|
||||
if(MMU.DMAStartTime[0][2] == 1)
|
||||
MMU_doDMA(0, 2);
|
||||
if(MMU.DMAStartTime[0][3] == 1)
|
||||
MMU_doDMA(0, 3);
|
||||
|
||||
if(MMU.DMAStartTime[1][0] == 1)
|
||||
MMU_doDMA(1, 0);
|
||||
if(MMU.DMAStartTime[1][1] == 1)
|
||||
MMU_doDMA(1, 1);
|
||||
if(MMU.DMAStartTime[1][2] == 1)
|
||||
MMU_doDMA(1, 2);
|
||||
if(MMU.DMAStartTime[1][3] == 1)
|
||||
MMU_doDMA(1, 3);
|
||||
}
|
||||
else
|
||||
if(nds.VCount==263)
|
||||
{
|
||||
nds.nextHBlank = 3168;
|
||||
nds.VCount = 0;
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFE);
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFE);
|
||||
|
||||
nds.cycles -= (560190<<1);
|
||||
nds.ARM9Cycle -= (560190<<1);
|
||||
nds.ARM7Cycle -= (560190<<1);
|
||||
nb -= (560190<<1);
|
||||
if(MMU.timerON[0][0])
|
||||
nds.timerCycle[0][0] -= (560190<<1);
|
||||
if(MMU.timerON[0][1])
|
||||
nds.timerCycle[0][1] -= (560190<<1);
|
||||
if(MMU.timerON[0][2])
|
||||
nds.timerCycle[0][2] -= (560190<<1);
|
||||
if(MMU.timerON[0][3])
|
||||
nds.timerCycle[0][3] -= (560190<<1);
|
||||
|
||||
if(MMU.timerON[1][0])
|
||||
nds.timerCycle[1][0] -= (560190<<1);
|
||||
if(MMU.timerON[1][1])
|
||||
nds.timerCycle[1][1] -= (560190<<1);
|
||||
if(MMU.timerON[1][2])
|
||||
nds.timerCycle[1][2] -= (560190<<1);
|
||||
if(MMU.timerON[1][3])
|
||||
nds.timerCycle[1][3] -= (560190<<1);
|
||||
if(MMU.DMAing[0][0])
|
||||
MMU.DMACycle[0][0] -= (560190<<1);
|
||||
if(MMU.DMAing[0][1])
|
||||
MMU.DMACycle[0][1] -= (560190<<1);
|
||||
if(MMU.DMAing[0][2])
|
||||
MMU.DMACycle[0][2] -= (560190<<1);
|
||||
if(MMU.DMAing[0][3])
|
||||
MMU.DMACycle[0][3] -= (560190<<1);
|
||||
if(MMU.DMAing[1][0])
|
||||
MMU.DMACycle[1][0] -= (560190<<1);
|
||||
if(MMU.DMAing[1][1])
|
||||
MMU.DMACycle[1][1] -= (560190<<1);
|
||||
if(MMU.DMAing[1][2])
|
||||
MMU.DMACycle[1][2] -= (560190<<1);
|
||||
if(MMU.DMAing[1][3])
|
||||
MMU.DMACycle[1][3] -= (560190<<1);
|
||||
}
|
||||
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 6, nds.VCount);
|
||||
T1WriteWord(MMU.ARM7_REG, 6, nds.VCount);
|
||||
|
||||
vmatch = T1ReadWord(ARM9Mem.ARM9_REG, 4);
|
||||
if((nds.VCount==(vmatch>>8)|((vmatch<<1)&(1<<8))))
|
||||
{
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 4);
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 32)
|
||||
NDS_makeARM9Int(2);
|
||||
}
|
||||
else
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFB);
|
||||
|
||||
vmatch = T1ReadWord(MMU.ARM7_REG, 4);
|
||||
if((nds.VCount==(vmatch>>8)|((vmatch<<1)&(1<<8))))
|
||||
{
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 4);
|
||||
if(T1ReadWord(MMU.ARM7_REG, 4) & 32)
|
||||
NDS_makeARM7Int(2);
|
||||
}
|
||||
else
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFB);
|
||||
}
|
||||
}
|
||||
/* assume the timers have not expired */
|
||||
nds.timerOver[0][0] = 0;
|
||||
nds.timerOver[0][1] = 0;
|
||||
nds.timerOver[0][2] = 0;
|
||||
nds.timerOver[0][3] = 0;
|
||||
nds.timerOver[1][0] = 0;
|
||||
nds.timerOver[1][1] = 0;
|
||||
nds.timerOver[1][2] = 0;
|
||||
nds.timerOver[1][3] = 0;
|
||||
if(MMU.timerON[0][0])
|
||||
{
|
||||
if(MMU.timerRUN[0][0])
|
||||
{
|
||||
switch(MMU.timerMODE[0][0])
|
||||
{
|
||||
case 0xFFFF :
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[0][0])>>MMU.timerMODE[0][0];
|
||||
nds.old = MMU.timer[0][0];
|
||||
MMU.timer[0][0] += nds.diff;
|
||||
nds.timerCycle[0][0] += (nds.diff << MMU.timerMODE[0][0]);
|
||||
nds.timerOver[0][0] = nds.old>MMU.timer[0][0];
|
||||
if(nds.timerOver[0][0])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x102) & 0x40)
|
||||
NDS_makeARM9Int(3);
|
||||
MMU.timer[0][0] = MMU.timerReload[0][0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[0][0] = TRUE;
|
||||
nds.timerCycle[0][0] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[0][1])
|
||||
{
|
||||
if(MMU.timerRUN[0][1])
|
||||
{
|
||||
switch(MMU.timerMODE[0][1])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[0][0])
|
||||
{
|
||||
++(MMU.timer[0][1]);
|
||||
nds.timerOver[0][1] = !MMU.timer[0][1];
|
||||
if (nds.timerOver[0][1])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x106) & 0x40)
|
||||
NDS_makeARM9Int(4);
|
||||
MMU.timer[0][1] = MMU.timerReload[0][1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[0][1])>>MMU.timerMODE[0][1];
|
||||
nds.old = MMU.timer[0][1];
|
||||
MMU.timer[0][1] += nds.diff;
|
||||
nds.timerCycle[0][1] += nds.diff << MMU.timerMODE[0][1];
|
||||
nds.timerOver[0][1] = nds.old>MMU.timer[0][1];
|
||||
if(nds.timerOver[0][1])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x106) & 0x40)
|
||||
NDS_makeARM9Int(4);
|
||||
MMU.timer[0][1] = MMU.timerReload[0][1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[0][1] = TRUE;
|
||||
nds.timerCycle[0][1] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[0][2])
|
||||
{
|
||||
if(MMU.timerRUN[0][2])
|
||||
{
|
||||
switch(MMU.timerMODE[0][2])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[0][1])
|
||||
{
|
||||
++(MMU.timer[0][2]);
|
||||
nds.timerOver[0][2] = !MMU.timer[0][2];
|
||||
if (nds.timerOver[0][2])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x10A) & 0x40)
|
||||
NDS_makeARM9Int(5);
|
||||
MMU.timer[0][2] = MMU.timerReload[0][2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[0][2])>>MMU.timerMODE[0][2];
|
||||
nds.old = MMU.timer[0][2];
|
||||
MMU.timer[0][2] += nds.diff;
|
||||
nds.timerCycle[0][2] += nds.diff << MMU.timerMODE[0][2];
|
||||
nds.timerOver[0][2] = nds.old>MMU.timer[0][2];
|
||||
if(nds.timerOver[0][2])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x10A) & 0x40)
|
||||
NDS_makeARM9Int(5);
|
||||
MMU.timer[0][2] = MMU.timerReload[0][2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[0][2] = TRUE;
|
||||
nds.timerCycle[0][2] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[0][3])
|
||||
{
|
||||
if(MMU.timerRUN[0][3])
|
||||
{
|
||||
switch(MMU.timerMODE[0][3])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[0][2])
|
||||
{
|
||||
++(MMU.timer[0][3]);
|
||||
nds.timerOver[0][3] = !MMU.timer[0][3];
|
||||
if (nds.timerOver[0][3])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x10E) & 0x40)
|
||||
NDS_makeARM9Int(6);
|
||||
MMU.timer[0][3] = MMU.timerReload[0][3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[0][3])>>MMU.timerMODE[0][3];
|
||||
nds.old = MMU.timer[0][3];
|
||||
MMU.timer[0][3] += nds.diff;
|
||||
nds.timerCycle[0][3] += nds.diff << MMU.timerMODE[0][3];
|
||||
nds.timerOver[0][3] = nds.old>MMU.timer[0][3];
|
||||
if(nds.timerOver[0][3])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x10E) & 0x40)
|
||||
NDS_makeARM9Int(6);
|
||||
MMU.timer[0][3] = MMU.timerReload[0][3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[0][3] = TRUE;
|
||||
nds.timerCycle[0][3] = nds.cycles;
|
||||
}
|
||||
}
|
||||
|
||||
if(MMU.timerON[1][0])
|
||||
{
|
||||
if(MMU.timerRUN[1][0])
|
||||
{
|
||||
switch(MMU.timerMODE[1][0])
|
||||
{
|
||||
case 0xFFFF :
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[1][0])>>MMU.timerMODE[1][0];
|
||||
nds.old = MMU.timer[1][0];
|
||||
MMU.timer[1][0] += nds.diff;
|
||||
nds.timerCycle[1][0] += nds.diff << MMU.timerMODE[1][0];
|
||||
nds.timerOver[1][0] = nds.old>MMU.timer[1][0];
|
||||
if(nds.timerOver[1][0])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x102) & 0x40)
|
||||
NDS_makeARM7Int(3);
|
||||
MMU.timer[1][0] = MMU.timerReload[1][0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[1][0] = TRUE;
|
||||
nds.timerCycle[1][0] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[1][1])
|
||||
{
|
||||
if(MMU.timerRUN[1][1])
|
||||
{
|
||||
switch(MMU.timerMODE[1][1])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[1][0])
|
||||
{
|
||||
++(MMU.timer[1][1]);
|
||||
nds.timerOver[1][1] = !MMU.timer[1][1];
|
||||
if (nds.timerOver[1][1])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x106) & 0x40)
|
||||
NDS_makeARM7Int(4);
|
||||
MMU.timer[1][1] = MMU.timerReload[1][1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[1][1])>>MMU.timerMODE[1][1];
|
||||
nds.old = MMU.timer[1][1];
|
||||
MMU.timer[1][1] += nds.diff;
|
||||
nds.timerCycle[1][1] += nds.diff << MMU.timerMODE[1][1];
|
||||
nds.timerOver[1][1] = nds.old>MMU.timer[1][1];
|
||||
if(nds.timerOver[1][1])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x106) & 0x40)
|
||||
NDS_makeARM7Int(4);
|
||||
MMU.timer[1][1] = MMU.timerReload[1][1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[1][1] = TRUE;
|
||||
nds.timerCycle[1][1] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[1][2])
|
||||
{
|
||||
if(MMU.timerRUN[1][2])
|
||||
{
|
||||
switch(MMU.timerMODE[1][2])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[1][1])
|
||||
{
|
||||
++(MMU.timer[1][2]);
|
||||
nds.timerOver[1][2] = !MMU.timer[1][2];
|
||||
if (nds.timerOver[1][2])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x10A) & 0x40)
|
||||
NDS_makeARM7Int(5);
|
||||
MMU.timer[1][2] = MMU.timerReload[1][2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[1][2])>>MMU.timerMODE[1][2];
|
||||
nds.old = MMU.timer[1][2];
|
||||
MMU.timer[1][2] += nds.diff;
|
||||
nds.timerCycle[1][2] += nds.diff << MMU.timerMODE[1][2];
|
||||
nds.timerOver[1][2] = nds.old>MMU.timer[1][2];
|
||||
if(nds.timerOver[1][2])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x10A) & 0x40)
|
||||
NDS_makeARM7Int(5);
|
||||
MMU.timer[1][2] = MMU.timerReload[1][2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[1][2] = TRUE;
|
||||
nds.timerCycle[1][2] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[1][3])
|
||||
{
|
||||
if(MMU.timerRUN[1][3])
|
||||
{
|
||||
switch(MMU.timerMODE[1][3])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[1][2])
|
||||
{
|
||||
++(MMU.timer[1][3]);
|
||||
nds.timerOver[1][3] = !MMU.timer[1][3];
|
||||
if (nds.timerOver[1][3])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x10E) & 0x40)
|
||||
NDS_makeARM7Int(6);
|
||||
MMU.timer[1][3] += MMU.timerReload[1][3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[1][3])>>MMU.timerMODE[1][3];
|
||||
nds.old = MMU.timer[1][3];
|
||||
MMU.timer[1][3] += nds.diff;
|
||||
nds.timerCycle[1][3] += nds.diff << MMU.timerMODE[1][3];
|
||||
nds.timerOver[1][3] = nds.old>MMU.timer[1][3];
|
||||
if(nds.timerOver[1][3])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x10E) & 0x40)
|
||||
NDS_makeARM7Int(6);
|
||||
MMU.timer[1][3] += MMU.timerReload[1][3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[1][3] = TRUE;
|
||||
nds.timerCycle[1][3] = nds.cycles;
|
||||
}
|
||||
}
|
||||
|
||||
if((MMU.DMAing[0][0])&&(MMU.DMACycle[0][0]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[0][0])&(1<<30)) NDS_makeARM9Int(8);
|
||||
MMU.DMAing[0][0] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[0][1])&&(MMU.DMACycle[0][1]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[0][1])&(1<<30)) NDS_makeARM9Int(9);
|
||||
MMU.DMAing[0][1] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[0][2])&&(MMU.DMACycle[0][2]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[0][2])&(1<<30)) NDS_makeARM9Int(10);
|
||||
MMU.DMAing[0][2] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[0][3])&&(MMU.DMACycle[0][3]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[0][3])&(1<<30)) NDS_makeARM9Int(11);
|
||||
MMU.DMAing[0][3] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[1][0])&&(MMU.DMACycle[1][0]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*0), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[1][0])&(1<<30)) NDS_makeARM7Int(8);
|
||||
MMU.DMAing[1][0] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[1][1])&&(MMU.DMACycle[1][1]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*1), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[1][1])&(1<<30)) NDS_makeARM7Int(9);
|
||||
MMU.DMAing[1][1] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[1][2])&&(MMU.DMACycle[1][2]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*2), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[1][2])&(1<<30)) NDS_makeARM7Int(10);
|
||||
MMU.DMAing[1][2] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[1][3])&&(MMU.DMACycle[1][3]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*3), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[1][3])&(1<<30)) NDS_makeARM7Int(11);
|
||||
MMU.DMAing[1][3] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.reg_IF[0]&MMU.reg_IE[0]) && (MMU.reg_IME[0]))
|
||||
//if(NDS_ARM9.irqExeption())
|
||||
if ( armcpu_flagIrq( &NDS_ARM9)) {
|
||||
nds.ARM9Cycle = nds.cycles;
|
||||
}
|
||||
/*
|
||||
if(armcpu_irqExeption(&NDS_ARM9))
|
||||
{
|
||||
nds.ARM9Cycle = nds.cycles;
|
||||
}
|
||||
*/
|
||||
|
||||
if((MMU.reg_IF[1]&MMU.reg_IE[1]) && (MMU.reg_IME[1]))
|
||||
if ( armcpu_flagIrq( &NDS_ARM7)) {
|
||||
nds.ARM7Cycle = nds.cycles;
|
||||
}
|
||||
/*
|
||||
if (armcpu_irqExeption(&NDS_ARM7))
|
||||
nds.ARM7Cycle = nds.cycles;
|
||||
*/
|
||||
|
||||
}
|
||||
return nds.cycles;
|
||||
}
|
||||
|
|
|
@ -127,8 +127,11 @@ typedef struct
|
|||
extern NDSSystem nds;
|
||||
extern NDSFirmware firmware;
|
||||
|
||||
int NDSInit(void);
|
||||
void NDSDeInit(void);
|
||||
int NDS_Init( struct armcpu_memory_iface *arm9_mem_if,
|
||||
struct armcpu_ctrl_iface **arm9_ctrl_iface,
|
||||
struct armcpu_memory_iface *arm7_mem_if,
|
||||
struct armcpu_ctrl_iface **arm7_ctrl_iface);
|
||||
void NDS_DeInit(void);
|
||||
|
||||
BOOL NDS_SetROM(u8 * rom, u32 mask);
|
||||
NDS_header * NDS_getROMHeader(void);
|
||||
|
@ -136,7 +139,8 @@ NDS_header * NDS_getROMHeader(void);
|
|||
void NDS_setTouchPos(u16 x, u16 y);
|
||||
void NDS_releasTouch(void);
|
||||
|
||||
int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize);
|
||||
int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize,
|
||||
const char *cflash_disk_image_file);
|
||||
void NDS_FreeROM(void);
|
||||
void NDS_Reset(void);
|
||||
int NDS_ImportSave(const char *filename);
|
||||
|
@ -144,6 +148,8 @@ int NDS_ImportSave(const char *filename);
|
|||
int NDS_WriteBMP(const char *filename);
|
||||
int NDS_LoadFirmware(const char *filename);
|
||||
int NDS_CreateDummyFirmware(void);
|
||||
u32
|
||||
NDS_exec(s32 nb, BOOL force);
|
||||
|
||||
static INLINE void NDS_ARM9HBlankInt(void)
|
||||
{
|
||||
|
@ -189,648 +195,7 @@ int NDS_CreateDummyFirmware(void);
|
|||
SubScreen.offset = tmp;
|
||||
}
|
||||
|
||||
#define INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF))
|
||||
static INLINE u32 NDS_exec(s32 nb, BOOL force)
|
||||
{
|
||||
nb += nds.cycles;//(nds.cycles>>26)<<26;
|
||||
|
||||
for(; (nb >= nds.cycles) && ((force)||(execute)); )
|
||||
{
|
||||
if(nds.ARM9Cycle<=nds.cycles)
|
||||
{
|
||||
#ifdef LOG_ARM9
|
||||
if(logcount==3){
|
||||
if(NDS_ARM9.CPSR.bits.T)
|
||||
des_thumb_instructions_set[(NDS_ARM9.instruction)>>6](NDS_ARM9.instruct_adr, NDS_ARM9.instruction, logbuf);
|
||||
else
|
||||
des_arm_instructions_set[INDEX(NDS_ARM9.instruction)](NDS_ARM9.instruct_adr, NDS_ARM9.instruction, logbuf);
|
||||
sprintf(logbuf, "%s\t%08X\n\t R00: %08X, R01: %08X, R02: %08X, R03: %08X, R04: %08X, R05: %08X, R06: %08X, R07: %08X,\n\t R08: %08X, R09: %08X, R10: %08X, R11: %08X, R12: %08X, R13: %08X, R14: %08X, R15: %08X,\n\t CPSR: %08X , SPSR: %08X",
|
||||
logbuf, NDS_ARM9.instruction, NDS_ARM9.R[0], NDS_ARM9.R[1], NDS_ARM9.R[2], NDS_ARM9.R[3], NDS_ARM9.R[4], NDS_ARM9.R[5], NDS_ARM9.R[6], NDS_ARM9.R[7],
|
||||
NDS_ARM9.R[8], NDS_ARM9.R[9], NDS_ARM9.R[10], NDS_ARM9.R[11], NDS_ARM9.R[12], NDS_ARM9.R[13], NDS_ARM9.R[14], NDS_ARM9.R[15],
|
||||
NDS_ARM9.CPSR, NDS_ARM9.SPSR);
|
||||
LOG(logbuf);
|
||||
}
|
||||
#endif
|
||||
if(NDS_ARM9.waitIRQ)
|
||||
nds.ARM9Cycle += 100;
|
||||
else
|
||||
//nds.ARM9Cycle += NDS_ARM9.exec();
|
||||
nds.ARM9Cycle += armcpu_exec(&NDS_ARM9);
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_WIFI
|
||||
|
||||
if((nds.ARM7Cycle % 0x3F03) == 0)
|
||||
{
|
||||
/* 3F03 arm7 cyles = ~1usec */
|
||||
WIFI_usTrigger(&wifiMac) ;
|
||||
}
|
||||
#endif
|
||||
if(nds.ARM7Cycle<=nds.cycles)
|
||||
{
|
||||
#ifdef LOG_ARM7
|
||||
if(logcount==1){
|
||||
if(NDS_ARM7.CPSR.bits.T)
|
||||
des_thumb_instructions_set[(NDS_ARM7.instruction)>>6](NDS_ARM7.instruct_adr, NDS_ARM7.instruction, logbuf);
|
||||
else
|
||||
des_arm_instructions_set[INDEX(NDS_ARM7.instruction)](NDS_ARM7.instruct_adr, NDS_ARM7.instruction, logbuf);
|
||||
sprintf(logbuf, "%s\n\t R00: %08X, R01: %08X, R02: %08X, R03: %08X, R04: %08X, R05: %08X, R06: %08X, R07: %08X,\n\t R08: %08X, R09: %08X, R10: %08X, R11: %08X, R12: %08X, R13: %08X, R14: %08X, R15: %08X,\n\t CPSR: %08X , SPSR: %08X",
|
||||
logbuf, NDS_ARM7.R[0], NDS_ARM7.R[1], NDS_ARM7.R[2], NDS_ARM7.R[3], NDS_ARM7.R[4], NDS_ARM7.R[5], NDS_ARM7.R[6], NDS_ARM7.R[7],
|
||||
NDS_ARM7.R[8], NDS_ARM7.R[9], NDS_ARM7.R[10], NDS_ARM7.R[11], NDS_ARM7.R[12], NDS_ARM7.R[13], NDS_ARM7.R[14], NDS_ARM7.R[15],
|
||||
NDS_ARM7.CPSR, NDS_ARM7.SPSR);
|
||||
LOG(logbuf);
|
||||
}
|
||||
#endif
|
||||
if(NDS_ARM7.waitIRQ)
|
||||
nds.ARM7Cycle += 100;
|
||||
else
|
||||
//nds.ARM7Cycle += (NDS_ARM7.exec()<<1);
|
||||
nds.ARM7Cycle += (armcpu_exec(&NDS_ARM7)<<1);
|
||||
}
|
||||
nds.cycles = (nds.ARM9Cycle<nds.ARM7Cycle)?nds.ARM9Cycle : nds.ARM7Cycle;
|
||||
|
||||
debug();
|
||||
|
||||
if(nds.cycles>=nds.nextHBlank)
|
||||
{
|
||||
if(!nds.lignerendu)
|
||||
{
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 2);
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 2);
|
||||
NDS_ARM9HBlankInt();
|
||||
NDS_ARM7HBlankInt();
|
||||
|
||||
if(nds.VCount<192)
|
||||
{
|
||||
GPU_ligne(&MainScreen, nds.VCount);
|
||||
GPU_ligne(&SubScreen, nds.VCount);
|
||||
|
||||
if(MMU.DMAStartTime[0][0] == 2)
|
||||
MMU_doDMA(0, 0);
|
||||
if(MMU.DMAStartTime[0][1] == 2)
|
||||
MMU_doDMA(0, 1);
|
||||
if(MMU.DMAStartTime[0][2] == 2)
|
||||
MMU_doDMA(0, 2);
|
||||
if(MMU.DMAStartTime[0][3] == 2)
|
||||
MMU_doDMA(0, 3);
|
||||
}
|
||||
nds.lignerendu = TRUE;
|
||||
}
|
||||
if(nds.cycles>=nds.nextHBlank+1092)
|
||||
{
|
||||
u32 vmatch;
|
||||
|
||||
++nds.VCount;
|
||||
nds.nextHBlank += 4260;
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFD);
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFD);
|
||||
|
||||
if(MMU.DMAStartTime[0][0] == 3)
|
||||
MMU_doDMA(0, 0);
|
||||
if(MMU.DMAStartTime[0][1] == 3)
|
||||
MMU_doDMA(0, 1);
|
||||
if(MMU.DMAStartTime[0][2] == 3)
|
||||
MMU_doDMA(0, 2);
|
||||
if(MMU.DMAStartTime[0][3] == 3)
|
||||
MMU_doDMA(0, 3);
|
||||
|
||||
// Main memory display
|
||||
if(MMU.DMAStartTime[0][0] == 4)
|
||||
{
|
||||
MMU_doDMA(0, 0);
|
||||
MMU.DMAStartTime[0][0] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[0][1] == 4)
|
||||
{
|
||||
MMU_doDMA(0, 1);
|
||||
MMU.DMAStartTime[0][1] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[0][2] == 4)
|
||||
{
|
||||
MMU_doDMA(0, 2);
|
||||
MMU.DMAStartTime[0][2] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[0][3] == 4)
|
||||
{
|
||||
MMU_doDMA(0, 3);
|
||||
MMU.DMAStartTime[0][3] = 0;
|
||||
}
|
||||
|
||||
if(MMU.DMAStartTime[1][0] == 4)
|
||||
{
|
||||
MMU_doDMA(1, 0);
|
||||
MMU.DMAStartTime[1][0] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[1][1] == 4)
|
||||
{
|
||||
MMU_doDMA(1, 1);
|
||||
MMU.DMAStartTime[0][1] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[1][2] == 4)
|
||||
{
|
||||
MMU_doDMA(1, 2);
|
||||
MMU.DMAStartTime[1][2] = 0;
|
||||
}
|
||||
if(MMU.DMAStartTime[1][3] == 4)
|
||||
{
|
||||
MMU_doDMA(1, 3);
|
||||
MMU.DMAStartTime[1][3] = 0;
|
||||
}
|
||||
|
||||
nds.lignerendu = FALSE;
|
||||
if(nds.VCount==192)
|
||||
{
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 1);
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 1);
|
||||
NDS_ARM9VBlankInt();
|
||||
NDS_ARM7VBlankInt();
|
||||
|
||||
if(MMU.DMAStartTime[0][0] == 1)
|
||||
MMU_doDMA(0, 0);
|
||||
if(MMU.DMAStartTime[0][1] == 1)
|
||||
MMU_doDMA(0, 1);
|
||||
if(MMU.DMAStartTime[0][2] == 1)
|
||||
MMU_doDMA(0, 2);
|
||||
if(MMU.DMAStartTime[0][3] == 1)
|
||||
MMU_doDMA(0, 3);
|
||||
|
||||
if(MMU.DMAStartTime[1][0] == 1)
|
||||
MMU_doDMA(1, 0);
|
||||
if(MMU.DMAStartTime[1][1] == 1)
|
||||
MMU_doDMA(1, 1);
|
||||
if(MMU.DMAStartTime[1][2] == 1)
|
||||
MMU_doDMA(1, 2);
|
||||
if(MMU.DMAStartTime[1][3] == 1)
|
||||
MMU_doDMA(1, 3);
|
||||
}
|
||||
else
|
||||
if(nds.VCount==263)
|
||||
{
|
||||
nds.nextHBlank = 3168;
|
||||
nds.VCount = 0;
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFE);
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFE);
|
||||
|
||||
nds.cycles -= (560190<<1);
|
||||
nds.ARM9Cycle -= (560190<<1);
|
||||
nds.ARM7Cycle -= (560190<<1);
|
||||
nb -= (560190<<1);
|
||||
if(MMU.timerON[0][0])
|
||||
nds.timerCycle[0][0] -= (560190<<1);
|
||||
if(MMU.timerON[0][1])
|
||||
nds.timerCycle[0][1] -= (560190<<1);
|
||||
if(MMU.timerON[0][2])
|
||||
nds.timerCycle[0][2] -= (560190<<1);
|
||||
if(MMU.timerON[0][3])
|
||||
nds.timerCycle[0][3] -= (560190<<1);
|
||||
|
||||
if(MMU.timerON[1][0])
|
||||
nds.timerCycle[1][0] -= (560190<<1);
|
||||
if(MMU.timerON[1][1])
|
||||
nds.timerCycle[1][1] -= (560190<<1);
|
||||
if(MMU.timerON[1][2])
|
||||
nds.timerCycle[1][2] -= (560190<<1);
|
||||
if(MMU.timerON[1][3])
|
||||
nds.timerCycle[1][3] -= (560190<<1);
|
||||
if(MMU.DMAing[0][0])
|
||||
MMU.DMACycle[0][0] -= (560190<<1);
|
||||
if(MMU.DMAing[0][1])
|
||||
MMU.DMACycle[0][1] -= (560190<<1);
|
||||
if(MMU.DMAing[0][2])
|
||||
MMU.DMACycle[0][2] -= (560190<<1);
|
||||
if(MMU.DMAing[0][3])
|
||||
MMU.DMACycle[0][3] -= (560190<<1);
|
||||
if(MMU.DMAing[1][0])
|
||||
MMU.DMACycle[1][0] -= (560190<<1);
|
||||
if(MMU.DMAing[1][1])
|
||||
MMU.DMACycle[1][1] -= (560190<<1);
|
||||
if(MMU.DMAing[1][2])
|
||||
MMU.DMACycle[1][2] -= (560190<<1);
|
||||
if(MMU.DMAing[1][3])
|
||||
MMU.DMACycle[1][3] -= (560190<<1);
|
||||
}
|
||||
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 6, nds.VCount);
|
||||
T1WriteWord(MMU.ARM7_REG, 6, nds.VCount);
|
||||
|
||||
vmatch = T1ReadWord(ARM9Mem.ARM9_REG, 4);
|
||||
if((nds.VCount==(vmatch>>8)|((vmatch<<1)&(1<<8))))
|
||||
{
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 4);
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 32)
|
||||
NDS_makeARM9Int(2);
|
||||
}
|
||||
else
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFB);
|
||||
|
||||
vmatch = T1ReadWord(MMU.ARM7_REG, 4);
|
||||
if((nds.VCount==(vmatch>>8)|((vmatch<<1)&(1<<8))))
|
||||
{
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 4);
|
||||
if(T1ReadWord(MMU.ARM7_REG, 4) & 32)
|
||||
NDS_makeARM7Int(2);
|
||||
}
|
||||
else
|
||||
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFB);
|
||||
}
|
||||
}
|
||||
/* assume the timers have not expired */
|
||||
nds.timerOver[0][0] = 0;
|
||||
nds.timerOver[0][1] = 0;
|
||||
nds.timerOver[0][2] = 0;
|
||||
nds.timerOver[0][3] = 0;
|
||||
nds.timerOver[1][0] = 0;
|
||||
nds.timerOver[1][1] = 0;
|
||||
nds.timerOver[1][2] = 0;
|
||||
nds.timerOver[1][3] = 0;
|
||||
if(MMU.timerON[0][0])
|
||||
{
|
||||
if(MMU.timerRUN[0][0])
|
||||
{
|
||||
switch(MMU.timerMODE[0][0])
|
||||
{
|
||||
case 0xFFFF :
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[0][0])>>MMU.timerMODE[0][0];
|
||||
nds.old = MMU.timer[0][0];
|
||||
MMU.timer[0][0] += nds.diff;
|
||||
nds.timerCycle[0][0] += (nds.diff << MMU.timerMODE[0][0]);
|
||||
nds.timerOver[0][0] = nds.old>MMU.timer[0][0];
|
||||
if(nds.timerOver[0][0])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x102) & 0x40)
|
||||
NDS_makeARM9Int(3);
|
||||
MMU.timer[0][0] = MMU.timerReload[0][0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[0][0] = TRUE;
|
||||
nds.timerCycle[0][0] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[0][1])
|
||||
{
|
||||
if(MMU.timerRUN[0][1])
|
||||
{
|
||||
switch(MMU.timerMODE[0][1])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[0][0])
|
||||
{
|
||||
++(MMU.timer[0][1]);
|
||||
nds.timerOver[0][1] = !MMU.timer[0][1];
|
||||
if (nds.timerOver[0][1])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x106) & 0x40)
|
||||
NDS_makeARM9Int(4);
|
||||
MMU.timer[0][1] = MMU.timerReload[0][1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[0][1])>>MMU.timerMODE[0][1];
|
||||
nds.old = MMU.timer[0][1];
|
||||
MMU.timer[0][1] += nds.diff;
|
||||
nds.timerCycle[0][1] += nds.diff << MMU.timerMODE[0][1];
|
||||
nds.timerOver[0][1] = nds.old>MMU.timer[0][1];
|
||||
if(nds.timerOver[0][1])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x106) & 0x40)
|
||||
NDS_makeARM9Int(4);
|
||||
MMU.timer[0][1] = MMU.timerReload[0][1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[0][1] = TRUE;
|
||||
nds.timerCycle[0][1] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[0][2])
|
||||
{
|
||||
if(MMU.timerRUN[0][2])
|
||||
{
|
||||
switch(MMU.timerMODE[0][2])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[0][1])
|
||||
{
|
||||
++(MMU.timer[0][2]);
|
||||
nds.timerOver[0][2] = !MMU.timer[0][2];
|
||||
if (nds.timerOver[0][2])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x10A) & 0x40)
|
||||
NDS_makeARM9Int(5);
|
||||
MMU.timer[0][2] = MMU.timerReload[0][2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[0][2])>>MMU.timerMODE[0][2];
|
||||
nds.old = MMU.timer[0][2];
|
||||
MMU.timer[0][2] += nds.diff;
|
||||
nds.timerCycle[0][2] += nds.diff << MMU.timerMODE[0][2];
|
||||
nds.timerOver[0][2] = nds.old>MMU.timer[0][2];
|
||||
if(nds.timerOver[0][2])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x10A) & 0x40)
|
||||
NDS_makeARM9Int(5);
|
||||
MMU.timer[0][2] = MMU.timerReload[0][2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[0][2] = TRUE;
|
||||
nds.timerCycle[0][2] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[0][3])
|
||||
{
|
||||
if(MMU.timerRUN[0][3])
|
||||
{
|
||||
switch(MMU.timerMODE[0][3])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[0][2])
|
||||
{
|
||||
++(MMU.timer[0][3]);
|
||||
nds.timerOver[0][3] = !MMU.timer[0][3];
|
||||
if (nds.timerOver[0][3])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x10E) & 0x40)
|
||||
NDS_makeARM9Int(6);
|
||||
MMU.timer[0][3] = MMU.timerReload[0][3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[0][3])>>MMU.timerMODE[0][3];
|
||||
nds.old = MMU.timer[0][3];
|
||||
MMU.timer[0][3] += nds.diff;
|
||||
nds.timerCycle[0][3] += nds.diff << MMU.timerMODE[0][3];
|
||||
nds.timerOver[0][3] = nds.old>MMU.timer[0][3];
|
||||
if(nds.timerOver[0][3])
|
||||
{
|
||||
if(T1ReadWord(ARM9Mem.ARM9_REG, 0x10E) & 0x40)
|
||||
NDS_makeARM9Int(6);
|
||||
MMU.timer[0][3] = MMU.timerReload[0][3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[0][3] = TRUE;
|
||||
nds.timerCycle[0][3] = nds.cycles;
|
||||
}
|
||||
}
|
||||
|
||||
if(MMU.timerON[1][0])
|
||||
{
|
||||
if(MMU.timerRUN[1][0])
|
||||
{
|
||||
switch(MMU.timerMODE[1][0])
|
||||
{
|
||||
case 0xFFFF :
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[1][0])>>MMU.timerMODE[1][0];
|
||||
nds.old = MMU.timer[1][0];
|
||||
MMU.timer[1][0] += nds.diff;
|
||||
nds.timerCycle[1][0] += nds.diff << MMU.timerMODE[1][0];
|
||||
nds.timerOver[1][0] = nds.old>MMU.timer[1][0];
|
||||
if(nds.timerOver[1][0])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x102) & 0x40)
|
||||
NDS_makeARM7Int(3);
|
||||
MMU.timer[1][0] = MMU.timerReload[1][0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[1][0] = TRUE;
|
||||
nds.timerCycle[1][0] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[1][1])
|
||||
{
|
||||
if(MMU.timerRUN[1][1])
|
||||
{
|
||||
switch(MMU.timerMODE[1][1])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[1][0])
|
||||
{
|
||||
++(MMU.timer[1][1]);
|
||||
nds.timerOver[1][1] = !MMU.timer[1][1];
|
||||
if (nds.timerOver[1][1])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x106) & 0x40)
|
||||
NDS_makeARM7Int(4);
|
||||
MMU.timer[1][1] = MMU.timerReload[1][1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[1][1])>>MMU.timerMODE[1][1];
|
||||
nds.old = MMU.timer[1][1];
|
||||
MMU.timer[1][1] += nds.diff;
|
||||
nds.timerCycle[1][1] += nds.diff << MMU.timerMODE[1][1];
|
||||
nds.timerOver[1][1] = nds.old>MMU.timer[1][1];
|
||||
if(nds.timerOver[1][1])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x106) & 0x40)
|
||||
NDS_makeARM7Int(4);
|
||||
MMU.timer[1][1] = MMU.timerReload[1][1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[1][1] = TRUE;
|
||||
nds.timerCycle[1][1] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[1][2])
|
||||
{
|
||||
if(MMU.timerRUN[1][2])
|
||||
{
|
||||
switch(MMU.timerMODE[1][2])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[1][1])
|
||||
{
|
||||
++(MMU.timer[1][2]);
|
||||
nds.timerOver[1][2] = !MMU.timer[1][2];
|
||||
if (nds.timerOver[1][2])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x10A) & 0x40)
|
||||
NDS_makeARM7Int(5);
|
||||
MMU.timer[1][2] = MMU.timerReload[1][2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[1][2])>>MMU.timerMODE[1][2];
|
||||
nds.old = MMU.timer[1][2];
|
||||
MMU.timer[1][2] += nds.diff;
|
||||
nds.timerCycle[1][2] += nds.diff << MMU.timerMODE[1][2];
|
||||
nds.timerOver[1][2] = nds.old>MMU.timer[1][2];
|
||||
if(nds.timerOver[1][2])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x10A) & 0x40)
|
||||
NDS_makeARM7Int(5);
|
||||
MMU.timer[1][2] = MMU.timerReload[1][2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[1][2] = TRUE;
|
||||
nds.timerCycle[1][2] = nds.cycles;
|
||||
}
|
||||
}
|
||||
if(MMU.timerON[1][3])
|
||||
{
|
||||
if(MMU.timerRUN[1][3])
|
||||
{
|
||||
switch(MMU.timerMODE[1][3])
|
||||
{
|
||||
case 0xFFFF :
|
||||
if(nds.timerOver[1][2])
|
||||
{
|
||||
++(MMU.timer[1][3]);
|
||||
nds.timerOver[1][3] = !MMU.timer[1][3];
|
||||
if (nds.timerOver[1][3])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x10E) & 0x40)
|
||||
NDS_makeARM7Int(6);
|
||||
MMU.timer[1][3] += MMU.timerReload[1][3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
{
|
||||
nds.diff = (nds.cycles - nds.timerCycle[1][3])>>MMU.timerMODE[1][3];
|
||||
nds.old = MMU.timer[1][3];
|
||||
MMU.timer[1][3] += nds.diff;
|
||||
nds.timerCycle[1][3] += nds.diff << MMU.timerMODE[1][3];
|
||||
nds.timerOver[1][3] = nds.old>MMU.timer[1][3];
|
||||
if(nds.timerOver[1][3])
|
||||
{
|
||||
if(T1ReadWord(MMU.ARM7_REG, 0x10E) & 0x40)
|
||||
NDS_makeARM7Int(6);
|
||||
MMU.timer[1][3] += MMU.timerReload[1][3];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU.timerRUN[1][3] = TRUE;
|
||||
nds.timerCycle[1][3] = nds.cycles;
|
||||
}
|
||||
}
|
||||
|
||||
if((MMU.DMAing[0][0])&&(MMU.DMACycle[0][0]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[0][0])&(1<<30)) NDS_makeARM9Int(8);
|
||||
MMU.DMAing[0][0] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[0][1])&&(MMU.DMACycle[0][1]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[0][1])&(1<<30)) NDS_makeARM9Int(9);
|
||||
MMU.DMAing[0][1] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[0][2])&&(MMU.DMACycle[0][2]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[0][2])&(1<<30)) NDS_makeARM9Int(10);
|
||||
MMU.DMAing[0][2] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[0][3])&&(MMU.DMACycle[0][3]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[0][3])&(1<<30)) NDS_makeARM9Int(11);
|
||||
MMU.DMAing[0][3] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[1][0])&&(MMU.DMACycle[1][0]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*0), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[1][0])&(1<<30)) NDS_makeARM7Int(8);
|
||||
MMU.DMAing[1][0] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[1][1])&&(MMU.DMACycle[1][1]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*1), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[1][1])&(1<<30)) NDS_makeARM7Int(9);
|
||||
MMU.DMAing[1][1] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[1][2])&&(MMU.DMACycle[1][2]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*2), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[1][2])&(1<<30)) NDS_makeARM7Int(10);
|
||||
MMU.DMAing[1][2] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.DMAing[1][3])&&(MMU.DMACycle[1][3]<=nds.cycles))
|
||||
{
|
||||
T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*3), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF);
|
||||
if((MMU.DMACrt[1][3])&(1<<30)) NDS_makeARM7Int(11);
|
||||
MMU.DMAing[1][3] = FALSE;
|
||||
}
|
||||
|
||||
if((MMU.reg_IF[0]&MMU.reg_IE[0]) && (MMU.reg_IME[0]))
|
||||
//if(NDS_ARM9.irqExeption())
|
||||
if(armcpu_irqExeption(&NDS_ARM9))
|
||||
{
|
||||
nds.ARM9Cycle = nds.cycles;
|
||||
}
|
||||
|
||||
if((MMU.reg_IF[1]&MMU.reg_IE[1]) && (MMU.reg_IME[1]))
|
||||
if (armcpu_irqExeption(&NDS_ARM7))
|
||||
nds.ARM7Cycle = nds.cycles;
|
||||
|
||||
}
|
||||
return nds.cycles;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,8 @@
|
|||
armcpu_t NDS_ARM7;
|
||||
armcpu_t NDS_ARM9;
|
||||
|
||||
#define STALLED_CYCLE_COUNT 10
|
||||
|
||||
#define SWAP(a, b, c) do \
|
||||
{ \
|
||||
c=a; \
|
||||
|
@ -36,14 +38,98 @@ armcpu_t NDS_ARM9;
|
|||
b=c; \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
static void
|
||||
stall_cpu( void *instance) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
|
||||
armcpu->stalled = 1;
|
||||
}
|
||||
|
||||
int armcpu_new(armcpu_t *armcpu, u32 id)
|
||||
|
||||
static void
|
||||
unstall_cpu( void *instance) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
|
||||
armcpu->stalled = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
install_post_exec_fn( void *instance,
|
||||
void (*ex_fn)( void *, u32 adr, int thumb),
|
||||
void *fn_data) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
|
||||
armcpu->post_ex_fn = ex_fn;
|
||||
armcpu->post_ex_fn_data = fn_data;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_post_exec_fn( void *instance) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
|
||||
armcpu->post_ex_fn = NULL;
|
||||
}
|
||||
|
||||
static u32
|
||||
read_cpu_reg( void *instance, u32 reg_num) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
u32 reg_value = 0;
|
||||
|
||||
if ( reg_num <= 14) {
|
||||
reg_value = armcpu->R[reg_num];
|
||||
}
|
||||
else if ( reg_num == 15) {
|
||||
reg_value = armcpu->next_instruction;
|
||||
}
|
||||
else if ( reg_num == 16) {
|
||||
/* CPSR */
|
||||
reg_value = armcpu->CPSR.val;
|
||||
}
|
||||
|
||||
return reg_value;
|
||||
}
|
||||
|
||||
static void
|
||||
set_cpu_reg( void *instance, u32 reg_num, u32 value) {
|
||||
armcpu_t *armcpu = (armcpu_t *)instance;
|
||||
|
||||
if ( reg_num <= 14) {
|
||||
armcpu->R[reg_num] = value;
|
||||
}
|
||||
else if ( reg_num == 15) {
|
||||
armcpu->next_instruction = value;
|
||||
}
|
||||
else if ( reg_num == 16) {
|
||||
/* FIXME: setting the CPSR */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int armcpu_new( armcpu_t *armcpu, u32 id,
|
||||
struct armcpu_memory_iface *mem_if,
|
||||
struct armcpu_ctrl_iface **ctrl_iface_ret)
|
||||
{
|
||||
|
||||
armcpu->proc_ID = id;
|
||||
|
||||
if(id==0) armcpu->swi_tab = ARM9_swi_tab;
|
||||
else armcpu->swi_tab = ARM7_swi_tab;
|
||||
armcpu->mem_if = mem_if;
|
||||
|
||||
/* populate the control interface */
|
||||
armcpu->ctrl_iface.stall = stall_cpu;
|
||||
armcpu->ctrl_iface.unstall = unstall_cpu;
|
||||
armcpu->ctrl_iface.read_reg = read_cpu_reg;
|
||||
armcpu->ctrl_iface.set_reg = set_cpu_reg;
|
||||
armcpu->ctrl_iface.install_post_ex_fn = install_post_exec_fn;
|
||||
armcpu->ctrl_iface.remove_post_ex_fn = remove_post_exec_fn;
|
||||
armcpu->ctrl_iface.data = armcpu;
|
||||
|
||||
*ctrl_iface_ret = &armcpu->ctrl_iface;
|
||||
|
||||
armcpu->stalled = 0;
|
||||
armcpu->post_ex_fn = NULL;
|
||||
|
||||
armcpu_init(armcpu, 0);
|
||||
|
||||
|
@ -58,7 +144,8 @@ void armcpu_init(armcpu_t *armcpu, u32 adr)
|
|||
armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0);
|
||||
armcpu->waitIRQ = FALSE;
|
||||
armcpu->wirq = FALSE;
|
||||
|
||||
armcpu->irq_flag = 0;
|
||||
|
||||
if(armcpu->coproc[15]) free(armcpu->coproc[15]);
|
||||
|
||||
for(i = 0; i < 15; ++i)
|
||||
|
@ -77,11 +164,12 @@ void armcpu_init(armcpu_t *armcpu, u32 adr)
|
|||
armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0;
|
||||
|
||||
armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0;
|
||||
armcpu->instruct_adr = adr;
|
||||
armcpu->next_instruction = adr;
|
||||
armcpu->R[15] = adr;
|
||||
armcpu->R[15] = adr + 8;
|
||||
armcpu->coproc[15] = (armcp_t*)armcp15_new(armcpu);
|
||||
|
||||
armcpu_prefetch(armcpu);
|
||||
|
||||
//armcpu_prefetch(armcpu);
|
||||
}
|
||||
|
||||
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode)
|
||||
|
@ -191,20 +279,34 @@ u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode)
|
|||
return oldmode;
|
||||
}
|
||||
|
||||
u32 armcpu_prefetch(armcpu_t *armcpu)
|
||||
static u32
|
||||
armcpu_prefetch(armcpu_t *armcpu)
|
||||
{
|
||||
u32 temp_instruction;
|
||||
|
||||
if(armcpu->CPSR.bits.T == 0)
|
||||
{
|
||||
armcpu->instruction = MMU_readWordACL(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
|
||||
armcpu->instruct_adr = armcpu->next_instruction;
|
||||
armcpu->next_instruction += 4;
|
||||
armcpu->R[15] = armcpu->next_instruction + 4;
|
||||
return MMU.MMU_WAIT32[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
|
||||
temp_instruction =
|
||||
armcpu->mem_if->prefetch32( armcpu->mem_if->data,
|
||||
armcpu->next_instruction);
|
||||
|
||||
if ( !armcpu->stalled) {
|
||||
armcpu->instruction = temp_instruction;
|
||||
armcpu->instruct_adr = armcpu->next_instruction;
|
||||
armcpu->next_instruction += 4;
|
||||
armcpu->R[15] = armcpu->next_instruction + 4;
|
||||
}
|
||||
return MMU.MMU_WAIT32[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
|
||||
}
|
||||
armcpu->instruction = MMU_readHWordACL(armcpu->proc_ID, armcpu->next_instruction,CP15_ACCESS_EXECUTE);
|
||||
armcpu->instruct_adr = armcpu->next_instruction;
|
||||
armcpu->next_instruction = armcpu->next_instruction + 2;
|
||||
armcpu->R[15] = armcpu->next_instruction + 2;
|
||||
temp_instruction =
|
||||
armcpu->mem_if->prefetch16( armcpu->mem_if->data,
|
||||
armcpu->next_instruction);
|
||||
if ( !armcpu->stalled) {
|
||||
armcpu->instruction = temp_instruction;
|
||||
armcpu->instruct_adr = armcpu->next_instruction;
|
||||
armcpu->next_instruction = armcpu->next_instruction + 2;
|
||||
armcpu->R[15] = armcpu->next_instruction + 2;
|
||||
}
|
||||
return MMU.MMU_WAIT16[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
|
||||
}
|
||||
|
||||
|
@ -238,54 +340,89 @@ static BOOL (*FASTCALL test_conditions[])(Status_Reg CPSR)= {
|
|||
#define TEST_COND2(cond, CPSR) \
|
||||
(cond<15&&test_conditions[cond](CPSR))
|
||||
|
||||
u32 armcpu_exec(armcpu_t *armcpu)
|
||||
{
|
||||
u32 c = 1;
|
||||
if(armcpu->CPSR.bits.T == 0)
|
||||
{
|
||||
if((TEST_COND(CONDITION(armcpu->instruction), armcpu->CPSR)) || ((CONDITION(armcpu->instruction)==0xF)&&(CODE(armcpu->instruction)==0x5)))
|
||||
{
|
||||
c = arm_instructions_set[INSTRUCTION_INDEX(armcpu->instruction)](armcpu);
|
||||
}
|
||||
c += armcpu_prefetch(armcpu);
|
||||
return c;
|
||||
}
|
||||
c = thumb_instructions_set[armcpu->instruction>>6](armcpu);
|
||||
c += armcpu_prefetch(armcpu);
|
||||
return c;
|
||||
}
|
||||
|
||||
BOOL armcpu_irqExeption(armcpu_t *armcpu)
|
||||
static BOOL armcpu_irqExeption(armcpu_t *armcpu)
|
||||
{
|
||||
Status_Reg tmp;
|
||||
if(armcpu->CPSR.bits.I) return FALSE;
|
||||
armcpu->irq_flag = 0;
|
||||
tmp = armcpu->CPSR;
|
||||
armcpu_switchMode(armcpu, IRQ);
|
||||
armcpu->R[14] = armcpu->instruct_adr + 4;
|
||||
armcpu->R[14] = armcpu->next_instruction + 4;
|
||||
armcpu->SPSR = tmp;
|
||||
armcpu->CPSR.bits.T = 0;
|
||||
armcpu->CPSR.bits.I = 1;
|
||||
armcpu->next_instruction = armcpu->intVector + 0x18;
|
||||
armcpu->R[15] = armcpu->next_instruction;
|
||||
//armcpu->R[15] = armcpu->next_instruction + 8;
|
||||
armcpu->waitIRQ = 0;
|
||||
armcpu_prefetch(armcpu);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL armcpu_prefetchExeption(armcpu_t *armcpu)
|
||||
static BOOL armcpu_prefetchExeption(armcpu_t *armcpu)
|
||||
{
|
||||
Status_Reg tmp;
|
||||
if(armcpu->CPSR.bits.I) return FALSE;
|
||||
tmp = armcpu->CPSR;
|
||||
armcpu_switchMode(armcpu, ABT);
|
||||
armcpu->R[14] = armcpu->instruct_adr + 4;
|
||||
armcpu->R[14] = armcpu->next_instruction + 4;
|
||||
armcpu->SPSR = tmp;
|
||||
armcpu->CPSR.bits.T = 0;
|
||||
armcpu->CPSR.bits.I = 1;
|
||||
armcpu->next_instruction = armcpu->intVector + 0xC;
|
||||
armcpu->R[15] = armcpu->next_instruction;
|
||||
armcpu->R[15] = armcpu->next_instruction + 8;
|
||||
armcpu->waitIRQ = 0;
|
||||
armcpu_prefetch(armcpu);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
armcpu_flagIrq( armcpu_t *armcpu) {
|
||||
if(armcpu->CPSR.bits.I) return FALSE;
|
||||
|
||||
armcpu->waitIRQ = 0;
|
||||
armcpu->irq_flag = 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
u32 armcpu_exec(armcpu_t *armcpu)
|
||||
{
|
||||
u32 c;
|
||||
if ( armcpu->stalled)
|
||||
return STALLED_CYCLE_COUNT;
|
||||
|
||||
/* check for interrupts */
|
||||
if ( armcpu->irq_flag) {
|
||||
armcpu_irqExeption( armcpu);
|
||||
}
|
||||
|
||||
c = armcpu_prefetch(armcpu);
|
||||
|
||||
if ( armcpu->stalled) {
|
||||
return c;
|
||||
}
|
||||
|
||||
if(armcpu->CPSR.bits.T == 0)
|
||||
{
|
||||
if((TEST_COND(CONDITION(armcpu->instruction), armcpu->CPSR)) || ((CONDITION(armcpu->instruction)==0xF)&&(CODE(armcpu->instruction)==0x5)))
|
||||
{
|
||||
c += arm_instructions_set[INSTRUCTION_INDEX(armcpu->instruction)](armcpu);
|
||||
}
|
||||
|
||||
if ( armcpu->post_ex_fn != NULL) {
|
||||
/* call the external post execute function */
|
||||
armcpu->post_ex_fn( armcpu->post_ex_fn_data,
|
||||
armcpu->instruct_adr, 0);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
c += thumb_instructions_set[armcpu->instruction>>6](armcpu);
|
||||
|
||||
if ( armcpu->post_ex_fn != NULL) {
|
||||
/* call the external post execute function */
|
||||
armcpu->post_ex_fn( armcpu->post_ex_fn_data, armcpu->instruct_adr, 1);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
|
@ -135,6 +135,35 @@ typedef union
|
|||
} Status_Reg;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The control interface to a CPU
|
||||
*/
|
||||
struct armcpu_ctrl_iface {
|
||||
/** stall the processor */
|
||||
void (*stall)( void *instance);
|
||||
|
||||
/** unstall the processor */
|
||||
void (*unstall)( void *instance);
|
||||
|
||||
/** read a register value */
|
||||
u32 (*read_reg)( void *instance, u32 reg_num);
|
||||
|
||||
/** set a register value */
|
||||
void (*set_reg)( void *instance, u32 reg_num, u32 value);
|
||||
|
||||
/** install the post execute function */
|
||||
void (*install_post_ex_fn)( void *instance,
|
||||
void (*fn)( void *, u32 adr, int thumb),
|
||||
void *fn_data);
|
||||
|
||||
/** remove the post execute function */
|
||||
void (*remove_post_ex_fn)( void *instance);
|
||||
|
||||
/** the private data passed to all interface functions */
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
typedef void* armcp_t;
|
||||
|
||||
typedef struct armcpu_t
|
||||
|
@ -164,18 +193,38 @@ typedef struct armcpu_t
|
|||
BOOL wIRQ;
|
||||
BOOL wirq;
|
||||
|
||||
|
||||
u32 (* *swi_tab)(struct armcpu_t * cpu);
|
||||
|
||||
|
||||
/** there is a pending irq for the cpu */
|
||||
int irq_flag;
|
||||
|
||||
/** the post executed function (if installed) */
|
||||
void (*post_ex_fn)( void *, u32 adr, int thumb);
|
||||
|
||||
/** data for the post executed function */
|
||||
void *post_ex_fn_data;
|
||||
|
||||
/** flag indicating if the processor is stalled */
|
||||
int stalled;
|
||||
|
||||
/** the memory interface */
|
||||
struct armcpu_memory_iface *mem_if;
|
||||
|
||||
/** the ctrl interface */
|
||||
struct armcpu_ctrl_iface ctrl_iface;
|
||||
} armcpu_t;
|
||||
|
||||
int armcpu_new(armcpu_t *armcpu, u32 id);
|
||||
|
||||
|
||||
int armcpu_new( armcpu_t *armcpu, u32 id, struct armcpu_memory_iface *mem_if,
|
||||
struct armcpu_ctrl_iface **ctrl_iface_ret);
|
||||
void armcpu_init(armcpu_t *armcpu, u32 adr);
|
||||
u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode);
|
||||
u32 armcpu_prefetch(armcpu_t *armcpu);
|
||||
//u32 armcpu_prefetch(armcpu_t *armcpu);
|
||||
u32 armcpu_exec(armcpu_t *armcpu);
|
||||
BOOL armcpu_irqExeption(armcpu_t *armcpu);
|
||||
BOOL armcpu_prefetchExeption(armcpu_t *armcpu);
|
||||
//BOOL armcpu_irqExeption(armcpu_t *armcpu);
|
||||
//BOOL armcpu_prefetchExeption(armcpu_t *armcpu);
|
||||
BOOL
|
||||
armcpu_flagIrq( armcpu_t *armcpu);
|
||||
|
||||
extern armcpu_t NDS_ARM7;
|
||||
extern armcpu_t NDS_ARM9;
|
||||
|
|
|
@ -538,7 +538,7 @@ static u32 FASTCALL OP_LDR_PCREL(armcpu_t *cpu)
|
|||
{
|
||||
u32 adr = (cpu->R[15]&0xFFFFFFFC) + ((cpu->instruction&0xFF)<<2);
|
||||
|
||||
cpu->R[REG_NUM(cpu->instruction, 8)] = MMU_readWord(cpu->proc_ID, adr);
|
||||
cpu->R[REG_NUM(cpu->instruction, 8)] = cpu->mem_if->read32(cpu->mem_if->data, adr);
|
||||
|
||||
return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ static u32 FASTCALL OP_STR_REG_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)];
|
||||
MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_NUM(i, 0)]);
|
||||
cpu->mem_if->write32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
|
||||
|
||||
return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -556,7 +556,7 @@ static u32 FASTCALL OP_STRH_REG_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
||||
MMU_writeHWord(cpu->proc_ID, adr, ((u16)cpu->R[REG_NUM(i, 0)]));
|
||||
cpu->mem_if->write16(cpu->mem_if->data, adr, ((u16)cpu->R[REG_NUM(i, 0)]));
|
||||
|
||||
return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -565,7 +565,7 @@ static u32 FASTCALL OP_STRB_REG_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
||||
MMU_writeByte(cpu->proc_ID, adr, ((u8)cpu->R[REG_NUM(i, 0)]));
|
||||
cpu->mem_if->write8(cpu->mem_if->data, adr, ((u8)cpu->R[REG_NUM(i, 0)]));
|
||||
|
||||
return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -574,7 +574,7 @@ static u32 FASTCALL OP_LDRSB_REG_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
||||
cpu->R[REG_NUM(i, 0)] = (s32)((s8)MMU_readByte(cpu->proc_ID, adr));
|
||||
cpu->R[REG_NUM(i, 0)] = (s32)((s8)cpu->mem_if->read8(cpu->mem_if->data, adr));
|
||||
|
||||
return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -583,7 +583,7 @@ static u32 FASTCALL OP_LDR_REG_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = (cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]);
|
||||
u32 tempValue = MMU_readWord(cpu->proc_ID, adr&0xFFFFFFFC);
|
||||
u32 tempValue = cpu->mem_if->read32(cpu->mem_if->data, adr&0xFFFFFFFC);
|
||||
|
||||
adr = (adr&3)*8;
|
||||
tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
|
||||
|
@ -596,7 +596,7 @@ static u32 FASTCALL OP_LDRH_REG_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
||||
cpu->R[REG_NUM(i, 0)] = (u32)MMU_readHWord(cpu->proc_ID, adr);
|
||||
cpu->R[REG_NUM(i, 0)] = (u32)cpu->mem_if->read16(cpu->mem_if->data, adr);
|
||||
|
||||
return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -605,7 +605,7 @@ static u32 FASTCALL OP_LDRB_REG_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
||||
cpu->R[REG_NUM(i, 0)] = (u32)MMU_readByte(cpu->proc_ID, adr);
|
||||
cpu->R[REG_NUM(i, 0)] = (u32)cpu->mem_if->read8(cpu->mem_if->data, adr);
|
||||
|
||||
return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -614,7 +614,7 @@ static u32 FASTCALL OP_LDRSH_REG_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
||||
cpu->R[REG_NUM(i, 0)] = (s32)((s16)MMU_readHWord(cpu->proc_ID, adr));
|
||||
cpu->R[REG_NUM(i, 0)] = (s32)((s16)cpu->mem_if->read16(cpu->mem_if->data, adr));
|
||||
|
||||
return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -623,7 +623,7 @@ static u32 FASTCALL OP_STR_IMM_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
|
||||
MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_NUM(i, 0)]);
|
||||
cpu->mem_if->write32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
|
||||
|
||||
return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -632,7 +632,7 @@ static u32 FASTCALL OP_LDR_IMM_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
|
||||
u32 tempValue = MMU_readWord(cpu->proc_ID, adr&0xFFFFFFFC);
|
||||
u32 tempValue = cpu->mem_if->read32(cpu->mem_if->data, adr&0xFFFFFFFC);
|
||||
adr = (adr&3)*8;
|
||||
tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
|
||||
cpu->R[REG_NUM(i, 0)] = tempValue;
|
||||
|
@ -644,7 +644,7 @@ static u32 FASTCALL OP_STRB_IMM_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
|
||||
MMU_writeByte(cpu->proc_ID, adr, (u8)cpu->R[REG_NUM(i, 0)]);
|
||||
cpu->mem_if->write8(cpu->mem_if->data, adr, (u8)cpu->R[REG_NUM(i, 0)]);
|
||||
|
||||
return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -653,7 +653,7 @@ static u32 FASTCALL OP_LDRB_IMM_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
|
||||
cpu->R[REG_NUM(i, 0)] = MMU_readByte(cpu->proc_ID, adr);
|
||||
cpu->R[REG_NUM(i, 0)] = cpu->mem_if->read8(cpu->mem_if->data, adr);
|
||||
|
||||
return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -662,7 +662,7 @@ static u32 FASTCALL OP_STRH_IMM_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
|
||||
MMU_writeHWord(cpu->proc_ID, adr, (u16)cpu->R[REG_NUM(i, 0)]);
|
||||
cpu->mem_if->write16(cpu->mem_if->data, adr, (u16)cpu->R[REG_NUM(i, 0)]);
|
||||
|
||||
return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -671,7 +671,7 @@ static u32 FASTCALL OP_LDRH_IMM_OFF(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
|
||||
cpu->R[REG_NUM(i, 0)] = MMU_readHWord(cpu->proc_ID, adr);
|
||||
cpu->R[REG_NUM(i, 0)] = cpu->mem_if->read16(cpu->mem_if->data, adr);
|
||||
|
||||
return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -680,7 +680,7 @@ static u32 FASTCALL OP_STR_SPREL(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[13] + ((i&0xFF)<<2);
|
||||
MMU_writeWord(cpu->proc_ID, adr, cpu->R[REG_NUM(i, 8)]);
|
||||
cpu->mem_if->write32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 8)]);
|
||||
|
||||
return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -689,7 +689,7 @@ static u32 FASTCALL OP_LDR_SPREL(armcpu_t *cpu)
|
|||
{
|
||||
u32 i = cpu->instruction;
|
||||
u32 adr = cpu->R[13] + ((i&0xFF)<<2);
|
||||
cpu->R[REG_NUM(i, 8)] = MMU_readWord(cpu->proc_ID, adr);
|
||||
cpu->R[REG_NUM(i, 8)] = cpu->mem_if->read32(cpu->mem_if->data, adr);
|
||||
|
||||
return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
}
|
||||
|
@ -733,7 +733,7 @@ static u32 FASTCALL OP_PUSH(armcpu_t *cpu)
|
|||
for(j = 0; j<8; ++j)
|
||||
if(BIT_N(i, 7-j))
|
||||
{
|
||||
MMU_writeWord(cpu->proc_ID, adr, cpu->R[7-j]);
|
||||
cpu->mem_if->write32(cpu->mem_if->data, adr, cpu->R[7-j]);
|
||||
c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
adr -= 4;
|
||||
}
|
||||
|
@ -748,14 +748,14 @@ static u32 FASTCALL OP_PUSH_LR(armcpu_t *cpu)
|
|||
u32 adr = cpu->R[13] - 4;
|
||||
u32 c = 0, j;
|
||||
|
||||
MMU_writeWord(cpu->proc_ID, adr, cpu->R[14]);
|
||||
cpu->mem_if->write32(cpu->mem_if->data, adr, cpu->R[14]);
|
||||
c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
adr -= 4;
|
||||
|
||||
for(j = 0; j<8; ++j)
|
||||
if(BIT_N(i, 7-j))
|
||||
{
|
||||
MMU_writeWord(cpu->proc_ID, adr, cpu->R[7-j]);
|
||||
cpu->mem_if->write32(cpu->mem_if->data, adr, cpu->R[7-j]);
|
||||
c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
adr -= 4;
|
||||
}
|
||||
|
@ -773,7 +773,7 @@ static u32 FASTCALL OP_POP(armcpu_t *cpu)
|
|||
for(j = 0; j<8; ++j)
|
||||
if(BIT_N(i, j))
|
||||
{
|
||||
cpu->R[j] = MMU_readWord(cpu->proc_ID, adr);
|
||||
cpu->R[j] = cpu->mem_if->read32(cpu->mem_if->data, adr);
|
||||
c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
adr += 4;
|
||||
}
|
||||
|
@ -792,12 +792,12 @@ static u32 FASTCALL OP_POP_PC(armcpu_t *cpu)
|
|||
for(j = 0; j<8; ++j)
|
||||
if(BIT_N(i, j))
|
||||
{
|
||||
cpu->R[j] = MMU_readWord(cpu->proc_ID, adr);
|
||||
cpu->R[j] = cpu->mem_if->read32(cpu->mem_if->data, adr);
|
||||
c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
adr += 4;
|
||||
}
|
||||
|
||||
v = MMU_readWord(cpu->proc_ID, adr);
|
||||
v = cpu->mem_if->read32(cpu->mem_if->data, adr);
|
||||
c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
cpu->R[15] = v & 0xFFFFFFFE;
|
||||
cpu->next_instruction = v & 0xFFFFFFFE;
|
||||
|
@ -823,7 +823,7 @@ static u32 FASTCALL OP_STMIA_THUMB(armcpu_t *cpu)
|
|||
for(j = 0; j<8; ++j)
|
||||
if(BIT_N(i, j))
|
||||
{
|
||||
MMU_writeWord(cpu->proc_ID, adr, cpu->R[j]);
|
||||
cpu->mem_if->write32(cpu->mem_if->data, adr, cpu->R[j]);
|
||||
c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
adr += 4;
|
||||
}
|
||||
|
@ -840,7 +840,7 @@ static u32 FASTCALL OP_LDMIA_THUMB(armcpu_t *cpu)
|
|||
for(j = 0; j<8; ++j)
|
||||
if(BIT_N(i, j))
|
||||
{
|
||||
cpu->R[j] = MMU_readWord(cpu->proc_ID, adr);
|
||||
cpu->R[j] = cpu->mem_if->read32(cpu->mem_if->data, adr);
|
||||
c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
||||
adr += 4;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue