From bc61000d9a625b5c3b5366016add0952f7dab71c Mon Sep 17 00:00:00 2001 From: zeromus Date: Sat, 31 Aug 2013 19:23:28 +0000 Subject: [PATCH] some cleanup in boot process --- desmume/src/GPU.cpp | 2 + desmume/src/NDSSystem.cpp | 518 +++++++++++++++++++------------------- desmume/src/NDSSystem.h | 6 + desmume/src/saves.cpp | 1 + 4 files changed, 273 insertions(+), 254 deletions(-) diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index 281783874..8e92867b6 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -1868,6 +1868,8 @@ void Screen_Reset(void) { GPU_Reset(MainScreen.gpu, 0); GPU_Reset(SubScreen.gpu, 1); + MainScreen.offset = 0; + SubScreen.offset = 192; memset(GPU_screen, 0, sizeof(GPU_screen)); for(int i = 0; i < (256*192*2); i++) diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 93717369f..efa5f843b 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -110,7 +110,6 @@ int NDS_Init( void) nds.idleFrameCounter = 0; memset(nds.runCycleCollector,0,sizeof(nds.runCycleCollector)); MMU_Init(); - nds.VCount = 0; //got to print this somewhere.. printf("%s\n", EMU_DESMUME_NAME_AND_VERSION()); @@ -2449,28 +2448,232 @@ static void PrepareLogfiles() #endif } +bool NDS_LegitBoot() +{ + #ifdef HAVE_JIT + //hack for firmware boot in JIT mode. + //we know that it takes certain jit parameters to successfully boot the firmware. + //CRAZYMAX: is it safe to accept anything smaller than 12? + CommonSettings.jit_max_block_size = std::min(CommonSettings.jit_max_block_size,12U); + #endif + + //crazymax: how would it have got whacked? dont think we need this + //gameInfo.restoreSecureArea(); + + //partially clobber the loaded firmware with the user settings from DFC + firmware->loadSettings(); + + //since firmware only boots encrypted roms, we have to make sure it's encrypted first + //this has not been validated on big endian systems. it almost positively doesn't work. + EncryptSecureArea((u8*)gameInfo.romdata,gameInfo.romsize); + + //boot processors from their bios entrypoints + armcpu_init(&NDS_ARM7, 0x00000000); + armcpu_init(&NDS_ARM9, 0xFFFF0000); + + // TODO: hack!!! + // possible explanation - since we can't generally trust calibration info from the firmware (who's bothered to set it up?) + // we don't bother to use the firmware's configured calibration info, and just enter our own. + // Can someone verify this? + // TODO - this isn't good. need revising. + 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); + + return true; +} + +//the fake firmware boot-up process +bool NDS_FakeBoot() +{ + NDS_header * header = NDS_getROMHeader(); + + //DEBUG_reset(); + + if (!header) return false; + + nds.isFakeBooted = true; + + //crazymax: how would it have got whacked? dont think we need this + //gameInfo.restoreSecureArea(); + + //since we're bypassing the code to decrypt the secure area, we need to make sure its decrypted first + //this has not been validated on big endian systems. it almost positively doesn't work. + bool okRom = DecryptSecureArea((u8*)gameInfo.romdata,gameInfo.romsize); + + if(!okRom) { + printf("Specified file is not a valid rom\n"); + return false; + } + + //bios (or firmware) sets this default, which is generally not important for retail games but some homebrews are depending on + _MMU_write08(REG_WRAMCNT,3); + + //EDIT - whats this firmware and how is it relating to the dummy firmware below + //how do these even get used? what is the purpose of unpack and why is it not used by the firmware boot process? + if (CommonSettings.UseExtFirmware && firmware->loaded()) + { + firmware->unpack(); + firmware->loadSettings(); + } + + // Create the dummy firmware + //EDIT - whats dummy firmware and how is relating to the above? + //it seems to be emplacing basic firmware data into MMU.fw.data + NDS_CreateDummyFirmware(&CommonSettings.fw_config); + + //firmware loads the game card arm9 and arm7 programs as specified in rom header + { + //copy the arm9 program to the address specified by rom header + u32 src = header->ARM9src; + u32 dst = header->ARM9cpy; + for(u32 i = 0; i < (header->ARM9binSize>>2); ++i) + { + _MMU_write32(dst, T1ReadLong(MMU.CART_ROM, src)); + dst += 4; + src += 4; + } + + //copy the arm7 program to the address specified by rom header + src = header->ARM7src; + dst = header->ARM7cpy; + for(u32 i = 0; i < (header->ARM7binSize>>2); ++i) + { + _MMU_write32(dst, T1ReadLong(MMU.CART_ROM, src)); + dst += 4; + src += 4; + } + } + + //bios does this (thats weird, though. shouldnt it get changed when the card is swapped in the firmware menu? + //right now our firmware menu isnt detecting any change to the card. + //are some games depending on it being written here? please document. + //_MMU_write16(0x027FF808, T1ReadWord(MMU.CART_ROM, 0x15E)); + + //firmware sets up a copy of the firmware user settings in memory. + //TBD - this code is really clunky + //it seems to be copying the MMU.fw.data data into RAM in the user memory stash locations + u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT]; + if ( copy_firmware_user_data( temp_buffer, MMU.fw.data)) { + for ( int fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++) + _MMU_write08(0x027FFC80 + fw_index, temp_buffer[fw_index]); + } + + //something copies 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(0x02FFFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); + } + else + { + for (int i = 0; i < ((0x170)/4); i++) + _MMU_write32(0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); + } + + //firmware sets the cpus to an initial state with their respective programs entrypoints + armcpu_init(&NDS_ARM7, header->ARM7exe); + armcpu_init(&NDS_ARM9, header->ARM9exe); + + //firmware sets REG_POSTFLG to the value indicating post-firmware status + MMU.ARM9_REG[0x300] = 1; + MMU.ARM7_REG[0x300] = 1; + + //firmware makes system think it's booted from card -- EXTREMELY IMPORTANT!!! This is actually checked by some things. (which things?) Thanks to cReDiAr + _MMU_write08(0x02FFFC40,0x1); // removed redundant write to ARM9, this is going to shared main memory. But one has to wonder why r3478 was made which corrected a typo resulting in only ARMCPU_ARM7 getting used. + + //the chipId is read several times + //for some reason, each of those reads get stored here. + _MMU_write32(0x027FF800, gameInfo.chipID); //1st chipId + _MMU_write32(0x027FF804, gameInfo.chipID); //2nd (secure) chipId + _MMU_write32(0x027FFC00, gameInfo.chipID); //3rd (secure) chipId + + // Write the header checksum to memory + _MMU_write16(0x027FF808, gameInfo.header.headerCRC16); + + // Save touchscreen calibration info in a structure + // so we can easily access it at any time + // TODO - this isn't good. need revising. + TSCal.adc.x1 = _MMU_read16(0x027FFC80 + 0x58); + TSCal.adc.y1 = _MMU_read16(0x027FFC80 + 0x5A); + TSCal.scr.x1 = _MMU_read08(0x027FFC80 + 0x5C); + TSCal.scr.y1 = _MMU_read08(0x027FFC80 + 0x5D); + TSCal.adc.x2 = _MMU_read16(0x027FFC80 + 0x5E); + TSCal.adc.y2 = _MMU_read16(0x027FFC80 + 0x60); + TSCal.scr.x2 = _MMU_read08(0x027FFC80 + 0x62); + TSCal.scr.y2 = _MMU_read08(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); + + //zero 11-aug-2013 - dont think we need this. the emulator will be setting these nonstop + //_MMU_write16(REG_KEYINPUT, 0x3FF); + //_MMU_write16(REG_KEYINPUT, 0x3FF); + //_MMU_write08(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. + + //-------------------------------- + //setup the homebrew argv + //this is useful for nitrofs apps which are emulating themselves via cflash + //struct __argv { + // int argvMagic; //!< argv magic number, set to 0x5f617267 ('_arg') if valid + // char *commandLine; //!< base address of command line, set of null terminated strings + // int length; //!< total length of command line + // int argc; //!< internal use, number of arguments + // char **argv; //!< internal use, argv pointer + //}; + std::string rompath = "fat:/" + path.RomName; + const u32 kCommandline = 0x027E0000; + //const u32 kCommandline = 0x027FFF84; + + // + _MMU_write32(0x02FFFE70, 0x5f617267); + _MMU_write32(0x02FFFE74, kCommandline); //(commandline starts here) + _MMU_write32(0x02FFFE78, rompath.size()+1); + //0x027FFF7C (argc) + //0x027FFF80 (argv) + for(size_t i=0;i(kCommandline+i, rompath[i]); + _MMU_write08(kCommandline+rompath.size(), 0); + //-------------------------------- + + delete header; + return true; +} + bool _HACK_DONT_STOPMOVIE = false; void NDS_Reset() { - singleStep = false; - nds_debug_continuing[0] = nds_debug_continuing[1] = false; - FILE* inf = NULL; - NDS_header * header = NDS_getROMHeader(); - - DEBUG_reset(); - - if (!header) return ; - - nds.sleeping = FALSE; - nds.cardEjected = FALSE; - nds.freezeBus = 0; - nds.power1.lcd = nds.power1.gpuMain = nds.power1.gfx3d_render = nds.power1.gfx3d_geometry = nds.power1.gpuSub = nds.power1.dispswap = 1; - nds.power2.speakers = 1; - nds.power2.wifi = 0; - - nds_timer = 0; - nds_arm9_timer = 0; - nds_arm7_timer = 0; + PrepareLogfiles(); if(movieMode != MOVIEMODE_INACTIVE && !_HACK_DONT_STOPMOVIE) movie_reset_command = true; @@ -2483,25 +2686,23 @@ void NDS_Reset() TotalLagFrames = 0; } - SPU_DeInit(); - - MMU_Reset(); - -#ifdef HAVE_JIT - arm_jit_reset(CommonSettings.use_jit); -#endif - - JumbleMemory(); - PrepareBiosARM7(); - PrepareBiosARM9(); - - PrepareLogfiles(); + resetUserInput(); + + singleStep = false; + nds_debug_continuing[0] = nds_debug_continuing[1] = false; + nds.sleeping = FALSE; + nds.cardEjected = FALSE; + nds.freezeBus = 0; + nds.power1.lcd = nds.power1.gpuMain = nds.power1.gfx3d_render = nds.power1.gfx3d_geometry = nds.power1.gpuSub = nds.power1.dispswap = 1; + nds.power2.speakers = 1; + nds.power2.wifi = 0; 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.isFakeBooted = false; nds.paddle = 0; nds.ConsoleType = CommonSettings.ConsoleType; nds._DebugConsole = CommonSettings.DebugConsole; @@ -2509,21 +2710,31 @@ void NDS_Reset() nds.stylusJitter = CommonSettings.StylusJitter; nds.ensataHandshake = ENSATA_HANDSHAKE_none; nds.ensataIpcSyncCounter = 0; - SetupMMU(nds.Is_DebugConsole(),nds.Is_DSI()); - + nds_timer = 0; + nds_arm9_timer = 0; + nds_arm7_timer = 0; LidClosed = FALSE; countLid = 0; - - MainScreen.offset = 0; - SubScreen.offset = 192; - // only ARM9 have co-processor + MMU_Reset(); + SetupMMU(nds.Is_DebugConsole(),nds.Is_DSI()); + JumbleMemory(); + + #ifdef HAVE_JIT + arm_jit_reset(CommonSettings.use_jit); + #endif + + + //initialize CP15 specially for this platform + //TODO - how much of this is necessary for firmware boot? + //(only ARM9 has CP15) reconstruct(&cp15); MMU.ARM9_RW_MODE = BIT7(cp15.ctrl); NDS_ARM9.intVector = 0xFFFF0000 * (BIT13(cp15.ctrl)); NDS_ARM9.LDTBit = !BIT15(cp15.ctrl); //TBit - resetUserInput(); + PrepareBiosARM7(); + PrepareBiosARM9(); if (firmware) { @@ -2534,219 +2745,16 @@ void NDS_Reset() firmware = new CFIRMWARE(); firmware->load(); - //the firmware can't be booted without the roms, for the following reasons: - //TBD - if (NDS_ARM7.BIOS_loaded && NDS_ARM9.BIOS_loaded && CommonSettings.BootFromFirmware && firmware->loaded()) - { -#ifdef HAVE_JIT - // hack for firmware boot in JIT mode - CommonSettings.jit_max_block_size = 12; -#endif - //crazymax: how would it have got whacked? dont think we need this - //gameInfo.restoreSecureArea(); - - //partially clobber the loaded firmware with the user settings from DFC - firmware->loadSettings(); - - //since firmware only boots encrypted roms, we have to make sure it's encrypted first - #ifndef WORDS_BIGENDIAN - //this has not been validated on big endian systems. it almost positively doesn't work. - EncryptSecureArea((u8*)gameInfo.romdata,gameInfo.romsize); - #endif - - //boot processors from their bios entrypoints - armcpu_init(&NDS_ARM7, 0x00000000); - armcpu_init(&NDS_ARM9, 0xFFFF0000); - - // TODO: hack!!! - // possible explanation - since we can't generally trust calibration info from the firmware (who's bothered to set it up?) - // we don't bother to use the firmware's configured calibration info, and just enter our own. - // Can someone verify this? - // TODO - this isn't good. need revising. - 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); - } + //we will allow a proper firmware boot, if: + //1. we have the ARM7 and ARM9 bioses (its doubtful that our HLE bios implement the necessary functions) + //2. firmware is available + //3. user has requested booting from firmware + bool canBootFromFirmware = (NDS_ARM7.BIOS_loaded && NDS_ARM9.BIOS_loaded && CommonSettings.BootFromFirmware && firmware->loaded()); + bool bootResult = false; + if(canBootFromFirmware) + bootResult = NDS_LegitBoot(); else - { - //the fake firmware boot-up process - - //crazymax: how would it have got whacked? dont think we need this - //gameInfo.restoreSecureArea(); - - //since we're bypassing the code to decrypt the secure area, we need to make sure its decrypted first -#ifndef WORDS_BIGENDIAN - //this has not been validated on big endian systems. it almost positively doesn't work. - bool okRom = DecryptSecureArea((u8*)gameInfo.romdata,gameInfo.romsize); - - if(!okRom) { - printf("Specified file is not a valid rom\n"); - return; - } -#endif - - //bios (or firmware) sets this default - _MMU_write08(REG_WRAMCNT,3); - - //EDIT - whats this firmware and how is it relating to the dummy firmware below - //how do these even get used? what is the purpose of unpack and why is it not used by the firmware boot process? - if (CommonSettings.UseExtFirmware && firmware->loaded()) - { - firmware->unpack(); - firmware->loadSettings(); - } - - // Create the dummy firmware - //EDIT - whats dummy firmware and how is relating to the above? - //it seems to be emplacing basic firmware data into MMU.fw.data - NDS_CreateDummyFirmware(&CommonSettings.fw_config); - - //firmware loads the game card arm9 and arm7 programs as specified in rom header - { - //copy the arm9 program to the address specified by rom header - u32 src = header->ARM9src; - u32 dst = header->ARM9cpy; - for(u32 i = 0; i < (header->ARM9binSize>>2); ++i) - { - _MMU_write32(dst, T1ReadLong(MMU.CART_ROM, src)); - dst += 4; - src += 4; - } - - //copy the arm7 program to the address specified by rom header - src = header->ARM7src; - dst = header->ARM7cpy; - for(u32 i = 0; i < (header->ARM7binSize>>2); ++i) - { - _MMU_write32(dst, T1ReadLong(MMU.CART_ROM, src)); - dst += 4; - src += 4; - } - } - - //bios does this (thats weird, though. shouldnt it get changed when the card is swapped in the firmware menu? - //right now our firmware menu isnt detecting any change to the card. - //are some games depending on it being written here? please document. - //_MMU_write16(0x027FF808, T1ReadWord(MMU.CART_ROM, 0x15E)); - - //firmware sets up a copy of the firmware user settings in memory. - //TBD - this code is really clunky - //it seems to be copying the MMU.fw.data data into RAM in the user memory stash locations - u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT]; - if ( copy_firmware_user_data( temp_buffer, MMU.fw.data)) { - for ( int fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++) - _MMU_write08(0x027FFC80 + fw_index, temp_buffer[fw_index]); - } - - //something copies 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(0x02FFFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); - } - else - { - for (int i = 0; i < ((0x170)/4); i++) - _MMU_write32(0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); - } - - //firmware sets the cpus to an initial state with their respective programs entrypoints - armcpu_init(&NDS_ARM7, header->ARM7exe); - armcpu_init(&NDS_ARM9, header->ARM9exe); - - //firmware sets REG_POSTFLG to the value indicating post-firmware status - MMU.ARM9_REG[0x300] = 1; - MMU.ARM7_REG[0x300] = 1; - - //firmware makes system think it's booted from card -- EXTREMELY IMPORTANT!!! This is actually checked by some things. (which things?) Thanks to cReDiAr - _MMU_write08(0x02FFFC40,0x1); // removed redundant write to ARM9, this is going to shared main memory. But one has to wonder why r3478 was made which corrected a typo resulting in only ARMCPU_ARM7 getting used. - - //the chipId is read several times - //for some reason, each of those reads get stored here. - _MMU_write32(0x027FF800, gameInfo.chipID); //1st chipId - _MMU_write32(0x027FF804, gameInfo.chipID); //2nd (secure) chipId - _MMU_write32(0x027FFC00, gameInfo.chipID); //3rd (secure) chipId - - // Write the header checksum to memory - _MMU_write16(0x027FF808, gameInfo.header.headerCRC16); - - // Save touchscreen calibration info in a structure - // so we can easily access it at any time - // TODO - this isn't good. need revising. - TSCal.adc.x1 = _MMU_read16(0x027FFC80 + 0x58); - TSCal.adc.y1 = _MMU_read16(0x027FFC80 + 0x5A); - TSCal.scr.x1 = _MMU_read08(0x027FFC80 + 0x5C); - TSCal.scr.y1 = _MMU_read08(0x027FFC80 + 0x5D); - TSCal.adc.x2 = _MMU_read16(0x027FFC80 + 0x5E); - TSCal.adc.y2 = _MMU_read16(0x027FFC80 + 0x60); - TSCal.scr.x2 = _MMU_read08(0x027FFC80 + 0x62); - TSCal.scr.y2 = _MMU_read08(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); - - //zero 11-aug-2013 - dont think we need this. the emulator will be setting these nonstop - //_MMU_write16(REG_KEYINPUT, 0x3FF); - //_MMU_write16(REG_KEYINPUT, 0x3FF); - //_MMU_write08(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. - - //-------------------------------- - //setup the homebrew argv - //this is useful for nitrofs apps which are emulating themselves via cflash - //struct __argv { - // int argvMagic; //!< argv magic number, set to 0x5f617267 ('_arg') if valid - // char *commandLine; //!< base address of command line, set of null terminated strings - // int length; //!< total length of command line - // int argc; //!< internal use, number of arguments - // char **argv; //!< internal use, argv pointer - //}; - std::string rompath = "fat:/" + path.RomName; - const u32 kCommandline = 0x027E0000; - //const u32 kCommandline = 0x027FFF84; - - // - _MMU_write32(0x02FFFE70, 0x5f617267); - _MMU_write32(0x02FFFE74, kCommandline); //(commandline starts here) - _MMU_write32(0x02FFFE78, rompath.size()+1); - //0x027FFF7C (argc) - //0x027FFF80 (argv) - for(size_t i=0;i(kCommandline+i, rompath[i]); - _MMU_write08(kCommandline+rompath.size(), 0); - //-------------------------------- - } - - delete header; + bootResult = NDS_FakeBoot(); Screen_Reset(); gfx3d_reset(); @@ -2755,9 +2763,11 @@ void NDS_Reset() WIFI_Reset(); memcpy(FW_Mac, (MMU.fw.data + 0x36), 6); - initSchedule(); - + SPU_DeInit(); SPU_ReInit(); + + //this needs to happen last, pretty much, since it establishes the correct scheduling state based on all of the above initialization + initSchedule(); } static std::string MakeInputDisplayString(u16 pad, const std::string* Buttons, int count) { diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 444f2336b..018bb5bc4 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -187,6 +187,9 @@ struct NDSSystem u16 scr_touchX; u16 scr_touchY; + //whether the console is using our faked-bootup process + BOOL isFakeBooted; + BOOL isTouch; u16 pad; @@ -479,6 +482,9 @@ int NDS_ImportSave(const char *filename, u32 force_size = 0); u32 NDS_ImportSaveSize(const char *filename); bool NDS_ExportSave(const char *filename); +bool NDS_LegitBoot(); +bool NDS_FakeBoot(); + void nds_savestate(EMUFILE* os); bool nds_loadstate(EMUFILE* is, int size); diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index a1816b7ef..e4341b8c4 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -177,6 +177,7 @@ SFORMAT SF_NDS[]={ { "_STX", 2, 1, &nds.scr_touchX}, { "_STY", 2, 1, &nds.scr_touchY}, { "_TPB", 4, 1, &nds.isTouch}, + { "_IFB", 4, 1, &nds.isFakeBooted}, { "_DBG", 4, 1, &nds._DebugConsole}, { "_ENS", 4, 1, &nds.ensataEmulation}, { "_TYP", 4, 1, &nds.ConsoleType},