Core: prepare gamecard system for future KEY1 and KEY2 encrypted command support.

Also rename MMU_clearMem to MMU_Reset because it's called upon reset and it
doesn't only clear memory.
This commit is contained in:
luigi__ 2009-08-02 20:55:38 +00:00
parent 64e0b8a2af
commit bf124165f7
4 changed files with 119 additions and 69 deletions

View File

@ -886,7 +886,7 @@ u32 rom_mask = 0;
u32 DMASrc[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
u32 DMADst[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
void MMU_clearMem()
void MMU_Reset()
{
memset(ARM9Mem.ARM9_DTCM, 0, sizeof(ARM9Mem.ARM9_DTCM));
memset(ARM9Mem.ARM9_ITCM, 0, sizeof(ARM9Mem.ARM9_ITCM));
@ -953,6 +953,16 @@ void MMU_clearMem()
addonsReset();
Mic_Reset();
MMU.gfx3dCycles = 0;
memset(MMU.dscard[ARMCPU_ARM9].command, 0, 8);
MMU.dscard[ARMCPU_ARM9].address = 0;
MMU.dscard[ARMCPU_ARM9].transfer_count = 0;
MMU.dscard[ARMCPU_ARM9].mode = CardMode_Normal;
memset(MMU.dscard[ARMCPU_ARM7].command, 0, 8);
MMU.dscard[ARMCPU_ARM7].address = 0;
MMU.dscard[ARMCPU_ARM7].transfer_count = 0;
MMU.dscard[ARMCPU_ARM7].mode = CardMode_Normal;
}
void MMU_setRom(u8 * rom, u32 mask)
@ -1068,83 +1078,107 @@ static void execdiv() {
template<int PROCNUM>
void FASTCALL MMU_writeToGCControl(u32 val)
{
nds_dscard& card = MMU.dscard[PROCNUM];
if(!(val & 0x80000000))
{
MMU.dscard[PROCNUM].address = 0;
MMU.dscard[PROCNUM].transfer_count = 0;
card.address = 0;
card.transfer_count = 0;
val &= 0x7F7FFFFF;
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
return;
}
switch(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT))
memcpy(&card.command[0], &MMU.MMU_MEM[PROCNUM][0x40][0x1A8], 8);
switch (card.mode)
{
/* Dummy */
case CardMode_Normal:
break;
case CardMode_KEY1:
{
// TODO
INFO("Cartridge: KEY1 mode unsupported.\n");
card.address = 0;
card.transfer_count = 0;
val &= 0x7F7FFFFF;
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
return;
}
break;
}
switch(card.command[0])
{
// Dummy
case 0x9F:
{
MMU.dscard[PROCNUM].address = 0;
MMU.dscard[PROCNUM].transfer_count = 0x800;
card.address = 0;
card.transfer_count = 0x800;
}
break;
/* Nand Init */
// Nand Init
case 0x94:
{
MMU.dscard[PROCNUM].address = 0;
MMU.dscard[PROCNUM].transfer_count = 0x80;
card.address = 0;
card.transfer_count = 0x80;
}
break;
/* Nand Error? */
// Nand Error?
case 0xD6:
{
MMU.dscard[PROCNUM].address = 0;
MMU.dscard[PROCNUM].transfer_count = 1;
card.address = 0;
card.transfer_count = 1;
}
break;
/* Data read */
// 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;
card.address = (card.command[1] << 24) | (card.command[2] << 16) | (card.command[3] << 8) | card.command[4];
card.transfer_count = 0x80;
}
break;
/* Get ROM chip ID */
// Get ROM chip ID
case 0x90:
case 0xB8:
{
MMU.dscard[PROCNUM].address = 0;
MMU.dscard[PROCNUM].transfer_count = 1;
card.address = 0;
card.transfer_count = 1;
}
break;
// Switch to KEY1 mode
case 0x3C:
{
card.address = 0;
card.transfer_count = 0;
card.mode = CardMode_KEY1;
}
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("WRITE CARD command: %02X%02X%02X%02X%02X%02X%02X%02X\t",
card.command[0], card.command[1], card.command[2], card.command[3],
card.command[4], card.command[5], card.command[6], card.command[7]);
LOG("FROM: %08X\n", (PROCNUM ? NDS_ARM7:NDS_ARM9).instruct_adr);
MMU.dscard[PROCNUM].address = 0;
MMU.dscard[PROCNUM].transfer_count = 0;
card.address = 0;
card.transfer_count = 0;
}
break;
}
if(MMU.dscard[PROCNUM].transfer_count == 0)
if(card.transfer_count == 0)
{
val &= 0x7F7FFFFF;
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
@ -1154,7 +1188,7 @@ void FASTCALL MMU_writeToGCControl(u32 val)
val |= 0x00800000;
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
//launch DMA if start flag was set to "DS Cart"
// 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);
@ -1164,76 +1198,87 @@ void FASTCALL MMU_writeToGCControl(u32 val)
template<int PROCNUM>
u32 MMU_readFromGC()
{
nds_dscard& card = MMU.dscard[PROCNUM];
u32 val = 0;
if(MMU.dscard[PROCNUM].transfer_count == 0)
if(card.transfer_count == 0)
return 0;
switch(MEM_8(MMU.MMU_MEM[PROCNUM], REG_GCCMDOUT))
switch(card.command[0])
{
/* Dummy */
// Dummy
case 0x9F:
{
val = 0xFFFFFFFF;
}
break;
/* Nand Init? */
// Nand Init?
case 0x94:
{
val = 0; //Unsure what to return here so return 0 for now
}
break;
/* Nand Error? */
// Nand Error?
case 0xD6:
{
val = 0x80; //0x80 == ok?
}
break;
/* Data read */
// 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))
// 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((card.command[0] == 0xB7) && (card.address < 0x8000))
{
MMU.dscard[PROCNUM].address = (0x8000 + (MMU.dscard[PROCNUM].address&0x1FF));
INFO("Read below 0x8000 from: %08X\n", NDS_ARM9.instruct_adr);
LOG("Read below 0x8000 (0x%04X) from: ARM%s %08X\n",
card.address, (PROCNUM ? "7":"9"), (PROCNUM ? NDS_ARM7:NDS_ARM9).instruct_adr);
card.address = (0x8000 + (card.address&0x1FF));
}
val = T1ReadLong(MMU.CART_ROM, MMU.dscard[PROCNUM].address & MMU.CART_ROM_MASK);
val = T1ReadLong(MMU.CART_ROM, card.address & MMU.CART_ROM_MASK);
}
break;
/* Get ROM chip ID */
// Get ROM chip ID
case 0x90:
case 0xB8:
{
/* TODO */
// Note: the BIOS stores the chip ID in main memory
// Most games continuously compare the chip ID with
// the value in memory, probably to know if the card
// was removed.
// As DeSmuME boots directly from the game, the chip
// ID in main mem is zero and this value needs to be
// zero too.
val = 0x00000000;
}
break;
// Switch to KEY1 mode
case 0x3C:
{
val = 0xFFFFFFFF;
}
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("READ CARD command: %02X%02X%02X%02X%02X%02X%02X%02X\t",
card.command[0], card.command[1], card.command[2], card.command[3],
card.command[4], card.command[5], card.command[6], card.command[7]);
LOG("FROM: %08X\n", (PROCNUM ? NDS_ARM7:NDS_ARM9).instruct_adr);
break;
}
MMU.dscard[PROCNUM].address += 4; // increment address
card.address += 4; // increment address
MMU.dscard[PROCNUM].transfer_count--; // update transfer counter
if(MMU.dscard[PROCNUM].transfer_count) // if transfer is not ended
card.transfer_count--; // update transfer counter
if(card.transfer_count) // if transfer is not ended
return val; // return data
// transfer is done

View File

@ -39,12 +39,6 @@
#define ARMPROC (PROCNUM?NDS_ARM7:NDS_ARM9)
#endif
/* theses macros are designed for reading/writing in memory (m is a pointer to memory, like MMU.MMU_MEM[proc], and a is an address, like 0x04000000 */
#define MEM_8(m, a) (((u8*)(m[((a)>>20)&0xff]))[((a)&0xfff)])
/* theses ones for reading in rom data */
#define ROM_8(m, a) (((u8*)(m))[(a)])
typedef const u8 TWaitState;
struct MMU_struct {
@ -168,7 +162,7 @@ struct armcpu_memory_iface {
void MMU_Init(void);
void MMU_DeInit(void);
void MMU_clearMem( void);
void MMU_Reset( void);
void MMU_setRom(u8 * rom, u32 mask);
void MMU_unsetRom( void);

View File

@ -2305,7 +2305,7 @@ void NDS_Reset()
TotalLagFrames = 0;
}
MMU_clearMem();
MMU_Reset();
MMU_new.backupDevice.reset();
//ARM7 BIOS IRQ HANDLER

View File

@ -20,11 +20,22 @@
#ifndef __DSCARD_H__
#define __DSCARD_H__
enum ECardMode
{
CardMode_Normal = 0,
CardMode_KEY1,
CardMode_KEY2,
};
typedef struct
{
u8 command[8];
u32 address;
u32 transfer_count;
ECardMode mode;
} nds_dscard;