From 159f323068d384a3d1f94f3038025a9db658f97e Mon Sep 17 00:00:00 2001 From: luigi__ Date: Sun, 15 Mar 2009 13:43:07 +0000 Subject: [PATCH] Cartridge emulation entirely remade as I was trying to get the BIOS running. But I can't get the BIOS running. The Nintendo logo checksum in the cart header is copied to 0x027FF808, allowing the firmware to detect the cart. But unfortunately you can't boot from it. --- desmume/src/MMU.cpp | 274 +++++++++++++++++++++++++++----------- desmume/src/NDSSystem.cpp | 8 +- desmume/src/armcpu.cpp | 5 +- 3 files changed, 203 insertions(+), 84 deletions(-) diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index c92126598..80e54c02f 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -2748,54 +2748,79 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; case REG_GCROMCTRL : { - if(MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT) == 0xB7) + if(!(val & 0x80000000)) { - MMU.dscard[ARMCPU_ARM9].address = (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+1) << 24) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+2) << 16) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+3) << 8) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+4)); - MMU.dscard[ARMCPU_ARM9].transfer_count = 0x80;// * ((val>>24)&7)); - } - else if (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT) == 0xB8) - { - // Get ROM chip ID - val |= 0x800000; // Data-Word Status - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val); - MMU.dscard[ARMCPU_ARM9].address = 0; - } - else - { - LOG("CARD command: %02X\n", MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT)); - } - - //CARDLOG("%08X : %08X %08X\r\n", adr, val, adresse[ARMCPU_ARM9]); - val |= 0x00800000; - - if(MMU.dscard[ARMCPU_ARM9].address == 0) - { - val &= ~0x80000000; - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val); + MMU.dscard[ARMCPU_ARM9].address = 0; + MMU.dscard[ARMCPU_ARM9].transfer_count = 0; + + val &= 0x7F7FFFFF; + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4, val); return; } - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val); + + switch(MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT)) + { + /* Dummy */ + case 0x9F: + { + MMU.dscard[ARMCPU_ARM9].address = 0; + MMU.dscard[ARMCPU_ARM9].transfer_count = 0x800; + } + break; + + /* Data read */ + case 0x00: + case 0xB7: + { + MMU.dscard[ARMCPU_ARM9].address = (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+1) << 24) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+2) << 16) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+3) << 8) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+4)); + MMU.dscard[ARMCPU_ARM9].transfer_count = 0x80; + } + break; + + /* Get ROM chip ID */ + case 0x90: + case 0xB8: + { + MMU.dscard[ARMCPU_ARM9].address = 0; + MMU.dscard[ARMCPU_ARM9].transfer_count = 1; + } + break; + + default: + { + LOG("CARD command: %02X\n", MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT)); + MMU.dscard[ARMCPU_ARM9].address = 0; + MMU.dscard[ARMCPU_ARM9].transfer_count = 0; + } + break; + } + + if(MMU.dscard[ARMCPU_ARM9].transfer_count == 0) + { + val &= 0x7F7FFFFF; + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4, val); + return; + } + + val |= 0x00800000; + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4, val); /* launch DMA if start flag was set to "DS Cart" */ if(MMU.DMAStartTime[ARMCPU_ARM9][0] == 5) { MMU_doDMA(0); - return; } if(MMU.DMAStartTime[ARMCPU_ARM9][1] == 5) { MMU_doDMA(1); - return; } if(MMU.DMAStartTime[ARMCPU_ARM9][2] == 5) { MMU_doDMA(2); - return; } if(MMU.DMAStartTime[ARMCPU_ARM9][3] == 5) { MMU_doDMA(3); - return; } } return; @@ -2851,7 +2876,9 @@ u8 FASTCALL _MMU_ARM9_read08(u32 adr) { #ifdef INTERNAL_DTCM_READ if((adr&(~0x3FFF)) == MMU.DTCMRegion) + { return T1ReadByte(ARM9Mem.ARM9_DTCM, adr&0x3FFF); + } #endif if(adr<0x02000000) @@ -2880,7 +2907,9 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr) { #ifdef INTERNAL_DTCM_READ if((adr&(~0x3FFF)) == MMU.DTCMRegion) + { return T1ReadWord(ARM9Mem.ARM9_DTCM, adr & 0x3FFF); + } #endif if(adr<0x02000000) @@ -3076,25 +3105,52 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr) */ case REG_GCDATAIN: { - u32 val=0; + u32 val = 0; - if(MMU.dscard[ARMCPU_ARM9].address) - val = T1ReadLong(MMU.CART_ROM, MMU.dscard[ARMCPU_ARM9].address); + if(MMU.dscard[ARMCPU_ARM9].transfer_count == 0) + return 0; + + switch(MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT)) + { + /* Dummy */ + case 0x9F: + { + val = 0xFFFFFFFF; + } + break; + + /* Data read */ + case 0x00: + case 0xB7: + { + /* TODO: prevent read if the address is out of range */ + val = T1ReadLong(MMU.CART_ROM, MMU.dscard[ARMCPU_ARM9].address); + } + break; + + /* Get ROM chip ID */ + case 0x90: + case 0xB8: + { + /* TODO */ + val = 0x00000000; + } + break; + } MMU.dscard[ARMCPU_ARM9].address += 4; // increment address MMU.dscard[ARMCPU_ARM9].transfer_count--; // update transfer counter if(MMU.dscard[ARMCPU_ARM9].transfer_count) // if transfer is not ended return val; // return data + // transfer is done - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][(REG_GCROMCTRL >> 20) & 0xff], - REG_GCROMCTRL & 0xfff, T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][(REG_GCROMCTRL >> 20) & 0xff], - REG_GCROMCTRL & 0xfff) & ~(0x00800000 | 0x80000000)); - // = 0x7f7fffff + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4, + T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0x7F7FFFFF); // if needed, throw irq for the end of transfer - if(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][(REG_AUXSPICNT >> 20) & 0xff], REG_AUXSPICNT & 0xfff) & 0x4000) - NDS_makeInt(ARMCPU_ARM9,19); + if(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A0) & 0x4000) + NDS_makeInt(ARMCPU_ARM9, 19); return val; } @@ -3792,48 +3848,74 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val) return; case REG_GCROMCTRL : { - if(MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT) == 0xB7) + if(!(val & 0x80000000)) { - MMU.dscard[ARMCPU_ARM7].address = (MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT+1) << 24) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT+2) << 16) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT+3) << 8) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT+4)); - MMU.dscard[ARMCPU_ARM7].transfer_count = 0x80;// * ((val>>24)&7)); - } - else - if (MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT) == 0xB8) - { - // Get ROM chip ID - val |= 0x800000; // Data-Word Status - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val); MMU.dscard[ARMCPU_ARM7].address = 0; - } - else - { - LOG("CARD command: %02X\n", MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT)); - } + MMU.dscard[ARMCPU_ARM7].transfer_count = 0; - //CARDLOG("%08X : %08X %08X\r\n", adr, val, adresse[ARMCPU_ARM7]); - val |= 0x00800000; - - if(MMU.dscard[ARMCPU_ARM7].address == 0) - { - val &= ~0x80000000; - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val); + val &= 0x7F7FFFFF; + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4, val); return; } - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val); + + switch(MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT)) + { + /* Dummy */ + case 0x9F: + { + MMU.dscard[ARMCPU_ARM7].address = 0; + MMU.dscard[ARMCPU_ARM7].transfer_count = 0x800; + } + break; + + /* Data read */ + case 0x00: + case 0xB7: + { + MMU.dscard[ARMCPU_ARM7].address = (MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT+1) << 24) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT+2) << 16) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT+3) << 8) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT+4)); + MMU.dscard[ARMCPU_ARM7].transfer_count = 0x80; + } + break; + + /* Get ROM chip ID */ + case 0x90: + case 0xB8: + { + MMU.dscard[ARMCPU_ARM7].address = 0; + MMU.dscard[ARMCPU_ARM7].transfer_count = 1; + } + break; + + default: + { + LOG("CARD command: %02X\n", MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT)); + MMU.dscard[ARMCPU_ARM7].address = 0; + MMU.dscard[ARMCPU_ARM7].transfer_count = 0; + } + break; + } + + if(MMU.dscard[ARMCPU_ARM7].transfer_count == 0) + { + val &= 0x7F7FFFFF; + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4, val); + return; + } + + val |= 0x00800000; + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4, val); /* launch DMA if start flag was set to "DS Cart" */ if(MMU.DMAStartTime[ARMCPU_ARM7][2] == 2) { MMU_doDMA(2); - return; } - else - if(MMU.DMAStartTime[ARMCPU_ARM7][3] == 2) + if(MMU.DMAStartTime[ARMCPU_ARM7][3] == 2) { MMU_doDMA(3); - return; } + return; } @@ -3986,27 +4068,61 @@ u32 FASTCALL _MMU_ARM7_read32(u32 adr) u32 val = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], (adr + 2) & 0xFFF); return MMU.timer[ARMCPU_ARM7][(adr&0xF)>>2] | (val<<16); } + case REG_GCROMCTRL: + { + //INFO("arm7 romctrl read\n"); + break; + } case REG_GCDATAIN: { - u32 val=0; + u32 val = 0; - if(MMU.dscard[ARMCPU_ARM7].address) - val = T1ReadLong(MMU.CART_ROM, MMU.dscard[ARMCPU_ARM7].address); + if(MMU.dscard[ARMCPU_ARM7].transfer_count == 0) + return 0; - MMU.dscard[ARMCPU_ARM7].address += 4; /* increment address */ + switch(MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT)) + { + /* Dummy */ + case 0x9F: + { + val = 0xFFFFFFFF; + } + break; + + /* Data read */ + case 0x00: + case 0xB7: + { + /* TODO: prevent read if the address is out of range */ + val = T1ReadLong(MMU.CART_ROM, MMU.dscard[ARMCPU_ARM7].address); + } + break; + + /* Get ROM chip ID */ + case 0x90: + case 0xB8: + { + /* TODO */ + val = 0x00000000; + } + break; + } + + MMU.dscard[ARMCPU_ARM7].address += 4; // increment address + + MMU.dscard[ARMCPU_ARM7].transfer_count--; // update transfer counter + if(MMU.dscard[ARMCPU_ARM7].transfer_count) // if transfer is not ended + return val; // return data + + // transfer is done + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4, + T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4) & 0x7F7FFFFF); - MMU.dscard[ARMCPU_ARM7].transfer_count--; /* update transfer counter */ - if(MMU.dscard[ARMCPU_ARM7].transfer_count) /* if transfer is not ended */ - return val; /* return data */ - /* transfer is done */ - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff) & ~(0x00800000 | 0x80000000)); - /* = 0x7f7fffff */ + // if needed, throw irq for the end of transfer + if(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A0) & 0x4000) + NDS_makeInt(ARMCPU_ARM7, 19); - /* if needed, throw irq for the end of transfer */ - if(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPICNT >> 20) & 0xff], REG_AUXSPICNT & 0xfff) & 0x4000) - NDS_makeInt(ARMCPU_ARM7,19); - - return val; + return val; } } #ifdef _MMU_DEBUG diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 39cb54f8b..f5a723ad9 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -918,12 +918,12 @@ void NDS_Reset( void) { for(i = 0; i < nds.FW_ARM9BootCodeSize; i += 4) { - _MMU_write32(0, (nds.FW_ARM9BootCodeAddr + i), T1ReadLong(nds.FW_ARM9BootCode, i)); + _MMU_write32((nds.FW_ARM9BootCodeAddr + i), T1ReadLong(nds.FW_ARM9BootCode, i)); } for(i = 0; i < nds.FW_ARM7BootCodeSize; i += 4) { - _MMU_write32(1, (nds.FW_ARM7BootCodeAddr + i), T1ReadLong(nds.FW_ARM7BootCode, i)); + _MMU_write32((nds.FW_ARM7BootCodeAddr + i), T1ReadLong(nds.FW_ARM7BootCode, i)); } armcpu_init(&NDS_ARM9, nds.FW_ARM9BootCodeAddr); @@ -996,6 +996,10 @@ void NDS_Reset( void) for (i = 0; i < ((0x170+0x90)/4); i++) { _MMU_write32(0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); } + + // Write the Nintendo logo checksum to memory (the firmware needs it to see the cart) + _MMU_write16(0x027FF808, T1ReadWord(MMU.CART_ROM, 0x15E)); + MainScreen.offset = 0; SubScreen.offset = 192; diff --git a/desmume/src/armcpu.cpp b/desmume/src/armcpu.cpp index 7cf7178a6..31db6a191 100644 --- a/desmume/src/armcpu.cpp +++ b/desmume/src/armcpu.cpp @@ -384,7 +384,7 @@ armcpu_prefetch() armcpu->R[15] = armcpu->next_instruction + 4; } #else - armcpu->instruction = MMU_read32_acl(PROCNUM, armcpu->next_instruction,CP15_ACCESS_EXECUTE); + armcpu->instruction = MMU_read32_acl(PROCNUM, armcpu->next_instruction&0xFFFFFFFC,CP15_ACCESS_EXECUTE); armcpu->instruct_adr = armcpu->next_instruction; armcpu->next_instruction += 4; @@ -406,7 +406,7 @@ armcpu_prefetch() armcpu->R[15] = armcpu->next_instruction + 2; } #else - armcpu->instruction = MMU_read16_acl(PROCNUM, armcpu->next_instruction,CP15_ACCESS_EXECUTE); + armcpu->instruction = MMU_read16_acl(PROCNUM, armcpu->next_instruction&0xFFFFFFFE,CP15_ACCESS_EXECUTE); armcpu->instruct_adr = armcpu->next_instruction; armcpu->next_instruction += 2; @@ -532,7 +532,6 @@ u32 armcpu_exec() } else c += arm_instructions_set_1[INSTRUCTION_INDEX(ARMPROC.instruction)](); - } #ifdef GDB_STUB if ( ARMPROC.post_ex_fn != NULL) {