- added part a new boot code (not finished yet and disabled by default).
entry point ARM CPUs set to xxxx0000h and now booting a firmware from BIOS as on a real DS.
all versions iQue and DS (patched with FlashME too) firmware works now, but can't run a games from firmware yet.
This commit is contained in:
mtabachenko 2013-07-26 01:31:58 +00:00
parent 06a70e4b0a
commit ef6daf9c10
12 changed files with 531 additions and 152 deletions

View File

@ -40,12 +40,22 @@
#include "readwrite.h" #include "readwrite.h"
#include "MMU_timing.h" #include "MMU_timing.h"
#ifdef _NEW_BOOT
#include "firmware.h"
#include "encrypt.h"
#endif
#ifdef DO_ASSERT_UNALIGNED #ifdef DO_ASSERT_UNALIGNED
#define ASSERT_UNALIGNED(x) assert(x) #define ASSERT_UNALIGNED(x) assert(x)
#else #else
#define ASSERT_UNALIGNED(x) #define ASSERT_UNALIGNED(x)
#endif #endif
#ifdef _NEW_BOOT
_KEY1 key1(&MMU.ARM7_BIOS[0x0030]);
_KEY2 key2;
#endif
//http://home.utah.edu/~nahaj/factoring/isqrt.c.html //http://home.utah.edu/~nahaj/factoring/isqrt.c.html
static u64 isqrt (u64 x) { static u64 isqrt (u64 x) {
u64 squaredbit, remainder, root; u64 squaredbit, remainder, root;
@ -1000,6 +1010,10 @@ void MMU_Reset()
MMU.SPI_CNT = 0; MMU.SPI_CNT = 0;
MMU.AUX_SPI_CNT = 0; MMU.AUX_SPI_CNT = 0;
#ifdef _NEW_BOOT
reconstruct(&key2);
#endif
MMU.WRAMCNT = 0; MMU.WRAMCNT = 0;
// Enable the sound speakers // Enable the sound speakers
@ -1274,95 +1288,243 @@ bool DSI_TSC::load_state(EMUFILE* is)
return true; return true;
} }
#ifdef _NEW_BOOT
//#define _LOG_NEW_BOOT 1
#endif
template<int PROCNUM> template<int PROCNUM>
void FASTCALL MMU_writeToGCControl(u32 val) void FASTCALL MMU_writeToGCControl(u32 val)
{ {
const int TEST_PROCNUM = PROCNUM; #ifdef _NEW_BOOT
nds_dscard& card = MMU.dscard[TEST_PROCNUM]; #ifdef _LOG_NEW_BOOT
extern bool dolog;
extern FILE *fp_dis9;
extern FILE *fp_dis7;
memcpy(&card.command[0], &MMU.MMU_MEM[TEST_PROCNUM][0x40][0x1A8], 8); u32 oldCnt = T1ReadLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4);
#endif
#endif
nds_dscard& card = MMU.dscard[PROCNUM];
#ifdef _NEW_BOOT
card.delay = 0;
#endif
memcpy(&card.command[0], &MMU.MMU_MEM[PROCNUM][0x40][0x1A8], 8);
card.blocklen = 0; card.blocklen = 0;
#ifndef _NEW_BOOT
slot1_device.write32(PROCNUM,0xFFFFFFFF,val); //Special case for some flashcarts slot1_device.write32(PROCNUM,0xFFFFFFFF,val); //Special case for some flashcarts
if(card.blocklen==0x01020304) return; if(card.blocklen==0x01020304) return;
if(!(val & 0x80000000)) if ((val & 0x80000000) == 0)
{ {
card.address = 0; card.address = 0;
card.transfer_count = 0; card.transfer_count = 0;
val &= 0x7F7FFFFF; val &= 0x7F7FFFFF;
T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val); T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
return; return;
} }
#else
if ((val & (1 << 15)) != 0)
{
#ifdef _LOG_NEW_BOOT
printf("--- ARM%c: cmd %02X (%016llX), ctrl %08X (%08X), delay %X/%X\n", PROCNUM?'7':'9', card.command[0], *(u64 *)&card.command[0], val, oldCnt, (val & 0x1FFF), ((val >> 16) & 0x3F));
if (fp_dis7)
fprintf(fp_dis7, "--- ARM%c: KEY2 apply!!! ctrl %08X (PC:0x%08X)\n", PROCNUM?'7':'9', val, ARMPROC.instruct_adr);
printf("--- ARM%c: KEY2 apply!!! ctrl %08X (PC:0x%08X)\n", PROCNUM?'7':'9', val, ARMPROC.instruct_adr);
#endif
key2.applySeed(PROCNUM);
}
if ((val & 0x80000000) == 0)
{
card.address = 0;
card.transfer_count = 0;
val &= 0x7F7FFFFF;
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
return;
}
#endif
u32 shift = (val>>24&7); u32 shift = (val>>24&7);
if(shift == 7) if(shift == 7)
card.transfer_count = 1; card.transfer_count = 1;
else if(shift == 0) else if(shift == 0)
card.transfer_count = 0; card.transfer_count = 0;
else else
card.transfer_count = (0x100<<shift)/4; card.transfer_count = (0x100 << shift) / 4;
switch (card.mode) #ifdef _NEW_BOOT
#ifdef _LOG_NEW_BOOT
if (fp_dis7)
fprintf(fp_dis7, "ARM%c: cmd %02X (%016llX), ctrl %08X\n", PROCNUM?'7':'9', card.command[0], *(u64 *)&card.command[0], val);
//printf("ARM%c: cmd %02X (%016llX), ctrl %08X (%08X), PC:%08X, delay %X/%X\n", PROCNUM?'7':'9', card.command[0], *(u64 *)&card.command[0], val, oldCnt, ARMPROC.instruct_adr, (val & 0x1FFF), ((val >> 16) & 0x3F));
#endif
#endif
if (card.mode == CardMode_Normal)
{ {
case CardMode_Normal: switch(card.command[0])
break;
case CardMode_KEY1:
{ {
// TODO case 0x9F: //Dummy
INFO("Cartridge: KEY1 mode unsupported.\n"); card.address = 0;
card.transfer_count = 0x800;
break;
case 0x3C: //Switch to KEY1 mode
#ifdef _NEW_BOOT
{
#ifdef _LOG_NEW_BOOT
u32 chipID = MMU_read32(PROCNUM, 0x027FFE0C);
if (fp_dis7)
fprintf(fp_dis7, "ARM%c: Activate KEY1 encryption mode (id %08X)\n", PROCNUM?'7':'9', chipID);
printf("ARM%c: Activate KEY1 encryption mode (id %08X)\n", PROCNUM?'7':'9', chipID);
#endif
card.mode = CardMode_KEY1;
card.transfer_count = 0;
}
#else
printf("ARM%c: Activate unsupported KEY1 encryption mode\n", PROCNUM?'7':'9');
card.mode = CardMode_KEY1;
card.transfer_count = 0;
#endif
break;
default:
//fall through to the special slot1 handler
slot1_device.write32(PROCNUM, REG_GCROMCTRL,val);
break;
}
}
else
if (card.mode == CardMode_KEY1 || card.mode == CardMode_KEY2)
{
#ifdef _NEW_BOOT
u32 chipID = MMU_read32(PROCNUM, 0x027FFE0C);
//u32 chipID = MMU_read32(PROCNUM, 0x037F8014);
u64 cmd = bswap64(*(u64 *)&card.command[0]);
key1.init(chipID, 2, 0x08);
key1.decrypt((u32*)&cmd);
*(u64*)&card.command[0] = bswap64(cmd);
switch (cmd >> 60)
{
case 0x02: // Get secure are block (4Kbytes) - 910h+11A8h
{
u32 size = ((cmd >> 44) & 0xFFFF) * (4 * 1024);
u32 addr = MMU_read32(PROCNUM, 0x0380FC00);
#ifdef _LOG_NEW_BOOT
if (fp_dis7)
fprintf(fp_dis7, "ARM%c: Get secure are block (4Kbytes)\n", PROCNUM?'7':'9');
printf("ARM%c: Get secure are block (4Kbytes) src %08X size %04X\n", PROCNUM?'7':'9', addr, size);
#endif
// TODO: check ChipID uppper bit
card.address = addr;
card.transfer_count = 0;//size / 4;
}
break;
case 0x04: // Activate KEY2 encryption mode - 910h+0
card.mode = CardMode_KEY2;
#ifdef _LOG_NEW_BOOT
if (fp_dis7)
fprintf(fp_dis7, "ARM%c: Activate KEY2 encryption mode\n", PROCNUM?'7':'9');
printf("ARM%c: Activate KEY2 encryption mode\n", PROCNUM?'7':'9');
#endif
//key2.applySeed(PROCNUM);
//card.delay = 0x910;
break;
case 0x06: // Optional KEY2 disable - 910h+?
break;
case 0x0A: // Enter main data mode - 910h+0
#ifdef _LOG_NEW_BOOT
if (fp_dis7)
fprintf(fp_dis7, "ARM%c: Enter main data mode\n", PROCNUM?'7':'9');
printf("ARM%c: Enter main data mode\n", PROCNUM?'7':'9');
#endif
card.mode = CardMode_DATA_LOAD;
//card.delay = 0x910;
break;
default: // Invalid - get KEY2 stream XOR 00h - 910h+...
slot1_device.write32(PROCNUM, REG_GCROMCTRL, val);
break;
}
#else
card.address = 0; card.address = 0;
card.transfer_count = 0; card.transfer_count = 0;
printf("ARM%c: Activate unsupported KEY2 encryption mode\n", PROCNUM?'7':'9');
val &= 0x7F7FFFFF; card.mode = CardMode_KEY2;
T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val); card.transfer_count = 0;
return; #endif
} }
break; else
case CardMode_KEY2: if (card.mode == CardMode_DATA_LOAD)
INFO("Cartridge: KEY2 mode unsupported.\n"); {
break; #ifdef _NEW_BOOT
} u64 cmd = bswap64(*(u64 *)&card.command[0]);
*(u64*)&card.command[0] = bswap64(cmd);
slot1_device.write32(PROCNUM, REG_GCROMCTRL, val);
#else
INFO("Cartridge: KEY2 load data mode unsupported.\n");
card.address = 0;
card.transfer_count = 0;
#endif
}
switch(card.command[0]) if(card.delay == 0 && card.transfer_count == 0)
{
case 0x9F: //Dummy
card.address = 0;
card.transfer_count = 0x800;
break;
//case 0x90: //Get ROM chip ID
// break;
case 0x3C: //Switch to KEY1 mode
card.mode = CardMode_KEY1;
break;
default:
//fall through to the special slot1 handler
slot1_device.write32(TEST_PROCNUM, REG_GCROMCTRL,val);
break;
}
if(card.transfer_count == 0)
{ {
val &= 0x7F7FFFFF; val &= 0x7F7FFFFF;
T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val); T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
#ifdef _LOG_NEW_BOOT
if (fp_dis7)
fprintf(fp_dis7, "ARM%c: ctrl %08X - stop transfer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", PROCNUM?'7':'9', val);
printf("ARM%c: ctrl %08X - stop transfer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", PROCNUM?'7':'9', val);
#endif
return; return;
} }
val |= 0x00800000; val |= 0x00800000;
T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val); 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"
//printf("triggering card dma\n"); //printf("triggering card dma\n");
triggerDma(EDMAMode_Card); triggerDma(EDMAMode_Card);
} }
template<int PROCNUM>
u32 FASTCALL MMU_readFromGCControl()
{
nds_dscard& card = MMU.dscard[PROCNUM];
#ifdef _NEW_BOOT
u32 val = T1ReadLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4);
if (card.delay > 0)
{
card.delay--;
if (card.delay == 0)
{
printf("ARM%c: delay stop\n", PROCNUM?'7':'9');
val &= 0x7F7FFFFF;
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
}
}
return val;
#else
card.delay = 0;
return T1ReadLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4);
#endif
}
template<int PROCNUM> template<int PROCNUM>
u32 MMU_readFromGC() u32 MMU_readFromGC()
@ -1375,7 +1537,11 @@ u32 MMU_readFromGC()
if(card.transfer_count == 0) if(card.transfer_count == 0)
return 0; return 0;
switch(card.command[0]) u8 cmd = card.command[0];
if ((card.mode == CardMode_KEY1) || (card.mode == CardMode_KEY2))
cmd >>= 4;
switch(cmd)
{ {
case 0x9F: //Dummy case 0x9F: //Dummy
val = 0xFFFFFFFF; val = 0xFFFFFFFF;
@ -2436,11 +2602,11 @@ static INLINE void write_auxspicnt(const int proc, const int size, const int adr
case 8: case 8:
switch(adr) { switch(adr) {
case 0: case 0:
T1WriteByte((u8*)&MMU.AUX_SPI_CNT,0,val); T1WriteByte((u8*)&MMU.AUX_SPI_CNT, 0, val);
if (val == 0) MMU_new.backupDevice.reset_command(); if (val == 0) MMU_new.backupDevice.reset_command();
break; break;
case 1: case 1:
T1WriteByte((u8*)&MMU.AUX_SPI_CNT,1,val); T1WriteByte((u8*)&MMU.AUX_SPI_CNT, 1, val);
break; break;
} }
} }
@ -2650,10 +2816,8 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
break; break;
case REG_AUXSPICNT: case REG_AUXSPICNT:
write_auxspicnt(9,8,0,val);
return;
case REG_AUXSPICNT+1: case REG_AUXSPICNT+1:
write_auxspicnt(9,8,1,val); write_auxspicnt(9, 8, adr & 1, val);
return; return;
case REG_AUXSPIDATA: case REG_AUXSPIDATA:
@ -2709,7 +2873,6 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
case 0x040001AF : case 0x040001AF :
LOG("%08X : %02X\r\n", adr, val); LOG("%08X : %02X\r\n", adr, val);
#endif #endif
} }
MMU.MMU_MEM[ARMCPU_ARM9][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]]=val; MMU.MMU_MEM[ARMCPU_ARM9][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]]=val;
@ -3008,7 +3171,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
} }
case REG_AUXSPICNT: case REG_AUXSPICNT:
write_auxspicnt(9,16,0,val); write_auxspicnt(9, 16, 0, val);
return; return;
case REG_AUXSPIDATA: case REG_AUXSPIDATA:
@ -4014,9 +4177,13 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val)
case REG_IF+3: REG_IF_WriteByte<ARMCPU_ARM7>(3,val); break; case REG_IF+3: REG_IF_WriteByte<ARMCPU_ARM7>(3,val); break;
case REG_POSTFLG: case REG_POSTFLG:
#ifdef _LOG_NEW_BOOT
printf("ARM7: write POSTFLG %02X\n", val);
#endif
//The NDS7 register can be written to only from code executed in BIOS. //The NDS7 register can be written to only from code executed in BIOS.
if (NDS_ARM7.instruct_adr > 0x3FFF) return; if (NDS_ARM7.instruct_adr > 0x3FFF) return;
#ifndef _NEW_BOOT
// hack for patched firmwares // hack for patched firmwares
if (val == 1) if (val == 1)
{ {
@ -4025,28 +4192,41 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val)
_MMU_write32<ARMCPU_ARM9>(0x27FFE24, gameInfo.header.ARM9exe); _MMU_write32<ARMCPU_ARM9>(0x27FFE24, gameInfo.header.ARM9exe);
_MMU_write32<ARMCPU_ARM7>(0x27FFE34, gameInfo.header.ARM7exe); _MMU_write32<ARMCPU_ARM7>(0x27FFE34, gameInfo.header.ARM7exe);
} }
#endif
break; break;
case REG_HALTCNT: case REG_HALTCNT:
//printf("halt 0x%02X\n", val);
switch(val)
{ {
case 0xC0: NDS_Sleep(); break; //printf("ARM7: Halt 0x%02X IME %02X, IE 0x%08X, IF 0x%08X PC 0x%08X\n", val, MMU.reg_IME[1], MMU.reg_IE[1], MMU.reg_IF_bits[1], NDS_ARM7.instruct_adr);
case 0x80: armcpu_Wait4IRQ(&NDS_ARM7); break; switch(val)
default: break; {
//case 0x10: printf("GBA mode unsupported\n"); break;
case 0xC0: NDS_Sleep(); break;
case 0x80:
#ifdef _NEW_BOOT
// FIXME: CrazyMax: HACK!!! for firmware boot form BIOS:
// i should study this and remove hack later
if (NDS_ARM7.instruct_adr == 0x00002F28 &&
(MMU.reg_IE[1] & (1 << 19)) &&
(MMU.reg_IF_bits[1] == 0))
MMU.reg_IF_bits[1] |= (1 << 19);
#endif
armcpu_Wait4IRQ(&NDS_ARM7);
break;
default: break;
}
break;
} }
break;
case REG_RTC: case REG_RTC:
rtcWrite(val); rtcWrite(val);
return; return;
case REG_AUXSPICNT: case REG_AUXSPICNT:
write_auxspicnt(9,8,0,val);
return;
case REG_AUXSPICNT+1: case REG_AUXSPICNT+1:
write_auxspicnt(9,8,1,val); write_auxspicnt(7, 8, adr & 1, val);
return; return;
case REG_AUXSPIDATA: case REG_AUXSPIDATA:
if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF; if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF;
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((u8)val,ARMCPU_ARM7)); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((u8)val,ARMCPU_ARM7));
@ -4054,8 +4234,8 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val)
return; return;
case REG_SPIDATA: case REG_SPIDATA:
// CrazyMax: 27 May 2013: BIOS write 8bit commands to flash controller // CrazyMax: 27 May 2013: BIOS write 8bit commands to flash controller when load firmware header
// (write firmware header into RAM at 0x027FF830) // into RAM at 0x027FF830
MMU_writeToSPIData(val); MMU_writeToSPIData(val);
return; return;
} }
@ -4149,7 +4329,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
case REG_AUXSPICNT: case REG_AUXSPICNT:
write_auxspicnt(7,16,0,val); write_auxspicnt(7, 16, 0, val);
return; return;
case REG_AUXSPIDATA: case REG_AUXSPIDATA:
@ -4594,10 +4774,8 @@ u32 FASTCALL _MMU_ARM7_read32(u32 adr)
return MMU.timer[ARMCPU_ARM7][(adr&0xF)>>2] | (val<<16); return MMU.timer[ARMCPU_ARM7][(adr&0xF)>>2] | (val<<16);
} }
case REG_GCROMCTRL: case REG_GCROMCTRL:
{ return MMU_readFromGCControl<ARMCPU_ARM7>();
//INFO("arm7 romctrl read\n");
break;
}
case REG_GCDATAIN: case REG_GCDATAIN:
return MMU_readFromGC<ARMCPU_ARM7>(); return MMU_readFromGC<ARMCPU_ARM7>();

View File

@ -300,6 +300,7 @@ enum ECardMode
CardMode_Normal = 0, CardMode_Normal = 0,
CardMode_KEY1, CardMode_KEY1,
CardMode_KEY2, CardMode_KEY2,
CardMode_DATA_LOAD
}; };
typedef struct typedef struct
@ -309,6 +310,7 @@ typedef struct
u32 address; u32 address;
u32 transfer_count; u32 transfer_count;
u32 delay;
ECardMode mode; ECardMode mode;

View File

@ -439,7 +439,6 @@ static std::vector<char> buffer;
static std::vector<char> v; static std::vector<char> v;
static void loadrom(std::string fname) { static void loadrom(std::string fname) {
FILE* inf = fopen(fname.c_str(),"rb"); FILE* inf = fopen(fname.c_str(),"rb");
if(!inf) return; if(!inf) return;
@ -448,7 +447,15 @@ static void loadrom(std::string fname) {
fseek(inf,0,SEEK_SET); fseek(inf,0,SEEK_SET);
gameInfo.resize(size); gameInfo.resize(size);
fread(gameInfo.romdata,1,size,inf);
#ifdef _NEW_BOOT
extern NDS_SLOT1_TYPE slot1_device_type;
if (slot1_device_type == NDS_SLOT1_NONE)
memset(gameInfo.romdata, 0xFF, size);
else
#endif
fread(gameInfo.romdata,1,size,inf);
gameInfo.fillGap(); gameInfo.fillGap();
fclose(inf); fclose(inf);
@ -566,6 +573,7 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
if (ret < 1) if (ret < 1)
return ret; return ret;
#ifndef _NEW_BOOT
//decrypt if necessary.. //decrypt if necessary..
//but this is untested and suspected to fail on big endian, so lets not support this on big endian //but this is untested and suspected to fail on big endian, so lets not support this on big endian
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
@ -575,6 +583,7 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
printf("Specified file is not a valid rom\n"); printf("Specified file is not a valid rom\n");
return -1; return -1;
} }
#endif
#endif #endif
if (cheatSearch) if (cheatSearch)
@ -591,6 +600,10 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
INFO("ROM serial: %s\n", gameInfo.ROMserial); INFO("ROM serial: %s\n", gameInfo.ROMserial);
INFO("ROM internal name: %s\n", gameInfo.ROMname); INFO("ROM internal name: %s\n", gameInfo.ROMname);
INFO("ROM developer: %s\n", getDeveloperNameByID(gameInfo.header.makerCode).c_str()); INFO("ROM developer: %s\n", getDeveloperNameByID(gameInfo.header.makerCode).c_str());
#ifdef _NEW_BOOT
gameInfo.storeSecureArea();
#endif
memset(buf, 0, MAX_PATH); memset(buf, 0, MAX_PATH);
strcpy(buf, path.pathToModule); strcpy(buf, path.pathToModule);
@ -1156,10 +1169,11 @@ template<int procnum, int num> struct TSequenceItem_Timer : public TSequenceItem
{ {
IF_DEVELOPER(DEBUG_statistics.sequencerExecutionCounters[13+procnum*4+num]++); IF_DEVELOPER(DEBUG_statistics.sequencerExecutionCounters[13+procnum*4+num]++);
u8* regs = procnum==0?MMU.ARM9_REG:MMU.ARM7_REG; u8* regs = procnum==0?MMU.ARM9_REG:MMU.ARM7_REG;
bool first = true, over; bool first = true;
//we'll need to check chained timers.. //we'll need to check chained timers..
for(int i=num;i<4;i++) for(int i=num;i<4;i++)
{ {
bool over = false;
//maybe too many checks if this is here, but we need it here for now //maybe too many checks if this is here, but we need it here for now
if(!MMU.timerON[procnum][i]) return; if(!MMU.timerON[procnum][i]) return;
@ -2478,12 +2492,14 @@ void NDS_Reset()
PrepareLogfiles(); PrepareLogfiles();
#ifndef _NEW_BOOT
//according to smea, this is initialized to 3 by the time we get into a user game program. who does this? //according to smea, this is initialized to 3 by the time we get into a user game program. who does this?
//well, the firmware load process is about to write a boot program into SIWRAM for the arm7. so we need it setup by now. //well, the firmware load process is about to write a boot program into SIWRAM for the arm7. so we need it setup by now.
//but, this is a bit weird.. I would be expecting the bioses to do that. maybe we have some more detail to emulate. //but, this is a bit weird.. I would be expecting the bioses to do that. maybe we have some more detail to emulate.
//* is this setting the default, or does the bios do it before loading the firmware programs? //* is this setting the default, or does the bios do it before loading the firmware programs?
//at any, it's important that this be done long before the user code ever runs //at any, it's important that this be done long before the user code ever runs
_MMU_write08<ARMCPU_ARM9>(REG_WRAMCNT,3); _MMU_write08<ARMCPU_ARM9>(REG_WRAMCNT,3);
#endif
if (firmware) if (firmware)
{ {
@ -2495,6 +2511,12 @@ void NDS_Reset()
if (NDS_ARM7.BIOS_loaded && NDS_ARM9.BIOS_loaded && CommonSettings.BootFromFirmware && fw_success) if (NDS_ARM7.BIOS_loaded && NDS_ARM9.BIOS_loaded && CommonSettings.BootFromFirmware && fw_success)
{ {
#ifdef _NEW_BOOT
gameInfo.restoreSecureArea();
armcpu_init(&NDS_ARM7, 0x00000000);
armcpu_init(&NDS_ARM9, 0xFFFF0000);
#else
//Copy secure area to memory if needed. //Copy secure area to memory if needed.
//could we get a comment about what's going on here? //could we get a comment about what's going on here?
//how does this stuff get copied before anything ever even runs? //how does this stuff get copied before anything ever even runs?
@ -2526,6 +2548,7 @@ void NDS_Reset()
armcpu_init(&NDS_ARM7, firmware->ARM7bootAddr); armcpu_init(&NDS_ARM7, firmware->ARM7bootAddr);
armcpu_init(&NDS_ARM9, firmware->ARM9bootAddr); armcpu_init(&NDS_ARM9, firmware->ARM9bootAddr);
} }
#endif
//set REG_POSTFLG to the value indicating pre-firmware status //set REG_POSTFLG to the value indicating pre-firmware status
MMU.ARM9_REG[0x300] = 0; MMU.ARM9_REG[0x300] = 0;
@ -2535,6 +2558,20 @@ void NDS_Reset()
{ {
//fake firmware boot-up process //fake firmware boot-up process
#ifdef _NEW_BOOT
gameInfo.restoreSecureArea();
//decrypt if necessary..
//but this is untested and suspected to fail on big endian, so lets not support this on big endian
#ifndef WORDS_BIGENDIAN
bool okRom = DecryptSecureArea((u8*)gameInfo.romdata,gameInfo.romsize);
if(!okRom) {
printf("Specified file is not a valid rom\n");
return;
}
#endif
#endif
// Create the dummy firmware // Create the dummy firmware
NDS_CreateDummyFirmware(&CommonSettings.fw_config); NDS_CreateDummyFirmware(&CommonSettings.fw_config);
@ -2571,6 +2608,7 @@ void NDS_Reset()
reconstruct(&cp15); reconstruct(&cp15);
cp15.reset(&NDS_ARM9); cp15.reset(&NDS_ARM9);
#ifndef _NEW_BOOT
//bitbox 4k demo is so stripped down it relies on default stack values //bitbox 4k demo is so stripped down it relies on default stack values
//otherwise the arm7 will crash before making a sound //otherwise the arm7 will crash before making a sound
//(these according to gbatek softreset bios docs) //(these according to gbatek softreset bios docs)
@ -2588,6 +2626,7 @@ void NDS_Reset()
NDS_ARM9.R[13] = NDS_ARM9.R13_usr; NDS_ARM9.R[13] = NDS_ARM9.R13_usr;
//n.b.: im not sure about all these, I dont know enough about arm9 svc/irq/etc modes //n.b.: im not sure about all these, I dont know enough about arm9 svc/irq/etc modes
//and how theyre named in desmume to match them up correctly. i just guessed. //and how theyre named in desmume to match them up correctly. i just guessed.
#endif
nds.wifiCycle = 0; nds.wifiCycle = 0;
memset(nds.timerCycle, 0, sizeof(u64) * 2 * 4); memset(nds.timerCycle, 0, sizeof(u64) * 2 * 4);
@ -2603,15 +2642,18 @@ void NDS_Reset()
nds.ensataIpcSyncCounter = 0; nds.ensataIpcSyncCounter = 0;
SetupMMU(nds.Is_DebugConsole(),nds.Is_DSI()); SetupMMU(nds.Is_DebugConsole(),nds.Is_DSI());
#ifndef _NEW_BOOT
_MMU_write16<ARMCPU_ARM9>(REG_KEYINPUT, 0x3FF); _MMU_write16<ARMCPU_ARM9>(REG_KEYINPUT, 0x3FF);
_MMU_write16<ARMCPU_ARM7>(REG_KEYINPUT, 0x3FF); _MMU_write16<ARMCPU_ARM7>(REG_KEYINPUT, 0x3FF);
_MMU_write08<ARMCPU_ARM7>(REG_EXTKEYIN, 0x43); _MMU_write08<ARMCPU_ARM7>(REG_EXTKEYIN, 0x43);
#endif
LidClosed = FALSE; LidClosed = FALSE;
countLid = 0; countLid = 0;
resetUserInput(); resetUserInput();
#ifndef _NEW_BOOT
//Setup a copy of the firmware user settings in memory. //Setup a copy of the firmware user settings in memory.
//(this is what the DS firmware would do). //(this is what the DS firmware would do).
{ {
@ -2638,7 +2680,6 @@ void NDS_Reset()
_MMU_write32<ARMCPU_ARM9>(0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); _MMU_write32<ARMCPU_ARM9>(0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i]));
} }
//-------------------------------- //--------------------------------
//setup the homebrew argv //setup the homebrew argv
//this is useful for nitrofs apps which are emulating themselves via cflash //this is useful for nitrofs apps which are emulating themselves via cflash
@ -2685,6 +2726,17 @@ void NDS_Reset()
TSCal.adc.y2 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x60); TSCal.adc.y2 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x60);
TSCal.scr.x2 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x62); TSCal.scr.x2 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x62);
TSCal.scr.y2 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x63); TSCal.scr.y2 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x63);
#else
// TODO: hack!!!
TSCal.adc.x1 = 0x0228;
TSCal.adc.y1 = 0x0350;
TSCal.scr.x1 = 0x0020;
TSCal.scr.y1 = 0x0020;
TSCal.adc.x2 = 0x0DA0;
TSCal.adc.y2 = 0x0BFC;
TSCal.scr.x2 = 0xE0;
TSCal.scr.y2 = 0xA0;
#endif
TSCal.adc.width = (TSCal.adc.x2 - TSCal.adc.x1); TSCal.adc.width = (TSCal.adc.x2 - TSCal.adc.x1);
TSCal.adc.height = (TSCal.adc.y2 - TSCal.adc.y1); TSCal.adc.height = (TSCal.adc.y2 - TSCal.adc.y1);
@ -2694,7 +2746,9 @@ void NDS_Reset()
MainScreen.offset = 0; MainScreen.offset = 0;
SubScreen.offset = 192; SubScreen.offset = 192;
#ifndef _NEW_BOOT
//_MMU_write32[ARMCPU_ARM9](0x02007FFC, 0xE92D4030); //_MMU_write32[ARMCPU_ARM9](0x02007FFC, 0xE92D4030);
#endif
delete header; delete header;

View File

@ -83,6 +83,7 @@ extern BOOL click;
#define NDS_FW_LANG_CHI 6 #define NDS_FW_LANG_CHI 6
#define NDS_FW_LANG_RES 7 #define NDS_FW_LANG_RES 7
extern CFIRMWARE *firmware;
//#define LOG_ARM9 //#define LOG_ARM9
//#define LOG_ARM7 //#define LOG_ARM7
@ -90,55 +91,55 @@ extern BOOL click;
#include "PACKED.h" #include "PACKED.h"
struct NDS_header struct NDS_header
{ {
char gameTile[12]; char gameTile[12]; // 000 - Game Title (uppercase ASCII, padded with 00h)
char gameCode[4]; char gameCode[4]; // 00C - Gamecode (uppercase ASCII, NTR-<code>, 0=homebrew)
u16 makerCode; u16 makerCode; // 010 - Makercode (uppercase ASCII, 0=homebrew)
u8 unitCode; u8 unitCode; // 012 - Unitcode (00h=Nintendo DS)
u8 deviceCode; u8 deviceCode; // 013 - Encryption Seed Select (00..07h, usually 00h)
u8 cardSize; u8 cardSize; // 014 - Devicecapacity (Chipsize = 128KB SHL nn) (eg. 7 = 16MB)
u8 cardInfo[8]; u8 cardInfo[8]; // 015 - ??? --> reversed (padded 00h)
u8 flags; u8 flags; // 01D - ??? |
u8 romversion; u8 romversion; // 01E - ROM Version (usually 00h)
u8 reserved; u8 autostart; // 01F - Autostart (Bit2: Skip "Press Button" after Health and Safety)
// (Also skips bootmenu, even in Manual mode & even Start pressed)
u32 ARM9src; // 020 -
u32 ARM9exe; // 024 -
u32 ARM9cpy; // 028 -
u32 ARM9binSize; // 02C -
u32 ARM7src; // 030 -
u32 ARM7exe; // 034 -
u32 ARM7cpy; // 038 -
u32 ARM7binSize; // 03C -
u32 FNameTblOff; // 040 -
u32 FNameTblSize; // 044 -
u32 ARM9src; u32 FATOff; // 048 -
u32 ARM9exe; u32 FATSize; // 04C -
u32 ARM9cpy;
u32 ARM9binSize;
u32 ARM7src; u32 ARM9OverlayOff; // 050 -
u32 ARM7exe; u32 ARM9OverlaySize; // 054 -
u32 ARM7cpy; u32 ARM7OverlayOff; // 058 -
u32 ARM7binSize; u32 ARM7OverlaySize; // 05C -
u32 FNameTblOff; u32 unknown2a; // 060 - Port 40001A4h setting for normal commands (usually 00586000h)
u32 FNameTblSize; u32 unknown2b; // 064 - Port 40001A4h setting for KEY1 commands (usually 001808F8h)
u32 FATOff; u32 IconOff; // 068 -
u32 FATSize; u16 CRC16; // 06C -
u16 ROMtimeout; // 06E -
u32 ARM9OverlayOff; u32 ARM9unk; // 070 -
u32 ARM9OverlaySize; u32 ARM7unk; // 074 -
u32 ARM7OverlayOff;
u32 ARM7OverlaySize; u8 unknown3c[8]; // 078 - Secure Area Disable (by encrypted "NmMdOnly") (usually zero)
u32 ROMSize; // 080 - Total Used ROM size (remaining/unused bytes usually FFh-padded)
u32 unknown2a; u32 HeaderSize; // 084 - ROM Header Size (4000h)
u32 unknown2b; u8 unknown5[56]; // 088 - Reserved (zero filled) - "PASS" is contained within here?
u8 logo[156]; // 0C0 - Nintendo Logo (compressed bitmap, same as in GBA Headers)
u32 IconOff; u16 logoCRC16; // 15C - Nintendo Logo Checksum, CRC-16 of [0C0h-15Bh], fixed CF56h
u16 CRC16; u16 headerCRC16; // 15E - Header Checksum, CRC-16 of [000h-15Dh]
u16 ROMtimeout; u8 reserved[160]; //
u32 ARM9unk;
u32 ARM7unk;
u8 unknown3c[8];
u32 ROMSize;
u32 HeaderSize;
u8 unknown5[56]; //"PASS" is contained within here?
u8 logo[156];
u16 logoCRC16;
u16 headerCRC16;
u8 unknown6[160];
}; };
#include "PACKED_END.h" #include "PACKED_END.h"
@ -325,6 +326,7 @@ struct GameInfo
memset(&header, 0, sizeof(header)); memset(&header, 0, sizeof(header));
memset(&ROMserial[0], 0, sizeof(ROMserial)); memset(&ROMserial[0], 0, sizeof(ROMserial));
memset(&ROMname[0], 0, sizeof(ROMname)); memset(&ROMname[0], 0, sizeof(ROMname));
memset(&securyArea[0], 0, sizeof(securyArea));
} }
void loadData(char* buf, int size) void loadData(char* buf, int size)
@ -335,6 +337,18 @@ struct GameInfo
fillGap(); fillGap();
} }
void storeSecureArea()
{
if ((header.ARM9src >= 0x4000) && (header.ARM9src < 0x8000))
memcpy(&securyArea[0], &romdata[header.ARM9src], 0x8000 - header.ARM9src);
}
void restoreSecureArea()
{
if ((header.ARM9src >= 0x4000) && (header.ARM9src < 0x8000))
memcpy(&romdata[header.ARM9src], &securyArea[0], 0x8000 - header.ARM9src);
}
void fillGap() void fillGap()
{ {
memset(romdata+romsize,0xFF,allocatedSize-romsize); memset(romdata+romsize,0xFF,allocatedSize-romsize);
@ -371,6 +385,7 @@ struct GameInfo
const RomBanner& getRomBanner(); const RomBanner& getRomBanner();
bool hasRomBanner(); bool hasRomBanner();
bool isHomebrew; bool isHomebrew;
u8 securyArea[0x4000];
}; };
typedef struct TSCalInfo typedef struct TSCalInfo

