MMU: reorganize gamecard emulation so it's easier to implement commands.
NDS: when booting from firmware, copy secure area to main memory (this is done by the BIOS, not the firmware). This allows the firmware to boot games! :)
This commit is contained in:
parent
ef6717c210
commit
c48ef684f6
|
@ -1064,6 +1064,188 @@ static void execdiv() {
|
|||
NDS_Reschedule();
|
||||
}
|
||||
|
||||
template<int PROCNUM>
|
||||
void FASTCALL MMU_writeToGCControl(u32 val)
|
||||
{
|
||||
if(!(val & 0x80000000))
|
||||
{
|
||||
MMU.dscard[PROCNUM].address = 0;
|
||||
MMU.dscard[PROCNUM].transfer_count = 0;
|
||||
|
||||
val &= 0x7F7FFFFF;
|
||||
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT))
|
||||
{
|
||||
/* Dummy */
|
||||
case 0x9F:
|
||||
{
|
||||
MMU.dscard[PROCNUM].address = 0;
|
||||
MMU.dscard[PROCNUM].transfer_count = 0x800;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Nand Init */
|
||||
case 0x94:
|
||||
{
|
||||
MMU.dscard[PROCNUM].address = 0;
|
||||
MMU.dscard[PROCNUM].transfer_count = 0x80;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Nand Error? */
|
||||
case 0xD6:
|
||||
{
|
||||
MMU.dscard[PROCNUM].address = 0;
|
||||
MMU.dscard[PROCNUM].transfer_count = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Data read */
|
||||
case 0x00:
|
||||
case 0xB7:
|
||||
{
|
||||
MMU.dscard[PROCNUM].address = (MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+1) << 24) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+2) << 16) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+3) << 8) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+4));
|
||||
MMU.dscard[PROCNUM].transfer_count = 0x80;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Get ROM chip ID */
|
||||
case 0x90:
|
||||
case 0xB8:
|
||||
{
|
||||
MMU.dscard[PROCNUM].address = 0;
|
||||
MMU.dscard[PROCNUM].transfer_count = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
LOG("WRITE CARD command: %08X %08X\t",
|
||||
((MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT) << 24) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+1) << 16) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+2) << 8) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+3))),
|
||||
((MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+4) << 24) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+5) << 16) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+6) << 8) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+7))));
|
||||
LOG("FROM: %08X\n", (PROCNUM ? NDS_ARM7:NDS_ARM9).instruct_adr);
|
||||
|
||||
MMU.dscard[PROCNUM].address = 0;
|
||||
MMU.dscard[PROCNUM].transfer_count = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(MMU.dscard[PROCNUM].transfer_count == 0)
|
||||
{
|
||||
val &= 0x7F7FFFFF;
|
||||
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
|
||||
return;
|
||||
}
|
||||
|
||||
val |= 0x00800000;
|
||||
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
|
||||
|
||||
//launch DMA if start flag was set to "DS Cart"
|
||||
if(MMU.DMAStartTime[PROCNUM][0] == EDMAMode_Card) MMU_doDMA<PROCNUM>(0);
|
||||
if(MMU.DMAStartTime[PROCNUM][1] == EDMAMode_Card) MMU_doDMA<PROCNUM>(1);
|
||||
if(MMU.DMAStartTime[PROCNUM][2] == EDMAMode_Card) MMU_doDMA<PROCNUM>(2);
|
||||
if(MMU.DMAStartTime[PROCNUM][3] == EDMAMode_Card) MMU_doDMA<PROCNUM>(3);
|
||||
}
|
||||
|
||||
template<int PROCNUM>
|
||||
u32 MMU_readFromGC()
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
if(MMU.dscard[PROCNUM].transfer_count == 0)
|
||||
return 0;
|
||||
|
||||
switch(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT))
|
||||
{
|
||||
/* Dummy */
|
||||
case 0x9F:
|
||||
{
|
||||
val = 0xFFFFFFFF;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Nand Init? */
|
||||
case 0x94:
|
||||
{
|
||||
val = 0; //Unsure what to return here so return 0 for now
|
||||
}
|
||||
break;
|
||||
|
||||
/* Nand Error? */
|
||||
case 0xD6:
|
||||
{
|
||||
val = 0x80; //0x80 == ok?
|
||||
}
|
||||
break;
|
||||
|
||||
/* Data read */
|
||||
case 0x00:
|
||||
case 0xB7:
|
||||
{
|
||||
/* TODO: prevent read if the address is out of range */
|
||||
/* Make sure any reads below 0x8000 redirect to 0x8000+(adr&0x1FF) as on real cart */
|
||||
if((MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT) == 0xB7) && (MMU.dscard[PROCNUM].address < 0x8000))
|
||||
{
|
||||
MMU.dscard[PROCNUM].address = (0x8000 + (MMU.dscard[PROCNUM].address&0x1FF));
|
||||
INFO("Read below 0x8000 from: %08X\n", NDS_ARM9.instruct_adr);
|
||||
}
|
||||
val = T1ReadLong(MMU.CART_ROM, MMU.dscard[PROCNUM].address & MMU.CART_ROM_MASK);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Get ROM chip ID */
|
||||
case 0x90:
|
||||
case 0xB8:
|
||||
{
|
||||
/* TODO */
|
||||
val = 0x00000000;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG("READ CARD command: %08X %08X\t",
|
||||
((MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT) << 24) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+1) << 16) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+2) << 8) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+3))),
|
||||
((MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+4) << 24) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+5) << 16) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+6) << 8) |
|
||||
(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT+7))));
|
||||
LOG("FROM: %08X\n", (PROCNUM ? NDS_ARM7:NDS_ARM9).instruct_adr);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
MMU.dscard[PROCNUM].address += 4; // increment address
|
||||
|
||||
MMU.dscard[PROCNUM].transfer_count--; // update transfer counter
|
||||
if(MMU.dscard[PROCNUM].transfer_count) // if transfer is not ended
|
||||
return val; // return data
|
||||
|
||||
// transfer is done
|
||||
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4,
|
||||
T1ReadLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4) & 0x7F7FFFFF);
|
||||
|
||||
// if needed, throw irq for the end of transfer
|
||||
if(MMU.AUX_SPI_CNT & 0x4000)
|
||||
NDS_makeInt(PROCNUM, 19);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
template<int PROCNUM>
|
||||
void FASTCALL MMU_doDMA(u32 num)
|
||||
{
|
||||
|
@ -2426,88 +2608,8 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xDC, val); //write the low word
|
||||
write_dma_hictrl<ARMCPU_ARM9>(3,val>>16);
|
||||
return;
|
||||
case REG_GCROMCTRL :
|
||||
{
|
||||
if(!(val & 0x80000000))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* Nand Init */
|
||||
case 0x94:
|
||||
{
|
||||
MMU.dscard[ARMCPU_ARM9].address = 0;
|
||||
MMU.dscard[ARMCPU_ARM9].transfer_count = 0x80;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Nand Error? */
|
||||
case 0xD6:
|
||||
{
|
||||
MMU.dscard[ARMCPU_ARM9].address = 0;
|
||||
MMU.dscard[ARMCPU_ARM9].transfer_count = 1;
|
||||
}
|
||||
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("WRITE CARD command: %08X %08X\t", ((MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT) << 24) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+1) << 16) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+2) << 8) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+3))),((MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+4) << 24) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+5) << 16) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+6) << 8) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+7))));
|
||||
LOG("FROM: %08X\n", NDS_ARM9.instruct_adr);
|
||||
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] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM9>(0);
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM9][1] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM9>(1);
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM9][2] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM9>(2);
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM9][3] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM9>(3);
|
||||
}
|
||||
case REG_GCROMCTRL :
|
||||
MMU_writeToGCControl<ARMCPU_ARM9>(val);
|
||||
return;
|
||||
case REG_DISPA_DISPCAPCNT :
|
||||
//INFO("MMU write32: REG_DISPA_DISPCAPCNT 0x%X\n", val);
|
||||
|
@ -2738,80 +2840,7 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr)
|
|||
return 0;
|
||||
*/
|
||||
case REG_GCDATAIN:
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
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;
|
||||
|
||||
/* Nand Init? */
|
||||
case 0x94:
|
||||
{
|
||||
val = 0; //Unsure what to return here so return 0 for now
|
||||
}
|
||||
break;
|
||||
/* Nand Error? */
|
||||
case 0xD6:
|
||||
{
|
||||
val = 0x80; //0x80 == ok?
|
||||
}
|
||||
break;
|
||||
|
||||
/* Data read */
|
||||
case 0x00:
|
||||
case 0xB7:
|
||||
{
|
||||
/* TODO: prevent read if the address is out of range */
|
||||
/* Make sure any reads below 0x8000 redirect to 0x8000+(adr&0x1FF) as on real cart */
|
||||
if((MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT) == 0xB7) && (MMU.dscard[ARMCPU_ARM9].address < 0x8000))
|
||||
{
|
||||
MMU.dscard[ARMCPU_ARM9].address = (0x8000 + (MMU.dscard[ARMCPU_ARM9].address&0x1FF));
|
||||
INFO("Read below 0x8000 from: %08X\n", NDS_ARM9.instruct_adr);
|
||||
}
|
||||
val = T1ReadLong(MMU.CART_ROM, MMU.dscard[ARMCPU_ARM9].address & MMU.CART_ROM_MASK);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Get ROM chip ID */
|
||||
case 0x90:
|
||||
case 0xB8:
|
||||
{
|
||||
/* TODO */
|
||||
val = 0x00000000;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG("READ CARD command: %08X %08X\t", ((MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT) << 24) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+1) << 16) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+2) << 8) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+3))),((MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+4) << 24) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+5) << 16) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+6) << 8) | (MEM_8(MMU.MMU_MEM[ARMCPU_ARM9], REG_GCCMDOUT+7))));
|
||||
LOG("FROM: %08X\n", NDS_ARM9.instruct_adr);
|
||||
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][0x40], 0x1A4,
|
||||
T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4) & 0x7F7FFFFF);
|
||||
|
||||
// if needed, throw irq for the end of transfer
|
||||
if(MMU.AUX_SPI_CNT & 0x4000)
|
||||
NDS_makeInt(ARMCPU_ARM9, 19);
|
||||
|
||||
return val;
|
||||
}
|
||||
return MMU_readFromGC<ARMCPU_ARM9>();
|
||||
}
|
||||
return T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20)]);
|
||||
}
|
||||
|
@ -3326,73 +3355,7 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
|||
return;
|
||||
|
||||
case REG_GCROMCTRL :
|
||||
{
|
||||
if(!(val & 0x80000000))
|
||||
{
|
||||
MMU.dscard[ARMCPU_ARM7].address = 0;
|
||||
MMU.dscard[ARMCPU_ARM7].transfer_count = 0;
|
||||
|
||||
val &= 0x7F7FFFFF;
|
||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4, val);
|
||||
return;
|
||||
}
|
||||
|
||||
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][0] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(0);
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM7][1] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(1);
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM7][2] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(2);
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM7][3] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(3);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
MMU_writeToGCControl<ARMCPU_ARM7>(val);
|
||||
return;
|
||||
}
|
||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
|
||||
|
@ -3546,61 +3509,7 @@ u32 FASTCALL _MMU_ARM7_read32(u32 adr)
|
|||
break;
|
||||
}
|
||||
case REG_GCDATAIN:
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
if(MMU.dscard[ARMCPU_ARM7].transfer_count == 0)
|
||||
return 0;
|
||||
|
||||
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 */
|
||||
/* Make sure any reads below 0x8000 redirect to 0x8000+(adr&0x1FF) as on real cart */
|
||||
if((MEM_8(MMU.MMU_MEM[ARMCPU_ARM7], REG_GCCMDOUT) == 0xB7) && (MMU.dscard[ARMCPU_ARM7].address < 0x8000))
|
||||
{
|
||||
MMU.dscard[ARMCPU_ARM7].address = (0x8000 + (MMU.dscard[ARMCPU_ARM7].address&0x1FF));
|
||||
}
|
||||
val = T1ReadLong(MMU.CART_ROM, MMU.dscard[ARMCPU_ARM7].address & MMU.CART_ROM_MASK);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Get ROM chip ID */
|
||||
case 0x90:
|
||||
case 0xB8:
|
||||
{
|
||||
/* TODO */
|
||||
val = 0x00000FC2;
|
||||
}
|
||||
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);
|
||||
|
||||
// if needed, throw irq for the end of transfer
|
||||
if(MMU.AUX_SPI_CNT & 0x4000)
|
||||
NDS_makeInt(ARMCPU_ARM7, 19);
|
||||
|
||||
return val;
|
||||
}
|
||||
return MMU_readFromGC<ARMCPU_ARM7>();
|
||||
}
|
||||
return T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][(adr >> 20)], adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr >> 20)]);
|
||||
}
|
||||
|
@ -3647,6 +3556,7 @@ u8 FASTCALL MMU_read8(u32 proc, u32 adr)
|
|||
void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val)
|
||||
{
|
||||
ASSERT_UNALIGNED((adr&3)==0);
|
||||
|
||||
if(proc==0)
|
||||
_MMU_ARM9_write32(adr, val);
|
||||
else
|
||||
|
@ -3656,6 +3566,7 @@ void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val)
|
|||
void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
|
||||
{
|
||||
ASSERT_UNALIGNED((adr&1)==0);
|
||||
|
||||
if(proc==0)
|
||||
_MMU_ARM9_write16(adr, val);
|
||||
else
|
||||
|
|
|
@ -58,9 +58,11 @@ PathInfo path;
|
|||
// zeromus: which games are these? I would like to see what happens.
|
||||
// this is a substantial framerate hit. we should consider an emulation option
|
||||
// to indicate whether this whole system should be enabled
|
||||
#if 1
|
||||
#ifndef PUBLIC_RELEASE
|
||||
#undef EXPERIMENTAL_WIFI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TCommonSettings CommonSettings;
|
||||
static BaseDriver _stub_driver;
|
||||
|
@ -2342,27 +2344,40 @@ void NDS_Reset()
|
|||
_MMU_write32<ARMCPU_ARM9>(0xFFFF0040, 0xE25EF004);
|
||||
}
|
||||
|
||||
/* Is it really needed ??? */
|
||||
_MMU_write32<ARMCPU_ARM9>(0x0000004, 0xE3A0010E);
|
||||
_MMU_write32<ARMCPU_ARM9>(0x0000008, 0xE3A01020);
|
||||
// _MMU_write32<ARMCPU_ARM9>(0x000000C, 0xE1B02110);
|
||||
_MMU_write32<ARMCPU_ARM9>(0x000000C, 0xE1B02040);
|
||||
_MMU_write32<ARMCPU_ARM9>(0x0000010, 0xE3B02020);
|
||||
// _MMU_write32<ARMCPU_ARM9>(0x0000010, 0xE2100202);
|
||||
|
||||
if(CommonSettings.UseExtFirmware == true)
|
||||
NDS_LoadFirmware(CommonSettings.Firmware);
|
||||
|
||||
if((CommonSettings.UseExtBIOS == true) && (CommonSettings.UseExtFirmware == true) && (CommonSettings.BootFromFirmware == true) && (fw_success == TRUE))
|
||||
{
|
||||
for(u32 i = 0; i < nds.FW_ARM9BootCodeSize; i += 4)
|
||||
// Copy firmware boot codes to their respective locations
|
||||
|
||||
src = 0;
|
||||
dst = nds.FW_ARM9BootCodeAddr;
|
||||
for(u32 i = 0; i < (nds.FW_ARM9BootCodeSize >> 2); i++)
|
||||
{
|
||||
_MMU_write32<ARMCPU_ARM9>((nds.FW_ARM9BootCodeAddr + i), T1ReadLong(nds.FW_ARM9BootCode, i));
|
||||
_MMU_write32<ARMCPU_ARM9>(dst, T1ReadLong(nds.FW_ARM9BootCode, src));
|
||||
src += 4; dst += 4;
|
||||
}
|
||||
|
||||
for(u32 i = 0; i < nds.FW_ARM7BootCodeSize; i += 4)
|
||||
src = 0;
|
||||
dst = nds.FW_ARM7BootCodeAddr;
|
||||
for(u32 i = 0; i < (nds.FW_ARM7BootCodeSize >> 2); i++)
|
||||
{
|
||||
_MMU_write32<ARMCPU_ARM7>((nds.FW_ARM7BootCodeAddr + i), T1ReadLong(nds.FW_ARM7BootCode, i));
|
||||
_MMU_write32<ARMCPU_ARM7>(dst, T1ReadLong(nds.FW_ARM7BootCode, src));
|
||||
src += 4; dst += 4;
|
||||
}
|
||||
|
||||
// Copy secure area to memory if needed
|
||||
if ((header->ARM9src >= 0x4000) && (header->ARM9src < 0x8000))
|
||||
{
|
||||
src = header->ARM9src;
|
||||
dst = header->ARM9cpy;
|
||||
u32 size = (0x8000 - src) >> 2;
|
||||
for (u32 i = 0; i < size; i++)
|
||||
{
|
||||
_MMU_write32<ARMCPU_ARM9>(dst, T1ReadLong(MMU.CART_ROM, src));
|
||||
src += 4; dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
armcpu_init(&NDS_ARM9, nds.FW_ARM9BootCodeAddr);
|
||||
|
@ -2679,6 +2694,7 @@ void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,b
|
|||
|
||||
|
||||
void emu_halt() {
|
||||
printf("halting emu: ARM9 PC=%08X/%08X, ARM7 PC=%08X/%08X\n", NDS_ARM9.R[15], NDS_ARM9.instruct_adr, NDS_ARM7.R[15], NDS_ARM7.instruct_adr);
|
||||
execute = false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue