new boot:

- refactoring old boot code;
This commit is contained in:
mtabachenko 2013-07-29 10:16:34 +00:00
parent 42705efde7
commit bce045de58
3 changed files with 161 additions and 167 deletions

View File

@ -2448,7 +2448,6 @@ void NDS_Reset()
{
singleStep = false;
nds_debug_continuing[0] = nds_debug_continuing[1] = false;
bool fw_success = false;
FILE* inf = NULL;
NDS_header * header = NDS_getROMHeader();
@ -2492,22 +2491,41 @@ void NDS_Reset()
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?
//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.
//* 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
_MMU_write08<ARMCPU_ARM9>(REG_WRAMCNT,3);
#endif
nds.wifiCycle = 0;
memset(nds.timerCycle, 0, sizeof(u64) * 2 * 4);
nds.old = 0;
nds.scr_touchX = nds.scr_touchY = nds.adc_touchX = nds.adc_touchY = 0;
nds.isTouch = 0;
nds.paddle = 0;
nds.ConsoleType = CommonSettings.ConsoleType;
nds._DebugConsole = CommonSettings.DebugConsole;
nds.ensataEmulation = CommonSettings.EnsataEmulation;
nds.stylusJitter = CommonSettings.StylusJitter;
nds.ensataHandshake = ENSATA_HANDSHAKE_none;
nds.ensataIpcSyncCounter = 0;
SetupMMU(nds.Is_DebugConsole(),nds.Is_DSI());
LidClosed = FALSE;
countLid = 0;
MainScreen.offset = 0;
SubScreen.offset = 192;
// only ARM9 have co-processor
reconstruct(&cp15);
cp15.reset(&NDS_ARM9);
resetUserInput();
if (firmware)
{
delete firmware;
firmware = NULL;
}
firmware = new CFIRMWARE();
fw_success = firmware->load();
// TODO: fw_success should be global
bool fw_success = firmware->load();
if (NDS_ARM7.BIOS_loaded && NDS_ARM9.BIOS_loaded && CommonSettings.BootFromFirmware && fw_success)
{
@ -2516,7 +2534,25 @@ void NDS_Reset()
armcpu_init(&NDS_ARM7, 0x00000000);
armcpu_init(&NDS_ARM9, 0xFFFF0000);
// 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;
TSCal.adc.width = (TSCal.adc.x2 - TSCal.adc.x1);
TSCal.adc.height = (TSCal.adc.y2 - TSCal.adc.y1);
TSCal.scr.width = (TSCal.scr.x2 - TSCal.scr.x1);
TSCal.scr.height = (TSCal.scr.y2 - TSCal.scr.y1);
#else
_MMU_write08<ARMCPU_ARM9>(REG_WRAMCNT,3);
firmware->unpack();
//Copy secure area to memory if needed.
//could we get a comment about what's going on here?
//how does this stuff get copied before anything ever even runs?
@ -2548,11 +2584,13 @@ void NDS_Reset()
armcpu_init(&NDS_ARM7, firmware->ARM7bootAddr);
armcpu_init(&NDS_ARM9, firmware->ARM9bootAddr);
}
#endif
//set REG_POSTFLG to the value indicating pre-firmware status
MMU.ARM9_REG[0x300] = 0;
MMU.ARM7_REG[0x300] = 0;
goto _fake_boot;
#endif
}
else
{
@ -2571,6 +2609,15 @@ void NDS_Reset()
}
#endif
#endif
//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.
//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?
//at any, it's important that this be done long before the user code ever runs
_MMU_write08<ARMCPU_ARM9>(REG_WRAMCNT,3);
if (CommonSettings.UseExtFirmware && fw_success)
firmware->unpack();
// Create the dummy firmware
NDS_CreateDummyFirmware(&CommonSettings.fw_config);
@ -2602,84 +2649,78 @@ void NDS_Reset()
//set REG_POSTFLG to the value indicating post-firmware status
MMU.ARM9_REG[0x300] = 1;
MMU.ARM7_REG[0x300] = 1;
}
// only ARM9 have co-processor
reconstruct(&cp15);
cp15.reset(&NDS_ARM9);
_fake_boot:
//Setup a copy of the firmware user settings in memory.
//(this is what the DS firmware would do).
{
u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT];
int fw_index;
#ifndef _NEW_BOOT
//bitbox 4k demo is so stripped down it relies on default stack values
//otherwise the arm7 will crash before making a sound
//(these according to gbatek softreset bios docs)
NDS_ARM7.R13_svc = 0x0380FFDC;
NDS_ARM7.R13_irq = 0x0380FFB0;
NDS_ARM7.R13_usr = 0x0380FF00;
NDS_ARM7.R[13] = NDS_ARM7.R13_usr;
//and let's set these for the arm9 while we're at it, though we have no proof
NDS_ARM9.R13_svc = 0x00803FC0;
NDS_ARM9.R13_irq = 0x00803FA0;
NDS_ARM9.R13_usr = 0x00803EC0;
NDS_ARM9.R13_abt = NDS_ARM9.R13_usr; //?????
//I think it is wrong to take gbatek's "SYS" and put it in USR--maybe USR doesnt matter.
//i think SYS is all the misc modes. please verify by setting nonsensical stack values for USR here
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
//and how theyre named in desmume to match them up correctly. i just guessed.
#endif
nds.wifiCycle = 0;
memset(nds.timerCycle, 0, sizeof(u64) * 2 * 4);
nds.old = 0;
nds.scr_touchX = nds.scr_touchY = nds.adc_touchX = nds.adc_touchY = 0;
nds.isTouch = 0;
nds.paddle = 0;
nds.ConsoleType = CommonSettings.ConsoleType;
nds._DebugConsole = CommonSettings.DebugConsole;
nds.ensataEmulation = CommonSettings.EnsataEmulation;
nds.stylusJitter = CommonSettings.StylusJitter;
nds.ensataHandshake = ENSATA_HANDSHAKE_none;
nds.ensataIpcSyncCounter = 0;
SetupMMU(nds.Is_DebugConsole(),nds.Is_DSI());
#ifndef _NEW_BOOT
_MMU_write16<ARMCPU_ARM9>(REG_KEYINPUT, 0x3FF);
_MMU_write16<ARMCPU_ARM7>(REG_KEYINPUT, 0x3FF);
_MMU_write08<ARMCPU_ARM7>(REG_EXTKEYIN, 0x43);
#endif
LidClosed = FALSE;
countLid = 0;
resetUserInput();
#ifndef _NEW_BOOT
//Setup a copy of the firmware user settings in memory.
//(this is what the DS firmware would do).
{
u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT];
int fw_index;
if ( copy_firmware_user_data( temp_buffer, MMU.fw.data)) {
for ( fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++)
_MMU_write08<ARMCPU_ARM9>(0x027FFC80 + fw_index, temp_buffer[fw_index]);
if ( copy_firmware_user_data( temp_buffer, MMU.fw.data)) {
for ( fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++)
_MMU_write08<ARMCPU_ARM9>(0x027FFC80 + fw_index, temp_buffer[fw_index]);
}
}
// Copy the whole header to Main RAM 0x27FFE00 on startup. (http://nocash.emubase.de/gbatek.htm#dscartridgeheader)
//once upon a time this copied 0x90 more. this was thought to be wrong, and changed.
if(nds.Is_DSI())
{
//dsi needs this copied later in memory. there are probably a number of things that get copied to a later location in memory.. thats where the NDS consoles tend to stash stuff.
for (int i = 0; i < ((0x170)/4); i++)
_MMU_write32<ARMCPU_ARM9>(0x02FFFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i]));
}
else
{
for (int i = 0; i < ((0x170)/4); i++)
_MMU_write32<ARMCPU_ARM9>(0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i]));
}
// make system think it's booted from card -- EXTREMELY IMPORTANT!!! Thanks to cReDiAr
_MMU_write08<ARMCPU_ARM9>(0x02FFFC40,0x1);
_MMU_write08<ARMCPU_ARM7>(0x02FFFC40,0x1);
// Save touchscreen calibration info in a structure
// so we can easily access it at any time
TSCal.adc.x1 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x58);
TSCal.adc.y1 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x5A);
TSCal.scr.x1 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x5C);
TSCal.scr.y1 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x5D);
TSCal.adc.x2 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x5E);
TSCal.adc.y2 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x60);
TSCal.scr.x2 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x62);
TSCal.scr.y2 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x63);
TSCal.adc.width = (TSCal.adc.x2 - TSCal.adc.x1);
TSCal.adc.height = (TSCal.adc.y2 - TSCal.adc.y1);
TSCal.scr.width = (TSCal.scr.x2 - TSCal.scr.x1);
TSCal.scr.height = (TSCal.scr.y2 - TSCal.scr.y1);
_MMU_write16<ARMCPU_ARM9>(REG_KEYINPUT, 0x3FF);
_MMU_write16<ARMCPU_ARM7>(REG_KEYINPUT, 0x3FF);
_MMU_write08<ARMCPU_ARM7>(REG_EXTKEYIN, 0x43);
//bitbox 4k demo is so stripped down it relies on default stack values
//otherwise the arm7 will crash before making a sound
//(these according to gbatek softreset bios docs)
NDS_ARM7.R13_svc = 0x0380FFDC;
NDS_ARM7.R13_irq = 0x0380FFB0;
NDS_ARM7.R13_usr = 0x0380FF00;
NDS_ARM7.R[13] = NDS_ARM7.R13_usr;
//and let's set these for the arm9 while we're at it, though we have no proof
NDS_ARM9.R13_svc = 0x00803FC0;
NDS_ARM9.R13_irq = 0x00803FA0;
NDS_ARM9.R13_usr = 0x00803EC0;
NDS_ARM9.R13_abt = NDS_ARM9.R13_usr; //?????
//I think it is wrong to take gbatek's "SYS" and put it in USR--maybe USR doesnt matter.
//i think SYS is all the misc modes. please verify by setting nonsensical stack values for USR here
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
//and how theyre named in desmume to match them up correctly. i just guessed.
}
// Copy the whole header to Main RAM 0x27FFE00 on startup. (http://nocash.emubase.de/gbatek.htm#dscartridgeheader)
//once upon a time this copied 0x90 more. this was thought to be wrong, and changed.
if(nds.Is_DSI())
{
//dsi needs this copied later in memory. there are probably a number of things that get copied to a later location in memory.. thats where the NDS consoles tend to stash stuff.
for (int i = 0; i < ((0x170)/4); i++)
_MMU_write32<ARMCPU_ARM9>(0x02FFFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i]));
}
else
{
for (int i = 0; i < ((0x170)/4); i++)
_MMU_write32<ARMCPU_ARM9>(0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i]));
}
#ifndef _NEW_BOOT
//--------------------------------
//setup the homebrew argv
//this is useful for nitrofs apps which are emulating themselves via cflash
@ -2704,52 +2745,8 @@ void NDS_Reset()
_MMU_write08<ARMCPU_ARM9>(kCommandline+i, rompath[i]);
_MMU_write08<ARMCPU_ARM9>(kCommandline+rompath.size(), 0);
//--------------------------------
if ((firmware->patched) && (CommonSettings.UseExtBIOS == true) && (CommonSettings.BootFromFirmware == true) && (fw_success == TRUE))
{
// HACK! for flashme
_MMU_write32<ARMCPU_ARM9>(0x27FFE24, firmware->ARM9bootAddr);
_MMU_write32<ARMCPU_ARM7>(0x27FFE34, firmware->ARM7bootAddr);
}
// make system think it's booted from card -- EXTREMELY IMPORTANT!!! Thanks to cReDiAr
_MMU_write08<ARMCPU_ARM9>(0x02FFFC40,0x1);
_MMU_write08<ARMCPU_ARM7>(0x02FFFC40,0x1);
// Save touchscreen calibration info in a structure
// so we can easily access it at any time
TSCal.adc.x1 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x58);
TSCal.adc.y1 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x5A);
TSCal.scr.x1 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x5C);
TSCal.scr.y1 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x5D);
TSCal.adc.x2 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x5E);
TSCal.adc.y2 = _MMU_read16<ARMCPU_ARM7>(0x027FFC80 + 0x60);
TSCal.scr.x2 = _MMU_read08<ARMCPU_ARM7>(0x027FFC80 + 0x62);
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.height = (TSCal.adc.y2 - TSCal.adc.y1);
TSCal.scr.width = (TSCal.scr.x2 - TSCal.scr.x1);
TSCal.scr.height = (TSCal.scr.y2 - TSCal.scr.y1);
MainScreen.offset = 0;
SubScreen.offset = 192;
#ifndef _NEW_BOOT
//_MMU_write32[ARMCPU_ARM9](0x02007FFC, 0xE92D4030);
#endif
delete header;
Screen_Reset();
@ -2758,7 +2755,6 @@ void NDS_Reset()
slot1Reset();
WIFI_Reset();
memcpy(FW_Mac, (MMU.fw.data + 0x36), 6);
initSchedule();

View File

@ -236,11 +236,6 @@ bool CFIRMWARE::load()
{
u32 size = 0;
u8 *data = NULL;
u16 shift1 = 0, shift2 = 0, shift3 = 0, shift4 = 0;
u32 part1addr = 0, part2addr = 0, part3addr = 0, part4addr = 0, part5addr = 0;
u32 part1ram = 0, part2ram = 0;
u32 src = 0;
if (CommonSettings.UseExtFirmware == false)
return false;
@ -259,15 +254,6 @@ bool CFIRMWARE::load()
return false;
}
#ifndef _NEW_BOOT
if (size == 512*1024)
{
INFO("ERROR: 32Mbit (512Kb) firmware not supported\n");
fclose(fp);
return false;
}
#endif
data = new u8 [size];
if (!data)
{
@ -291,19 +277,38 @@ bool CFIRMWARE::load()
fclose(fp);
return false;
}
fclose(fp);
#ifdef _NEW_BOOT
if (CommonSettings.BootFromFirmware)
if (MMU.fw.size != size) // reallocate
mc_alloc(&MMU.fw, size);
memcpy(MMU.fw.data, data, size);
delete [] data;
data = NULL;
return true;
}
bool CFIRMWARE::unpack()
{
u32 src = 0;
u16 shift1 = 0, shift2 = 0, shift3 = 0, shift4 = 0;
u32 part1addr = 0, part2addr = 0, part3addr = 0, part4addr = 0, part5addr = 0;
u32 part1ram = 0, part2ram = 0;
u32 size = MMU.fw.size;
if (size == 512*1024)
{
if (MMU.fw.size != size) // reallocate
mc_alloc(&MMU.fw, size);
memcpy(MMU.fw.data, data, size);
delete [] data;
data = NULL;
return true;
INFO("ERROR: 32Mbit (512Kb) firmware not supported\n");
return false;
}
#endif
u8 *data = new u8 [size];
if (!data)
return false;
memcpy(data, MMU.fw.data, size);
shift1 = ((header.shift_amounts >> 0) & 0x07);
shift2 = ((header.shift_amounts >> 3) & 0x07);
@ -344,8 +349,7 @@ bool CFIRMWARE::load()
size9 = decrypt(data + part1addr, tmp_data9);
if (!tmp_data9)
{
delete [] data;
fclose(fp);
delete [] data; data = NULL;
return false;
}
@ -353,8 +357,7 @@ bool CFIRMWARE::load()
if (!tmp_data7)
{
delete [] tmp_data9;
delete [] data;
fclose(fp);
delete [] data; data = NULL;
return false;
}
@ -365,8 +368,7 @@ bool CFIRMWARE::load()
INFO("Firmware: ERROR: the boot code CRC16 (0x%04X) doesn't match the value in the firmware header (0x%04X)", crc16_mine, header.part12_boot_crc16);
delete [] tmp_data9;
delete [] tmp_data7;
delete [] data;
fclose(fp);
delete [] data; data = NULL;
return false;
}
@ -435,7 +437,6 @@ bool CFIRMWARE::load()
if (!tmp_data9)
{
delete [] data;
fclose(fp);
return false;
}
@ -444,7 +445,6 @@ bool CFIRMWARE::load()
{
delete [] tmp_data9;
delete [] data;
fclose(fp);
return false;
};
// Copy firmware boot codes to their respective locations
@ -479,9 +479,7 @@ bool CFIRMWARE::load()
std::string extFilePath = CFIRMWARE::GetExternalFilePath();
strncpy(MMU.fw.userfile, extFilePath.c_str(), MAX_PATH);
fclose(fp);
fp = fopen(MMU.fw.userfile, "rb");
FILE *fp = fopen(MMU.fw.userfile, "rb");
if (fp)
{
fseek(fp, 0, SEEK_END);
@ -517,8 +515,7 @@ bool CFIRMWARE::load()
}
printf("\n");
// TODO: add 512Kb support
memcpy(MMU.fw.data, data, 256*1024);
memcpy(MMU.fw.data, data, size);
MMU.fw.fp = NULL;
delete [] data; data = NULL;

View File

@ -38,6 +38,7 @@ public:
CFIRMWARE(): size9(0), size7(0), ARM9bootAddr(0), ARM7bootAddr(0), patched(0) {};
bool load();
bool unpack();
static std::string GetExternalFilePath();