View File

@ -18,6 +18,7 @@
#include "../slot1.h" #include "../slot1.h"
#include "../registers.h" #include "../registers.h"
#include "../MMU.h" #include "../MMU.h"
#include "../NDSSystem.h"
static void slot1_info(char *info) { strcpy(info, "Slot1 no-card emulation"); } static void slot1_info(char *info) { strcpy(info, "Slot1 no-card emulation"); }
static void slot1_config(void) {} static void slot1_config(void) {}
@ -27,6 +28,9 @@ static BOOL slot1_init() { return (TRUE); }
static void slot1_reset() static void slot1_reset()
{ {
// Write the header checksum to memory (the firmware needs it to see the cart) // Write the header checksum to memory (the firmware needs it to see the cart)
#ifdef _NEW_BOOT
if (!CommonSettings.BootFromFirmware)
#endif
_MMU_write16<ARMCPU_ARM9>(0x027FF808, 0); _MMU_write16<ARMCPU_ARM9>(0x027FF808, 0);
} }

View File

@ -28,6 +28,9 @@ static BOOL init() { return (TRUE); }
static void reset() static void reset()
{ {
// Write the header checksum to memory (the firmware needs it to see the cart) // Write the header checksum to memory (the firmware needs it to see the cart)
#ifdef _NEW_BOOT
if (!CommonSettings.BootFromFirmware)
#endif
_MMU_write16<ARMCPU_ARM9>(0x027FF808, T1ReadWord(MMU.CART_ROM, 0x15E)); _MMU_write16<ARMCPU_ARM9>(0x027FF808, T1ReadWord(MMU.CART_ROM, 0x15E));
} }
@ -43,21 +46,72 @@ static void write32_GCROMCTRL(u8 PROCNUM, u32 val)
switch(card.command[0]) switch(card.command[0])
{ {
case 0x00: //Data read case 0x00: //Data read (0000000000000000h Get Cartridge Header) - len 200h bytes
case 0xB7: case 0xB7:
card.address = (card.command[1] << 24) | (card.command[2] << 16) | (card.command[3] << 8) | card.command[4]; card.address = (card.command[1] << 24) | (card.command[2] << 16) | (card.command[3] << 8) | card.command[4];
card.transfer_count = 0x80; card.transfer_count = 0x80;
break; break;
case 0xB8: // Chip ID case 0x90: // 1st Get ROM Chip ID - len 4 bytes
card.address = 0;
card.transfer_count = 1;
break;
case 0xB8: // 3rd Get ROM Chip ID - len 4 bytes
card.address = 0; card.address = 0;
card.transfer_count = 1; card.transfer_count = 1;
break; break;
default: default:
if (card.mode == CardMode_KEY1 || card.mode == CardMode_KEY2)
{
u8 cmd = (card.command[0] >> 4);
switch(cmd)
{
case 0x01: // 2nd Get ROM Chip ID - len 4 bytes
card.address = 0;
card.transfer_count = 1;
break;
default:
card.address = 0;
card.transfer_count = 0;
printf("ARM%c: SLOT1 invalid command %02X (write) - CardMode_KEY1/CardMode_KEY2 mode\n", PROCNUM?'7':'9', cmd);
break;
}
return;
}
if (card.mode == CardMode_DATA_LOAD)
{
switch(card.command[0])
{
case 0xB7:
card.address = (card.command[1] << 24) | (card.command[2] << 16) | (card.command[3] << 8) | card.command[4];
card.transfer_count = 0x80;
break;
case 0xB8: // 3nd Get ROM Chip ID - len 4 bytes
card.address = 0;
card.transfer_count = 1;
break;
default:
card.address = 0;
card.transfer_count = 0;
printf("ARM%c: SLOT1 invalid command %02X (write) - CardMode_DATA_LOAD mode\n", PROCNUM?'7':'9', card.command[0]);
break;
}
return;
}
card.address = 0; card.address = 0;
card.transfer_count = 0; card.transfer_count = 0;
break; #ifdef _NEW_BOOT
printf("ARM%c: SLOT1 invalid command %02X (write)\n", PROCNUM?'7':'9', card.command[0]);
#endif
break;
} }
} }
@ -83,13 +137,32 @@ static u16 read16(u8 PROCNUM, u32 adr)
static u32 read32_GCDATAIN(u8 PROCNUM) static u32 read32_GCDATAIN(u8 PROCNUM)
{ {
nds_dscard& card = MMU.dscard[PROCNUM]; nds_dscard& card = MMU.dscard[PROCNUM];
u8 cmd = card.command[0];
switch(card.command[0]) if (card.mode == CardMode_KEY1 || card.mode == CardMode_KEY2)
cmd >>= 4;
switch(cmd)
{ {
//Get ROM chip ID case 0x01: // 2nd Get ROM Chip ID - len 4 bytes
case 0x90: case 0x90: // 1st Get ROM Chip ID - len 4 bytes
case 0xB8: case 0xB8: // 3rd Get ROM Chip ID - len 4 bytes
{ {
// Returns RAW unencrypted Chip ID (eg. C2h,0Fh,00h,00h), repeated every 4 bytes.
//
// 1st byte - Manufacturer (C2h = Macronix)
// 2nd byte - Chip size in megabytes minus 1 (eg. 0Fh = 16MB)
// 3rd byte - Reserved/zero (probably upper bits of chip size)
// 4th byte - Bit7: Secure Area Block transfer mode (8x200h or 1000h)
#ifdef _NEW_BOOT
u32 chipID = 0;
if (CommonSettings.BootFromFirmware)
chipID = 0x00000000 | 0x00000000 | 0x00000F00 | 0x000000C2;;
#else
u32 chipID = 0;
#endif
// Note: the BIOS stores the chip ID in main memory // Note: the BIOS stores the chip ID in main memory
// Most games continuously compare the chip ID with // Most games continuously compare the chip ID with
// the value in memory, probably to know if the card // the value in memory, probably to know if the card
@ -104,7 +177,8 @@ static u32 read32_GCDATAIN(u8 PROCNUM)
//staff of kings verifies this (it also uses the arm7 IRQ 20) //staff of kings verifies this (it also uses the arm7 IRQ 20)
if(nds.cardEjected) //TODO - handle this with ejected card slot1 device (and verify using this case) if(nds.cardEjected) //TODO - handle this with ejected card slot1 device (and verify using this case)
return 0xFFFFFFFF; return 0xFFFFFFFF;
else return 0; else
return chipID;
} }
break; break;
@ -119,7 +193,7 @@ static u32 read32_GCDATAIN(u8 PROCNUM)
u32 address = card.address & (gameInfo.mask); u32 address = card.address & (gameInfo.mask);
// Make sure any reads below 0x8000 redirect to 0x8000+(adr&0x1FF) as on real cart // Make sure any reads below 0x8000 redirect to 0x8000+(adr&0x1FF) as on real cart
if((card.command[0] == 0xB7) && (address < 0x8000)) if((cmd == 0xB7) && (address < 0x8000))
{ {
//TODO - refactor this to include the PROCNUM, for debugging purposes if nothing else //TODO - refactor this to include the PROCNUM, for debugging purposes if nothing else
//(can refactor gbaslot also) //(can refactor gbaslot also)
@ -142,6 +216,9 @@ static u32 read32_GCDATAIN(u8 PROCNUM)
} }
break; break;
default: default:
#ifdef _NEW_BOOT
printf("ARM%c: SLOT1 invalid command %02X (read)\n", PROCNUM?'7':'9', cmd);
#endif
return 0; return 0;
} //switch(card.command[0]) } //switch(card.command[0])
} //read32_GCDATAIN } //read32_GCDATAIN

View File

@ -667,11 +667,14 @@ void arm_jit_sync()
template<int PROCNUM, bool jit> template<int PROCNUM, bool jit>
u32 armcpu_exec() u32 armcpu_exec()
{ {
// TODO: CrazyMax - temporarily disable JIT until finish a new boot code
#ifndef _NEW_BOOT
if (jit) if (jit)
{ {
ArmOpCompiled f = (ArmOpCompiled)JIT_COMPILED_FUNC(ARMPROC.instruct_adr, PROCNUM); ArmOpCompiled f = (ArmOpCompiled)JIT_COMPILED_FUNC(ARMPROC.instruct_adr, PROCNUM);
return f ? f() : arm_jit_compile<PROCNUM>(); return f ? f() : arm_jit_compile<PROCNUM>();
} }
#endif
return armcpu_exec<PROCNUM>(); return armcpu_exec<PROCNUM>();
} }

View File

@ -55,6 +55,22 @@ inline T SIGNED_OVERFLOW(T a,T b,T c) { return BIT31(((a)&(b)&(~c)) | ((~a)&(~(b
template<typename T> template<typename T>
inline T SIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((a)&(~(b))&(~c)) | ((~a)&(b)&(c))); } inline T SIGNED_UNDERFLOW(T a,T b,T c) { return BIT31(((a)&(~(b))&(~c)) | ((~a)&(b)&(c))); }
#define bswap32(val) \
( (val << 24) & 0xFF000000) | \
( (val << 8) & 0x00FF0000) | \
( (val >> 8) & 0x0000FF00) | \
( (val >> 24) & 0x000000FF)
#define bswap64(x) \
( (x << 56) & 0xff00000000000000UL ) | \
( (x << 40) & 0x00ff000000000000UL ) | \
( (x << 24) & 0x0000ff0000000000UL ) | \
( (x << 8) & 0x000000ff00000000UL ) | \
( (x >> 8) & 0x00000000ff000000UL ) | \
( (x >> 24) & 0x0000000000ff0000UL ) | \
( (x >> 40) & 0x000000000000ff00UL ) | \
( (x >> 56) & 0x00000000000000ffUL )
// ============================= CPRS flags funcs // ============================= CPRS flags funcs
inline bool CarryFrom(s32 left, s32 right) inline bool CarryFrom(s32 left, s32 right)
{ {

View File

@ -15,11 +15,11 @@
along with the this software. If not, see <http://www.gnu.org/licenses/>. along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "encrypt.h" #include "armcpu.h"
#include "MMU.h" #include "MMU.h"
#include "encrypt.h"
//================================================================================== KEY1 //================================================================================== KEY1
#define bswap32(val) (((val & 0x000000FF) << 24) | ((val & 0x0000FF00) << 8) | ((val & 0x00FF0000) >> 8) | ((val & 0xFF000000) >> 24))
#define DWNUM(i) ((i) >> 2) #define DWNUM(i) ((i) >> 2)
void _KEY1::init(u32 idcode, u8 level, u8 modulo) void _KEY1::init(u32 idcode, u8 level, u8 modulo)
@ -36,8 +36,6 @@ void _KEY1::init(u32 idcode, u8 level, u8 modulo)
keyCode[2] >>= 1; keyCode[2] >>= 1;
if (level >= 3) // third apply (optional) if (level >= 3) // third apply (optional)
applyKeycode(modulo); applyKeycode(modulo);
printf("keycode1: %08X%08X%08X\n", keyCode[2], keyCode[1], keyCode[0]);
} }
void _KEY1::applyKeycode(u8 modulo) void _KEY1::applyKeycode(u8 modulo)
@ -97,15 +95,33 @@ void _KEY1::encrypt(u32 *ptr)
ptr[1] = y ^ keyBuf[DWNUM(0x44)]; ptr[1] = y ^ keyBuf[DWNUM(0x44)];
} }
#undef DWNUM #undef DWNUM
#undef bswap32
//================================================================================== KEY2 //================================================================================== KEY2
u64 _KEY2::bitsReverse39(u64 key)
{
u64 tmp = 0;
for (u32 i = 0; i < 39; i++)
tmp |= ((key >> i) & 1) << (38 - i);
return tmp;
}
void _KEY2::applySeed(u8 PROCNUM) void _KEY2::applySeed(u8 PROCNUM)
{ {
u64 tmp = (MMU_read8(PROCNUM, REG_ENCSEED0H) & 0xFF); u64 tmp = (MMU_read8(PROCNUM, REG_ENCSEED0H) & 0xFF);
seed0 = MMU_read32(PROCNUM, REG_ENCSEED0L) | (tmp << 32); seed0 = MMU_read32(PROCNUM, REG_ENCSEED0L) | (tmp << 32);
tmp = (MMU_read8(PROCNUM, REG_ENCSEED1H) & 0xFF); tmp = (MMU_read8(PROCNUM, REG_ENCSEED1H) & 0xFF);
seed1 = MMU_read32(PROCNUM, REG_ENCSEED1L) | (tmp << 32); seed1 = MMU_read32(PROCNUM, REG_ENCSEED1L) | (tmp << 32);
printf("ARM%c: set KEY2 seed0 to %010llX\n", PROCNUM?'7':'9', seed0); x = bitsReverse39(seed0);
printf("ARM%c: set KEY2 seed1 to %010llX\n", PROCNUM?'7':'9', seed1); y = bitsReverse39(seed1);
//printf("ARM%c: set KEY2 seed0 to %010llX (reverse %010llX)\n", PROCNUM?'7':'9', seed0, x);
//printf("ARM%c: set KEY2 seed1 to %010llX (reverse %010llX)\n", PROCNUM?'7':'9', seed1, y);
}
u8 _KEY2::apply(u8 data)
{
x = (((x >> 5) ^ (x >> 17) ^ (x >> 18) ^ (x >> 31)) & 0xFF) + (x << 8);
y = (((y >> 5) ^ (y >> 23) ^ (y >> 18) ^ (y >> 31)) & 0xFF) + (y << 8);
return ((data ^ x ^ y) & 0xFF);
} }

View File

@ -25,8 +25,8 @@ struct _KEY1
_KEY1(u8 *inKeyBufPtr) _KEY1(u8 *inKeyBufPtr)
{ {
if (keyBuf) delete keyBuf; if (keyBuf) delete keyBuf;
keyBuf = new u32 [0x1048 / sizeof(u32)]; keyBuf = new u32 [0x412];
memset(keyBuf, 0x00, 0x1048); memset(keyBuf, 0x00, 0x412 * sizeof(u32));
memset(&keyCode[0], 0, sizeof(keyCode)); memset(&keyCode[0], 0, sizeof(keyCode));
this->keyBufPtr = inKeyBufPtr; this->keyBufPtr = inKeyBufPtr;
} }
@ -52,14 +52,21 @@ struct _KEY1
struct _KEY2 struct _KEY2
{ {
_KEY2() : seed0(0x58C56DE0E8ULL), private:
seed1(0x5C879B9B05ULL)
{}
u64 seed0; u64 seed0;
u64 seed1; u64 seed1;
u64 x;
u64 y;
u64 bitsReverse39(u64 key);
public:
_KEY2() : seed0(0x58C56DE0E8ULL),
seed1(0x5C879B9B05ULL)
{}
void applySeed(u8 PROCNUM); void applySeed(u8 PROCNUM);
u8 apply(u8 data);
}; };
#endif #endif

View File

@ -253,13 +253,13 @@ bool CFIRMWARE::load()
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
size = ftell(fp); size = ftell(fp);
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
if( (size != 256*1024) && (size != 512*1024) ) if( (size != NDS_FW_SIZE_V1) && (size != NDS_FW_SIZE_V2) )
{ {
fclose(fp); fclose(fp);
return false; return false;
} }
#if 1 #ifndef _NEW_BOOT
if (size == 512*1024) if (size == 512*1024)
{ {
INFO("ERROR: 32Mbit (512Kb) firmware not supported\n"); INFO("ERROR: 32Mbit (512Kb) firmware not supported\n");
@ -278,6 +278,7 @@ bool CFIRMWARE::load()
if (fread(data, 1, size, fp) != size) if (fread(data, 1, size, fp) != size)
{ {
delete [] data; delete [] data;
data = NULL;
fclose(fp); fclose(fp);
return false; return false;
} }
@ -294,8 +295,12 @@ bool CFIRMWARE::load()
#ifdef _NEW_BOOT #ifdef _NEW_BOOT
if (CommonSettings.BootFromFirmware) if (CommonSettings.BootFromFirmware)
{ {
if (MMU.fw.size != size) // reallocate
mc_alloc(&MMU.fw, size);
memcpy(MMU.fw.data, data, size); memcpy(MMU.fw.data, data, size);
MMU.fw.size = size; delete [] data;
data = NULL;
return true; return true;
} }
#endif #endif
@ -475,6 +480,7 @@ bool CFIRMWARE::load()
strncpy(MMU.fw.userfile, extFilePath.c_str(), MAX_PATH); strncpy(MMU.fw.userfile, extFilePath.c_str(), MAX_PATH);
fclose(fp); fclose(fp);
fp = fopen(MMU.fw.userfile, "rb"); fp = fopen(MMU.fw.userfile, "rb");
if (fp) if (fp)
{ {

View File

@ -147,13 +147,13 @@ void mc_init(memory_chip_t *mc, int type)
u8 *mc_alloc(memory_chip_t *mc, u32 size) u8 *mc_alloc(memory_chip_t *mc, u32 size)
{ {
u8 *buffer; u8 *buffer = NULL;
buffer = new u8[size]; buffer = new u8[size];
if(!buffer) { return NULL; }
memset(buffer,0,size); memset(buffer,0,size);
if (mc->data) delete [] mc->data; if (mc->data) delete [] mc->data;
mc->data = buffer; mc->data = buffer;
if(!buffer) { return NULL; }
mc->size = size; mc->size = size;
mc->writeable_buffer = TRUE; mc->writeable_buffer = TRUE;
@ -176,6 +176,7 @@ void fw_reset_com(memory_chip_t *mc)
fwrite(mc->data, mc->size, 1, mc->fp); fwrite(mc->data, mc->size, 1, mc->fp);
} }
#ifndef _NEW_BOOT
if (mc->isFirmware&&CommonSettings.UseExtFirmware) if (mc->isFirmware&&CommonSettings.UseExtFirmware)
{ {
// copy User Settings 1 to User Settings 0 area // copy User Settings 1 to User Settings 0 area
@ -200,7 +201,7 @@ void fw_reset_com(memory_chip_t *mc)
else else
printf(" - failed\n"); printf(" - failed\n");
} }
#endif
mc->write_enable = FALSE; mc->write_enable = FALSE;
} }