diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index c9afa713e..42bfd142e 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -903,7 +903,8 @@ static inline void MMU_VRAMmapControl(u8 block, u8 VRAMBankCnt) -void MMU_Init(void) { +void MMU_Init(void) +{ LOG("MMU init\n"); memset(&MMU, 0, sizeof(MMU_struct)); @@ -1597,14 +1598,26 @@ static void CalculateTouchPressure(int pressurePercent, u16 &z1, u16& z2) void FASTCALL MMU_writeToSPIData(u16 val) { + + enum PM_Bits //from libnds + { + PM_SOUND_AMP = BIT(0) , /*!< \brief Power the sound hardware (needed to hear stuff in GBA mode too) */ + PM_SOUND_MUTE = BIT(1), /*!< \brief Mute the main speakers, headphone output will still work. */ + PM_BACKLIGHT_BOTTOM = BIT(2), /*!< \brief Enable the top backlight if set */ + PM_BACKLIGHT_TOP = BIT(3) , /*!< \brief Enable the bottom backlight if set */ + PM_SYSTEM_PWR = BIT(6) , /*!< \brief Turn the power *off* if set */ + }; + if (val !=0) MMU.SPI_CMD = val; u16 spicnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_SPICNT >> 20) & 0xff], REG_SPICNT & 0xfff); - switch ((spicnt >> 8) & 0x3) // device + int device = (spicnt >> 8) & 0x3; + int baudrate = spicnt & 0x3; + switch(device) { - case 0: // Powerman + case SPI_DEVICE_POWERMAN: if (!MMU.powerMan_CntRegWritten) { MMU.powerMan_CntReg = (val & 0xFF); @@ -1627,15 +1640,6 @@ void FASTCALL MMU_writeToSPIData(u16 val) //write MMU.powerMan_Reg[reg] = (u8)val; - enum PM_Bits //from libnds - { - PM_SOUND_AMP = BIT(0) , /*!< \brief Power the sound hardware (needed to hear stuff in GBA mode too) */ - PM_SOUND_MUTE = BIT(1), /*!< \brief Mute the main speakers, headphone output will still work. */ - PM_BACKLIGHT_BOTTOM = BIT(2), /*!< \brief Enable the top backlight if set */ - PM_BACKLIGHT_TOP = BIT(3) , /*!< \brief Enable the bottom backlight if set */ - PM_SYSTEM_PWR = BIT(6) , /*!< \brief Turn the power *off* if set */ - }; - //our totally pathetic register handling, only the one thing we've wanted so far if(MMU.powerMan_Reg[0]&PM_SYSTEM_PWR) { @@ -1649,14 +1653,17 @@ void FASTCALL MMU_writeToSPIData(u16 val) } break; - case 1: // Firmware - if((spicnt & 0x3) != 0) // check SPI baudrate (must be 4mhz) + case SPI_DEVICE_FIRMWARE: + if(baudrate != SPI_BAUDRATE_4MHZ) // check SPI baudrate (must be 4mhz) + { + printf("Wrong SPI baud rate for firmware access\n"); val = 0; + } else val = fw_transfer(&MMU.fw, (u8)val); break; - case 2: // Touch screen + case SPI_DEVICE_TOUCHSCREEN: { if(nds.Is_DSI()) { @@ -1709,6 +1716,7 @@ void FASTCALL MMU_writeToSPIData(u16 val) case TSC_MEASURE_Y: //counter the number of adc touch coord reads and jitter it after a while to simulate a shaky human hand or multiple reads + //this is actually important for some games.. seemingly due to bugs. nds.adc_jitterctr++; if(nds.adc_jitterctr == 25) { @@ -2584,16 +2592,24 @@ u32 DmaController::read32() static INLINE void write_auxspicnt(const int proc, const int size, const int adr, const int val) { //why val==0 to reset? is it a particular bit? its not bit 6... - switch(size) { + + switch(size) + { case 16: MMU.AUX_SPI_CNT = val; - if (val == 0) MMU_new.backupDevice.reset_command(); + if (val == 0) + { + //you know.. its strange. according to gbatek, this should get cleared before the last transfer. + //we've got it coded in such a way that it sort of terminates the transfer (is it getting reset immediately before a new transfer?) + slot1_device->auxspi_reset(proc); + } break; case 8: - switch(adr) { + switch(adr) + { case 0: T1WriteByte((u8*)&MMU.AUX_SPI_CNT, 0, val); - if (val == 0) MMU_new.backupDevice.reset_command(); + if (val == 0) slot1_device->auxspi_reset(proc); break; case 1: T1WriteByte((u8*)&MMU.AUX_SPI_CNT, 1, val); @@ -2811,10 +2827,13 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) return; case REG_AUXSPIDATA: - if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF; - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((u8)val,ARMCPU_ARM9)); + { + //if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF; //zero 20-aug-2013 - this seems pointless + u8 spidata = slot1_device->auxspi_transaction(ARMCPU_ARM9,(u8)val); + T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, spidata); MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag return; + } case REG_POWCNT1: writereg_POWCNT1(8,adr,val); break; @@ -3165,13 +3184,13 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) return; case REG_AUXSPIDATA: - if(val!=0) - MMU.AUX_SPI_CMD = val & 0xFF; - - //T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val)); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((u8)val,ARMCPU_ARM9)); + { + //if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF; //zero 20-aug-2013 - this seems pointless + u8 spidata = slot1_device->auxspi_transaction(ARMCPU_ARM9,(u8)val); + T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, spidata); MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag return; + } case REG_DISPA_BG0CNT : //GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val); @@ -4199,10 +4218,13 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val) return; case REG_AUXSPIDATA: - 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)); + { + //if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF; //zero 20-aug-2013 - this seems pointless + u8 spidata = slot1_device->auxspi_transaction(ARMCPU_ARM7,(u8)val); + T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, spidata); MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag return; + } case REG_SPIDATA: // CrazyMax: 27 May 2013: BIOS write 8bit commands to flash controller when load firmware header @@ -4304,13 +4326,13 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) return; case REG_AUXSPIDATA: - if(val!=0) - MMU.AUX_SPI_CMD = val & 0xFF; - - //T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, bm_transfer(&MMU.bupmem, val)); - T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, MMU_new.backupDevice.data_command((u8)val,ARMCPU_ARM7)); + { + //if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF; //zero 20-aug-2013 - this seems pointless + u8 spidata = slot1_device->auxspi_transaction(ARMCPU_ARM7,(u8)val); + T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][(REG_AUXSPIDATA >> 20) & 0xff], REG_AUXSPIDATA & 0xfff, spidata); MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag - return; + return; + } case REG_SPICNT : { diff --git a/desmume/src/MMU.h b/desmume/src/MMU.h index 062ce1eca..a69e0d03d 100644 --- a/desmume/src/MMU.h +++ b/desmume/src/MMU.h @@ -27,6 +27,7 @@ #include "bits.h" #include "readwrite.h" #include "debug.h" +#include "firmware.h" #ifdef HAVE_LUA #include "lua-engine.h" @@ -419,7 +420,7 @@ struct MMU_struct u16 SPI_CNT; u16 SPI_CMD; u16 AUX_SPI_CNT; - u16 AUX_SPI_CMD; + //u16 AUX_SPI_CMD; //zero 20-aug-2013 - this seems pointless u8 WRAMCNT; @@ -429,7 +430,7 @@ struct MMU_struct BOOL powerMan_CntRegWritten; u8 powerMan_Reg[5]; - memory_chip_t fw; + fw_memory_chip fw; nds_dscard dscard[2]; }; diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index 1823bb93d..52a896458 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -43,6 +43,7 @@ libdesmume_a_SOURCES = \ shaders.h \ movie.cpp movie.h \ PACKED.h PACKED_END.h \ + utils/advanscene.cpp utils/advanscene.h \ utils/datetime.cpp utils/datetime.h \ utils/ConvertUTF.c utils/ConvertUTF.h utils/guid.cpp utils/guid.h \ utils/emufat.cpp utils/emufat.h utils/emufat_types.h \ @@ -86,7 +87,7 @@ libdesmume_a_SOURCES = \ utils/tinyxml/tinyxmlerror.cpp \ utils/tinyxml/tinyxmlparser.cpp \ addons.cpp addons.h \ - addons/slot2_mpcf.cpp addons/slot2_paddle.cpp addons/slot2_gbagame.cpp addons/slot2_none.cpp addons/slot2_rumblepak.cpp addons/slot2_guitarGrip.cpp addons/slot2_expMemory.cpp addons/slot2_piano.cpp addons/slot1_none.cpp addons/slot1_r4.cpp addons/slot1_retail.cpp addons/slot1_retail_nand.cpp \ + addons/slot2_mpcf.cpp addons/slot2_paddle.cpp addons/slot2_gbagame.cpp addons/slot2_none.cpp addons/slot2_rumblepak.cpp addons/slot2_guitarGrip.cpp addons/slot2_expMemory.cpp addons/slot2_piano.cpp addons/slot1_none.cpp addons/slot1_r4.cpp addons/slot1_retail_nand.cpp addons/slot1_retail_auto.cpp addons/slot1_retail_mcrom.cpp addons/slot1comp_mc.cpp addons/slot1comp_mc.h addons/slot1comp_rom.h addons/slot1comp_rom.cpp \ cheatSystem.cpp cheatSystem.h \ texcache.cpp texcache.h rasterize.cpp rasterize.h \ metaspu/metaspu.cpp metaspu/metaspu.h \ diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 3a7cd560a..23d27c466 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -30,6 +30,7 @@ #include "gfx3d.h" #include "utils/decrypt/decrypt.h" #include "utils/decrypt/crc.h" +#include "utils/advanscene.h" #include "cp15.h" #include "bios.h" #include "debug.h" @@ -41,7 +42,6 @@ #include "firmware.h" #include "version.h" #include "slot1.h" - #include "path.h" //int xxctr=0; @@ -69,7 +69,6 @@ static u8 countLid = 0; GameInfo gameInfo; NDSSystem nds; CFIRMWARE *firmware = NULL; -ADVANsCEne advsc; using std::min; using std::max; @@ -607,7 +606,8 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi INFO("ROM internal name: %s\n", gameInfo.ROMname); INFO("ROM developer: %s\n", getDeveloperNameByID(gameInfo.header.makerCode).c_str()); - gameInfo.storeSecureArea(); + //crazymax: how would it have got whacked? dont think we need this + //gameInfo.storeSecureArea(); memset(buf, 0, MAX_PATH); strcpy(buf, path.pathToModule); diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 43a400cd5..444f2336b 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -666,7 +666,8 @@ void ClearAutoHold(void); bool ValidateSlot2Access(u32 procnum, u32 demandSRAMSpeed, u32 demand1stROMSpeed, u32 demand2ndROMSpeed, int clockbits); -extern ADVANsCEne advsc; +//MUSTANG +//extern ADVANsCEne advsc; #endif diff --git a/desmume/src/addons/slot1_r4.cpp b/desmume/src/addons/slot1_r4.cpp index 700f46656..e1dc8ab29 100644 --- a/desmume/src/addons/slot1_r4.cpp +++ b/desmume/src/addons/slot1_r4.cpp @@ -40,7 +40,7 @@ public: virtual Slot1Info const* info() { - static Slot1InfoSimple info("R4","Slot1 R4 Emulation"); + static Slot1InfoSimple info("R4","Slot1 R4 emulation"); return &info; } diff --git a/desmume/src/addons/slot1_retail_auto.cpp b/desmume/src/addons/slot1_retail_auto.cpp new file mode 100644 index 000000000..aa152d2fb --- /dev/null +++ b/desmume/src/addons/slot1_retail_auto.cpp @@ -0,0 +1,186 @@ +/* + Copyright (C) 2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +#include "../slot1.h" +#include "../registers.h" +#include "../MMU.h" +#include "../NDSSystem.h" + +class Slot1_Retail_Auto : public ISlot1Interface +{ +private: + ISlot1Interface *mSelectedImplementation; + +public: + Slot1_Retail_Auto() + : mSelectedImplementation(NULL) + { + } + + virtual Slot1Info const* info() + { + static Slot1InfoSimple info("Retail (Auto)","Slot1 Retail (auto-selection) card emulation"); + return &info; + } + + virtual void connect() + { + //TODO - check game ID in core emulator and select right implementation + mSelectedImplementation = slot1_List[NDS_SLOT1_RETAIL_MCROM]; + } + + virtual void disconnect() + { + mSelectedImplementation = NULL; + } + + virtual void write32(u8 PROCNUM, u32 adr, u32 val) + { + mSelectedImplementation->write32(PROCNUM, adr, val); + } + + virtual u32 read32(u8 PROCNUM, u32 adr) + { + return mSelectedImplementation->read32(PROCNUM, adr); + } + + virtual u8 auxspi_transaction(int PROCNUM, u8 value) + { + return mSelectedImplementation->auxspi_transaction(PROCNUM, value); + } + + virtual void auxspi_reset(int PROCNUM) + { + mSelectedImplementation->auxspi_reset(PROCNUM); + } +}; + +ISlot1Interface* construct_Slot1_Retail_Auto() { return new Slot1_Retail_Auto(); } + + // ///writetoGCControl: + //// --- Ninja SD commands ------------------------------------- + + // // NJSD init/reset + // case 0x20: + // { + // card.address = 0; + // card.transfer_count = 0; + // } + // break; + + // // NJSD_sendCLK() + // case 0xE0: + // { + // card.address = 0; + // card.transfer_count = 0; + // NDS_makeInt(PROCNUM, 20); + // } + // break; + + // // NJSD_sendCMDN() / NJSD_sendCMDR() + // case 0xF0: + // case 0xF1: + // switch (card.command[2]) + // { + // // GO_IDLE_STATE + // case 0x40: + // card.address = 0; + // card.transfer_count = 0; + // NDS_makeInt(PROCNUM, 20); + // break; + + // case 0x42: // ALL_SEND_CID + // case 0x43: // SEND_RELATIVE_ADDR + // case 0x47: // SELECT_CARD + // case 0x49: // SEND_CSD + // case 0x4D: + // case 0x77: // APP_CMD + // case 0x69: // SD_APP_OP_COND + // card.address = 0; + // card.transfer_count = 6; + // NDS_makeInt(PROCNUM, 20); + // break; + + // // SET_BLOCKLEN + // case 0x50: + // card.address = 0; + // card.transfer_count = 6; + // card.blocklen = card.command[6] | (card.command[5] << 8) | (card.command[4] << 16) | (card.command[3] << 24); + // NDS_makeInt(PROCNUM, 20); + // break; + + // // READ_SINGLE_BLOCK + // case 0x51: + // card.address = card.command[6] | (card.command[5] << 8) | (card.command[4] << 16) | (card.command[3] << 24); + // card.transfer_count = (card.blocklen + 3) >> 2; + // NDS_makeInt(PROCNUM, 20); + // break; + // } + // break; + + // // --- Ninja SD commands end --------------------------------- + + + + // //GCDATAIN: + // // --- Ninja SD commands ------------------------------------- + + // // NJSD_sendCMDN() / NJSD_sendCMDR() + // case 0xF0: + // case 0xF1: + // switch (card.command[2]) + // { + // // ALL_SEND_CID + // case 0x42: + // if (card.transfer_count == 2) val = 0x44534A4E; + // else val = 0x00000000; + + // // SEND_RELATIVE_ADDR + // case 0x43: + // case 0x47: + // case 0x49: + // case 0x50: + // val = 0x00000000; + // break; + + // case 0x4D: + // if (card.transfer_count == 2) val = 0x09000000; + // else val = 0x00000000; + // break; + + // // APP_CMD + // case 0x77: + // if (card.transfer_count == 2) val = 0x00000037; + // else val = 0x00000000; + // break; + + // // SD_APP_OP_COND + // case 0x69: + // if (card.transfer_count == 2) val = 0x00008000; + // else val = 0x00000000; + // break; + + // // READ_SINGLE_BLOCK + // case 0x51: + // val = 0x00000000; + // break; + // } + // break; + + // // --- Ninja SD commands end --------------------------------- + + diff --git a/desmume/src/addons/slot1_retail.cpp b/desmume/src/addons/slot1_retail_mcrom.cpp similarity index 90% rename from desmume/src/addons/slot1_retail.cpp rename to desmume/src/addons/slot1_retail_mcrom.cpp index 813e15549..dc75cf3f2 100644 --- a/desmume/src/addons/slot1_retail.cpp +++ b/desmume/src/addons/slot1_retail_mcrom.cpp @@ -19,13 +19,15 @@ #include "../registers.h" #include "../MMU.h" #include "../NDSSystem.h" +#include "slot1comp_mc.h" +#include "slot1comp_rom.h" -class Slot1_Retail : public ISlot1Interface +class Slot1_Retail_MCROM : public ISlot1Interface { public: virtual Slot1Info const* info() { - static Slot1InfoSimple info("Retail","Slot1 Retail card emulation"); + static Slot1InfoSimple info("Retail MC+ROM","Slot1 Retail MC+ROM (standard) card emulation"); return &info; } @@ -55,6 +57,16 @@ public: } } + virtual u8 auxspi_transaction(int PROCNUM, u8 value) + { + return g_Slot1Comp_MC.auxspi_transaction(PROCNUM,value); + } + + virtual void auxspi_reset(int PROCNUM) + { + g_Slot1Comp_MC.auxspi_reset(PROCNUM); + } + private: u32 read32_GCDATAIN(u8 PROCNUM) @@ -199,7 +211,7 @@ private: }; -ISlot1Interface* construct_Slot1_Retail() { return new Slot1_Retail(); } +ISlot1Interface* construct_Slot1_Retail_MCROM() { return new Slot1_Retail_MCROM(); } // ///writetoGCControl: //// --- Ninja SD commands ------------------------------------- diff --git a/desmume/src/addons/slot1_retail_nand.cpp b/desmume/src/addons/slot1_retail_nand.cpp index 8dfaca39b..5ddde4a49 100644 --- a/desmume/src/addons/slot1_retail_nand.cpp +++ b/desmume/src/addons/slot1_retail_nand.cpp @@ -25,7 +25,7 @@ class Slot1_Retail_NAND : public ISlot1Interface public: virtual Slot1Info const* info() { - static Slot1InfoSimple info("Retail+NAND","Slot1 Retail NAND card emulation"); + static Slot1InfoSimple info("Retail NAND","Slot1 retail NAND card emulation"); return &info; } diff --git a/desmume/src/addons/slot1comp_mc.cpp b/desmume/src/addons/slot1comp_mc.cpp new file mode 100644 index 000000000..3aec7455a --- /dev/null +++ b/desmume/src/addons/slot1comp_mc.cpp @@ -0,0 +1,35 @@ +/* + Copyright (C) 2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +//this file contains the components used for emulating standard gamecard "MC" devices (eeprom, fram, flash) +//this is largely done by accessing the BackupDevice resources in the core emulator + +#include "types.h" +#include "mmu.h" +#include "slot1comp_mc.h" + +Slot1Comp_MC g_Slot1Comp_MC; + +u8 Slot1Comp_MC::auxspi_transaction(int PROCNUM, u8 value) +{ + return MMU_new.backupDevice.data_command((u8)value,ARMCPU_ARM9); +} +void Slot1Comp_MC::auxspi_reset(int PROCNUM) +{ + MMU_new.backupDevice.reset_command(); +} + diff --git a/desmume/src/addons/slot1comp_mc.h b/desmume/src/addons/slot1comp_mc.h new file mode 100644 index 000000000..e5dfe4f00 --- /dev/null +++ b/desmume/src/addons/slot1comp_mc.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +//this file contains the components used for emulating standard gamecard "MC" devices (eeprom, fram, flash) + +class Slot1Comp_MC +{ +public: + u8 auxspi_transaction(int PROCNUM, u8 value); + void auxspi_reset(int PROCNUM); +}; + +extern Slot1Comp_MC g_Slot1Comp_MC; \ No newline at end of file diff --git a/desmume/src/addons/slot1comp_rom.cpp b/desmume/src/addons/slot1comp_rom.cpp new file mode 100644 index 000000000..79e0d770e --- /dev/null +++ b/desmume/src/addons/slot1comp_rom.cpp @@ -0,0 +1,17 @@ +/* + Copyright (C) 2010-2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + diff --git a/desmume/src/addons/slot1comp_rom.h b/desmume/src/addons/slot1comp_rom.h new file mode 100644 index 000000000..711bac511 --- /dev/null +++ b/desmume/src/addons/slot1comp_rom.h @@ -0,0 +1,21 @@ +/* + Copyright (C) 2010-2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +//this file contains the components used for emulating standard gamecard ROMs +//this is largely done by accessing the rom resource in the cor eemulator + +//(TBD) \ No newline at end of file diff --git a/desmume/src/bios.cpp b/desmume/src/bios.cpp index 29671946a..c21641d03 100644 --- a/desmume/src/bios.cpp +++ b/desmume/src/bios.cpp @@ -652,6 +652,10 @@ TEMPLATE static u32 RLUnCompVram() TEMPLATE static u32 RLUnCompWram() { + //this routine is used by yoshi touch&go from the very beginning + + printf("RLUnCompWram\n"); + int i; int len; u32 source = cpu->R[0]; @@ -695,6 +699,8 @@ TEMPLATE static u32 RLUnCompWram() TEMPLATE static u32 UnCompHuffman() { + //this routine is used by the nintendo logo in the firmware boot screen + u32 source, dest, writeValue, header, treeStart, mask; u32 data; u8 treeSize, currentNode, rootNode; diff --git a/desmume/src/commandline.cpp b/desmume/src/commandline.cpp index 7c184208e..7749243ff 100644 --- a/desmume/src/commandline.cpp +++ b/desmume/src/commandline.cpp @@ -297,10 +297,14 @@ void CommandLine::process_addonCommands() slot1_SetFatDir(slot1_fat_dir); if(slot1 == "RETAIL") - slot1_Change(NDS_SLOT1_RETAIL); + slot1_Change(NDS_SLOT1_RETAIL_AUTO); + else if(slot1 == "RETAILAUTO") + slot1_Change(NDS_SLOT1_RETAIL_AUTO); else if(slot1 == "R4") slot1_Change(NDS_SLOT1_R4); else if(slot1 == "RETAILNAND") slot1_Change(NDS_SLOT1_RETAIL_NAND); + else if(slot1 == "RETAILMCROM") + slot1_Change(NDS_SLOT1_RETAIL_MCROM); } diff --git a/desmume/src/firmware.cpp b/desmume/src/firmware.cpp index f33c2d7c3..c36c0b012 100644 --- a/desmume/src/firmware.cpp +++ b/desmume/src/firmware.cpp @@ -910,3 +910,190 @@ void NDS_PatchFirmwareMAC() memcpy((MMU.fw.data + 0x36), FW_Mac, sizeof(FW_Mac)); (*(u16*)(MMU.fw.data + 0x2A)) = calc_CRC16(0, (MMU.fw.data + 0x2C), 0x138); } + +//========================= +//- firmware SPI chip interface - +//the original intention was for this code to have similarity to the AUXSPI backup memory devices. +//however, that got overgrown, and this stuff stayed pretty simple. +//perhaps it can be re-defined in terms of a simpler AUXSPI device after the AUXSPI devices are re-designed. + +#define FW_CMD_READ 0x03 +#define FW_CMD_WRITEDISABLE 0x04 +#define FW_CMD_READSTATUS 0x05 +#define FW_CMD_WRITEENABLE 0x06 +#define FW_CMD_PAGEWRITE 0x0A +#define FW_CMD_READ_ID 0x9F + +void fw_reset_com(fw_memory_chip *mc) +{ + if(mc->com == FW_CMD_PAGEWRITE) + { + if (mc->fp) + { + fseek(mc->fp, 0, SEEK_SET); + fwrite(mc->data, mc->size, 1, mc->fp); + } + + if (mc->isFirmware && CommonSettings.UseExtFirmware && CommonSettings.UseExtFirmwareSettings && firmware) + { + firmware->saveSettings(); + } + mc->write_enable = FALSE; + } + + mc->com = 0; +} + +u8 fw_transfer(fw_memory_chip *mc, u8 data) +{ + if(mc->com == FW_CMD_READ || mc->com == FW_CMD_PAGEWRITE) /* check if we are in a command that needs 3 bytes address */ + { + if(mc->addr_shift > 0) /* if we got a complete address */ + { + mc->addr_shift--; + mc->addr |= data << (mc->addr_shift * 8); /* argument is a byte of address */ + } + else /* if we have received 3 bytes of address, proceed command */ + { + switch(mc->com) + { + case FW_CMD_READ: + if(mc->addr < mc->size) /* check if we can read */ + { + data = mc->data[mc->addr]; /* return byte */ + mc->addr++; /* then increment address */ + } + break; + + case FW_CMD_PAGEWRITE: + if(mc->addr < mc->size) + { + mc->data[mc->addr] = data; /* write byte */ + mc->addr++; + } + break; + } + + } + } + else if(mc->com == FW_CMD_READ_ID) + { + switch(mc->addr) + { + //here is an ID string measured from an old ds fat: 62 16 00 (0x62=sanyo) + //but we chose to use an ST from martin's ds fat string so programs might have a clue as to the firmware size: + //20 40 12 + case 0: + data = 0x20; + mc->addr=1; + break; + case 1: + data = 0x40; //according to gbatek this is the device ID for the flash on someone's ds fat + mc->addr=2; + break; + case 2: + data = 0x12; + mc->addr = 0; + break; + } + } + else if(mc->com == FW_CMD_READSTATUS) + { + return (mc->write_enable ? 0x02 : 0x00); + } + else //finally, check if it's a new command + { + switch(data) + { + case 0: break; //nothing + + case FW_CMD_READ_ID: + mc->addr = 0; + mc->com = FW_CMD_READ_ID; + break; + + case FW_CMD_READ: //read command + mc->addr = 0; + mc->addr_shift = 3; + mc->com = FW_CMD_READ; + break; + + case FW_CMD_WRITEENABLE: //enable writing + if(mc->writeable_buffer) { mc->write_enable = TRUE; } + break; + + case FW_CMD_WRITEDISABLE: //disable writing + mc->write_enable = FALSE; + break; + + case FW_CMD_PAGEWRITE: //write command + if(mc->write_enable) + { + mc->addr = 0; + mc->addr_shift = 3; + mc->com = FW_CMD_PAGEWRITE; + } + else { data = 0; } + break; + + case FW_CMD_READSTATUS: //status register command + mc->com = FW_CMD_READSTATUS; + break; + + default: + printf("Unhandled FW command: %02X\n", data); + break; + } + } + + return data; +} + + +void mc_init(fw_memory_chip *mc, int type) +{ + mc->com = 0; + mc->addr = 0; + mc->addr_shift = 0; + mc->data = NULL; + mc->size = 0; + mc->write_enable = FALSE; + mc->writeable_buffer = FALSE; + mc->type = type; + + switch(mc->type) + { + case MC_TYPE_EEPROM1: + mc->addr_size = 1; + break; + case MC_TYPE_EEPROM2: + case MC_TYPE_FRAM: + mc->addr_size = 2; + break; + case MC_TYPE_FLASH: + mc->addr_size = 3; + break; + default: break; + } +} + +u8 *mc_alloc(fw_memory_chip *mc, u32 size) +{ + u8 *buffer = NULL; + buffer = new u8[size]; + if(!buffer) { return NULL; } + memset(buffer,0,size); + + if (mc->data) delete [] mc->data; + mc->data = buffer; + mc->size = size; + mc->writeable_buffer = TRUE; + + return buffer; +} + +void mc_free(fw_memory_chip *mc) +{ + if(mc->data) delete[] mc->data; + mc_init(mc, 0); +} diff --git a/desmume/src/firmware.h b/desmume/src/firmware.h index 13d38459a..72c387903 100644 --- a/desmume/src/firmware.h +++ b/desmume/src/firmware.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2009-2011 DeSmuME Team + Copyright (C) 2009-2013 DeSmuME Team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,8 +19,13 @@ #define _FIRMWARE_H_ #include "common.h" -// the count of bytes copied from the firmware into memory +#define NDS_FW_SIZE_V1 (256 * 1024) /* size of fw memory on nds v1 */ +#define NDS_FW_SIZE_V2 (512 * 1024) /* size of fw memory on nds v2 */ + +// the count of bytes (user settings) copied from the firmware into memory (for easy access) during the firmware boot process #define NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT 0x70 + +//extension of the firmware user settings file #define FW_CONFIG_FILE_EXT "dfc" class CFIRMWARE @@ -84,5 +89,35 @@ int NDS_CreateDummyFirmware( struct NDS_fw_config_data *user_settings); void NDS_FillDefaultFirmwareConfigData( struct NDS_fw_config_data *fw_config); void NDS_PatchFirmwareMAC(); +struct fw_memory_chip +{ + u8 com; //persistent command actually handled + u32 addr; //current address for reading/writing + u8 addr_shift; //shift for address (since addresses are transfered by 3 bytes units) + u8 addr_size; //size of addr when writing/reading + + BOOL write_enable; //is write enabled ? + + u8 *data; //memory data + u32 size; //memory size + BOOL writeable_buffer; //is "data" writeable ? + int type; //type of Memory + char *filename; + FILE *fp; + + // needs only for firmware + bool isFirmware; + char userfile[MAX_PATH]; +}; + + +void fw_reset_com(fw_memory_chip *mc); +u8 fw_transfer(fw_memory_chip *mc, u8 data); +void mc_init(fw_memory_chip *mc, int type); /* reset and init values for memory struct */ +u8 *mc_alloc(fw_memory_chip *mc, u32 size); /* alloc mc memory */ +void mc_realloc(fw_memory_chip *mc, int type, u32 size); /* realloc mc memory */ +void mc_load_file(fw_memory_chip *mc, const char* filename); /* load save file and setup fp */ +void mc_free(fw_memory_chip *mc); /* delete mc memory */ + #endif diff --git a/desmume/src/mc.cpp b/desmume/src/mc.cpp index 331264101..369bd4764 100644 --- a/desmume/src/mc.cpp +++ b/desmume/src/mc.cpp @@ -19,28 +19,15 @@ #include #include -#include "debug.h" + #include "types.h" +#include "debug.h" #include "mc.h" #include "movie.h" #include "readwrite.h" #include "NDSSystem.h" -#define TIXML_USE_STL -#include "utils/tinyxml/tinyxml.h" +#include "utils/advanscene.h" -//temporary hack until we have better error reporting facilities -#ifdef _WINDOWS -#include -#elif defined(_XBOX) -#include // it`s really need? -#endif - -#define FW_CMD_READ 0x03 -#define FW_CMD_WRITEDISABLE 0x04 -#define FW_CMD_READSTATUS 0x05 -#define FW_CMD_WRITEENABLE 0x06 -#define FW_CMD_PAGEWRITE 0x0A -#define FW_CMD_READ_ID 0x9F #define BM_CMD_AUTODETECT 0xFF #define BM_CMD_WRITESTATUS 0x01 @@ -52,7 +39,7 @@ #define BM_CMD_WRITEHIGH 0x0A #define BM_CMD_READHIGH 0x0B -/* FLASH*/ +//FLASH #define COMM_PAGE_WRITE 0x0A #define COMM_PAGE_ERASE 0xDB #define COMM_SECTOR_ERASE 0xD8 @@ -65,7 +52,7 @@ //but baby pals proves finally that it should be 0xFF: //the game reads its initial sound volumes from uninitialized data, and if it is 0, the game will be silent //if it is 0xFF then the game starts with its sound and music at max, as presumably it is supposed to. -//so in r3303 I finally changed it (no$ appears definitely to initialized to 0xFF) +//so in r3303 I finally changed it (no$ appears definitely to initialize to 0xFF) static const u8 kUninitializedSaveDataValue = 0xFF; static const char* kDesmumeSaveCookie = "|-DESMUME SAVE-|"; @@ -117,180 +104,6 @@ void backup_setManualBackupType(int type) CommonSettings.manualBackupType = type; } -void mc_init(memory_chip_t *mc, int type) -{ - mc->com = 0; - mc->addr = 0; - mc->addr_shift = 0; - mc->data = NULL; - mc->size = 0; - mc->write_enable = FALSE; - mc->writeable_buffer = FALSE; - mc->type = type; - mc->autodetectsize = 0; - - switch(mc->type) - { - case MC_TYPE_EEPROM1: - mc->addr_size = 1; - break; - case MC_TYPE_EEPROM2: - case MC_TYPE_FRAM: - mc->addr_size = 2; - break; - case MC_TYPE_FLASH: - mc->addr_size = 3; - break; - default: break; - } -} - -u8 *mc_alloc(memory_chip_t *mc, u32 size) -{ - u8 *buffer = NULL; - buffer = new u8[size]; - if(!buffer) { return NULL; } - memset(buffer,0,size); - - if (mc->data) delete [] mc->data; - mc->data = buffer; - mc->size = size; - mc->writeable_buffer = TRUE; - - return buffer; -} - -void mc_free(memory_chip_t *mc) -{ - if(mc->data) delete[] mc->data; - mc_init(mc, 0); -} - -void fw_reset_com(memory_chip_t *mc) -{ - if(mc->com == FW_CMD_PAGEWRITE) - { - if (mc->fp) - { - fseek(mc->fp, 0, SEEK_SET); - fwrite(mc->data, mc->size, 1, mc->fp); - } - - if (mc->isFirmware && CommonSettings.UseExtFirmware && CommonSettings.UseExtFirmwareSettings && firmware) - { - firmware->saveSettings(); - } - mc->write_enable = FALSE; - } - - mc->com = 0; -} - -u8 fw_transfer(memory_chip_t *mc, u8 data) -{ - if(mc->com == FW_CMD_READ || mc->com == FW_CMD_PAGEWRITE) /* check if we are in a command that needs 3 bytes address */ - { - if(mc->addr_shift > 0) /* if we got a complete address */ - { - mc->addr_shift--; - mc->addr |= data << (mc->addr_shift * 8); /* argument is a byte of address */ - } - else /* if we have received 3 bytes of address, proceed command */ - { - switch(mc->com) - { - case FW_CMD_READ: - if(mc->addr < mc->size) /* check if we can read */ - { - data = mc->data[mc->addr]; /* return byte */ - mc->addr++; /* then increment address */ - } - break; - - case FW_CMD_PAGEWRITE: - if(mc->addr < mc->size) - { - mc->data[mc->addr] = data; /* write byte */ - mc->addr++; - } - break; - } - - } - } - else if(mc->com == FW_CMD_READ_ID) - { - switch(mc->addr) - { - //here is an ID string measured from an old ds fat: 62 16 00 (0x62=sanyo) - //but we chose to use an ST from martin's ds fat string so programs might have a clue as to the firmware size: - //20 40 12 - case 0: - data = 0x20; - mc->addr=1; - break; - case 1: - data = 0x40; //according to gbatek this is the device ID for the flash on someone's ds fat - mc->addr=2; - break; - case 2: - data = 0x12; - mc->addr = 0; - break; - } - } - else if(mc->com == FW_CMD_READSTATUS) - { - return (mc->write_enable ? 0x02 : 0x00); - } - else //finally, check if it's a new command - { - switch(data) - { - case 0: break; //nothing - - case FW_CMD_READ_ID: - mc->addr = 0; - mc->com = FW_CMD_READ_ID; - break; - - case FW_CMD_READ: //read command - mc->addr = 0; - mc->addr_shift = 3; - mc->com = FW_CMD_READ; - break; - - case FW_CMD_WRITEENABLE: //enable writing - if(mc->writeable_buffer) { mc->write_enable = TRUE; } - break; - - case FW_CMD_WRITEDISABLE: //disable writing - mc->write_enable = FALSE; - break; - - case FW_CMD_PAGEWRITE: //write command - if(mc->write_enable) - { - mc->addr = 0; - mc->addr_shift = 3; - mc->com = FW_CMD_PAGEWRITE; - } - else { data = 0; } - break; - - case FW_CMD_READSTATUS: //status register command - mc->com = FW_CMD_READSTATUS; - break; - - default: - printf("Unhandled FW command: %02X\n", data); - break; - } - } - - return data; -} - bool BackupDevice::save_state(EMUFILE* os) { u32 version = 2; @@ -1319,225 +1132,3 @@ void BackupDevice::forceManualBackupType() addr_size = addr_size_for_old_save_size(save_types[CommonSettings.manualBackupType].size); state = RUNNING; } - -// ============================================= ADVANsCEne -u8 ADVANsCEne::checkDB(const char *serial, u32 crc) -{ - loaded = false; - FILE *fp = fopen(database_path, "rb"); - if (fp) - { - char buf[64]; - memset(buf, 0, sizeof(buf)); - if (fread(buf, 1, strlen(_ADVANsCEne_BASE_ID), fp) == strlen(_ADVANsCEne_BASE_ID)) - { - //printf("ID: %s\n", buf); - if (strcmp(buf, _ADVANsCEne_BASE_ID) == 0) - { - if (fread(&versionBase[0], 1, 2, fp) == 2) - { - //printf("Version base: %i.%i\n", versionBase[0], versionBase[1]); - if (fread(&version[0], 1, 4, fp) == 4) - { - //printf("Version: %c%c%c%c\n", version[3], version[2], version[1], version[0]); - if (fread(&createTime, 1, sizeof(time_t), fp) == sizeof(time_t)) - { - memset(buf, 0,sizeof(buf)); - // serial(8) + crc32(4) + save_type(1) = 13 + reserved(8) = 21 - while (true) - { - if (fread(buf, 1, 21, fp) != 21) break; - - bool serialFound = (memcmp(&buf[4], serial, 4) == 0); - u32 dbcrc = LE_TO_LOCAL_32(*(u32*)(buf+8)); - bool crcFound = (crc == dbcrc); - - if(serialFound || crcFound) - { - foundAsCrc = crcFound; - foundAsSerial = serialFound; - memcpy(&crc32, &buf[8], 4); - //printf("%s founded: crc32=%04X, save type %02X\n", serial, crc32, buf[12]); - saveType = buf[12]; - fclose(fp); - loaded = true; - return true; - } - } - } - } - } - } - } - fclose(fp); - } - return false; -} - - - -bool ADVANsCEne::getXMLConfig(const char *in_filaname) -{ - TiXmlDocument *xml = NULL; - TiXmlElement *el = NULL; - TiXmlElement *el_configuration = NULL; - TiXmlElement *el_newDat = NULL; - - xml = new TiXmlDocument(); - if (!xml) return false; - if (!xml->LoadFile(in_filaname)) return false; - el = xml->FirstChildElement("dat"); - if (!el) return false; - el_configuration = el->FirstChildElement("configuration"); - if (!el_configuration) return false; - el = el_configuration->FirstChildElement("datName"); if (el) { datName = el->GetText() ? el->GetText() : ""; } - el = el_configuration->FirstChildElement("datVersion"); if (el) { datVersion = el->GetText() ? el->GetText() : ""; } - - el_newDat = el_configuration->FirstChildElement("newDat"); - if (!el_newDat) return false; - el = el_newDat->FirstChildElement("datVersionURL"); if (el) { urlVersion = el->GetText() ? el->GetText() : ""; } - el = el_newDat->FirstChildElement("datURL"); if (el) { urlDat = el->GetText() ? el->GetText() : ""; } - - delete xml; - return true; -} - -u32 ADVANsCEne::convertDB(const char *in_filaname) -{ - //these strings are contained in the xml file, verbatim, so they function as enum values - //we leave the strings here rather than pooled elsewhere to remind us that theyre part of the advanscene format. - const char *saveTypeNames[] = { - "Eeprom - 4 kbit", // EEPROM 4kbit - "Eeprom - 64 kbit", // EEPROM 64kbit - "Eeprom - 512 kbit", // EEPROM 512kbit - "Fram - 256 kbit", // FRAM 256kbit ! - "Flash - 2 mbit", // FLASH 2Mbit - "Flash - 4 mbit", // FLASH 4Mbit - "Flash - 8 mbit", // FLASH 8Mbit - "Flash - 16 mbit", // FLASH 16Mbit ! - "Flash - 32 mbit", // FLASH 32Mbit ! - "Flash - 64 mbit", // FLASH 64Mbit - "Flash - 128 mbit", // FLASH 128Mbit ! - "Flash - 256 mbit", // FLASH 256Mbit ! - "Flash - 512 mbit" // FLASH 512Mbit ! - }; - - TiXmlDocument *xml = NULL; - TiXmlElement *el = NULL; - TiXmlElement *el_serial = NULL; - TiXmlElement *el_games = NULL; - TiXmlElement *el_crc32 = NULL; - TiXmlElement *el_saveType = NULL; - FILE *fp; - u32 crc32 = 0; - u32 reserved = 0; - - lastImportErrorMessage = ""; - - printf("Converting DB...\n"); - if (getXMLConfig(in_filaname)) - { - if (datName.size()==0) return 0; - if (datName != _ADVANsCEne_BASE_NAME) return 0; - } - - fp = fopen(database_path, "wb"); - if (!fp) return 0; - - // Header - fwrite(_ADVANsCEne_BASE_ID, 1, strlen(_ADVANsCEne_BASE_ID), fp); - fputc(_ADVANsCEne_BASE_VERSION_MAJOR, fp); - fputc(_ADVANsCEne_BASE_VERSION_MINOR, fp); - if (datVersion.size()) - fwrite(&datVersion[0], 1, datVersion.size(), fp); - else - fputc(0, fp); - time_t __time = time(NULL); - fwrite(&__time, 1, sizeof(time_t), fp); - - xml = new TiXmlDocument(); - if (!xml) { fclose(fp); return 0; } - if (!xml->LoadFile(in_filaname)) { fclose(fp); return 0; } - el = xml->FirstChildElement("dat"); - if (!el) { fclose(fp); return 0; } - el_games = el->FirstChildElement("games"); - if (!el_games) { fclose(fp); return 0; } - el = el_games->FirstChildElement("game"); - if (!el) { fclose(fp); return 0; } - u32 count = 0; - while (el) - { - TiXmlElement* title = el->FirstChildElement("title"); - if(title) - { - //just a little diagnostic - //printf("Importing %s\n",title->GetText()); - } - else { fclose(fp); return 0; } - - el_serial = el->FirstChildElement("serial"); - - if(!el_serial) - { - lastImportErrorMessage = "Missing element. Did you use the right xml file? We need the RtoolDS one."; - fclose(fp); - return 0; - } - if (fwrite(el_serial->GetText(), 1, 8, fp) != 8) - { - lastImportErrorMessage = "Error writing output file"; - fclose(fp); return 0; - } - - - // CRC32 - el_crc32 = el->FirstChildElement("files"); - sscanf_s(el_crc32->FirstChildElement("romCRC")->GetText(), "%x", &crc32); - if (fwrite(&crc32, 1, sizeof(u32), fp) != sizeof(u32)) - { - fclose(fp); return 0; - } - // Save type - el_saveType = el->FirstChildElement("saveType"); - if (el_saveType) - { - const char *tmp = el_saveType->GetText(); - if (tmp) - { - if (strcmp(tmp, "None") == 0) - fputc(0xFE, fp); - else - { - bool bUnknown = true; - for (u8 i = 0; i < MAX_SAVE_TYPES; i++) - { - if (strcmp(saveTypeNames[i], "") == 0) continue; - if (strcasecmp(tmp, saveTypeNames[i]) == 0) - { - fputc(i, fp); - bUnknown = false; - break; - } - } - if (bUnknown) - fputc(0xFF, fp); // Unknown - } - } - else - fputc(0xFF, fp); // Unknown - } - fwrite(&reserved, 1, sizeof(u32), fp); - fwrite(&reserved, 1, sizeof(u32), fp); - count++; - el = el->NextSiblingElement("game"); - } - printf("\n"); - delete xml; - fclose(fp); - if (count > 0) - printf("done\n"); - else - printf("error\n"); - printf("ADVANsCEne converter: %i found\n", count); - return count; -} diff --git a/desmume/src/mc.h b/desmume/src/mc.h index d72c71f0a..a25fb914d 100644 --- a/desmume/src/mc.h +++ b/desmume/src/mc.h @@ -17,8 +17,8 @@ along with the this software. If not, see . */ -#ifndef __FW_H__ -#define __FW_H__ +#ifndef __MC_H__ +#define __MC_H__ #include #include @@ -50,78 +50,11 @@ #define MC_SIZE_256MBITS 0x2000000 #define MC_SIZE_512MBITS 0x4000000 -// ============================================= ADVANsCEne -#define _ADVANsCEne_BASE_ID "DeSmuME database (ADVANsCEne)\0x1A" -#define _ADVANsCEne_BASE_VERSION_MAJOR 1 -#define _ADVANsCEne_BASE_VERSION_MINOR 0 -#define _ADVANsCEne_BASE_NAME "ADVANsCEne Nintendo DS Collection" -class ADVANsCEne -{ -private: - char database_path[MAX_PATH]; // DeSmuME save types - u8 versionBase[2]; - char version[4]; - time_t createTime; - u8 saveType; - u32 crc32; - bool loaded; - bool foundAsCrc, foundAsSerial; - // XML - std::string datName; - std::string datVersion; - std::string urlVersion; - std::string urlDat; - bool getXMLConfig(const char *in_filaname); - -public: - ADVANsCEne() : saveType(0xFF), - crc32(0), - loaded(false) - { - memset(database_path, 0, sizeof(database_path)); - memset(versionBase, 0, sizeof(versionBase)); - memset(version, 0, sizeof(version)); - } - void setDatabase(const char *path) { loaded = false; strcpy(database_path, path); } - u32 convertDB(const char *in_filaname); - u8 checkDB(const char *serial, u32 crc); - u32 getSaveType() { return saveType; } - u32 getCRC32() { return crc32; } - bool isLoaded() { return loaded; } - const char* getIdMethod() { - if(foundAsCrc) return "CRC"; - if(foundAsSerial) return "Serial"; - return ""; - } - std::string lastImportErrorMessage; -}; - - -struct memory_chip_t -{ - u8 com; //persistent command actually handled - u32 addr; //current address for reading/writing - u8 addr_shift; //shift for address (since addresses are transfered by 3 bytes units) - u8 addr_size; //size of addr when writing/reading - - BOOL write_enable; //is write enabled ? - - u8 *data; //memory data - u32 size; //memory size - BOOL writeable_buffer; //is "data" writeable ? - int type; //type of Memory - char *filename; - FILE *fp; - u8 autodetectbuf[32768]; - int autodetectsize; - - // needs only for firmware - bool isFirmware; - char userfile[MAX_PATH]; -}; - -//the new backup system by zeromus +//This "backup device" represents a typical retail NDS save memory accessible via AUXSPI. +//It is managed as a core emulator service for historical reasons which are bad, +//and possible infrastructural simplification reasons which are good. +//Slot-1 devices will map their AUXSPI accesses through to the core-managed BackupDevice to access it for the running software. class BackupDevice { public: @@ -219,16 +152,8 @@ private: void resize(u32 size); }; -#define NDS_FW_SIZE_V1 (256 * 1024) /* size of fw memory on nds v1 */ -#define NDS_FW_SIZE_V2 (512 * 1024) /* size of fw memory on nds v2 */ -void mc_init(memory_chip_t *mc, int type); /* reset and init values for memory struct */ -u8 *mc_alloc(memory_chip_t *mc, u32 size); /* alloc mc memory */ -void mc_realloc(memory_chip_t *mc, int type, u32 size); /* realloc mc memory */ -void mc_load_file(memory_chip_t *mc, const char* filename); /* load save file and setup fp */ -void mc_free(memory_chip_t *mc); /* delete mc memory */ -void fw_reset_com(memory_chip_t *mc); /* reset communication with mc */ -u8 fw_transfer(memory_chip_t *mc, u8 data); + void backup_setManualBackupType(int type); void backup_forceManualBackupType(); diff --git a/desmume/src/registers.h b/desmume/src/registers.h index 12cede928..0b37a0f9f 100644 --- a/desmume/src/registers.h +++ b/desmume/src/registers.h @@ -428,4 +428,13 @@ #define EXMEMCNT_MASK_SLOT2_ROM_2ND_TIME (1<<4) #define EXMEMCNT_MASK_SLOT2_CLOCKRATE (3<<5) +#define SPI_DEVICE_POWERMAN 0 +#define SPI_DEVICE_FIRMWARE 1 +#define SPI_DEVICE_TOUCHSCREEN 2 + +#define SPI_BAUDRATE_4MHZ 0 +#define SPI_BAUDRATE_2MHZ 1 +#define SPI_BAUDRATE_1MHZ 2 +#define SPI_BAUDRATE_512KHZ 3 + #endif diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index aa18c5441..b80891d1a 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -220,7 +220,7 @@ SFORMAT SF_MMU[]={ { "M_SX", 1, 2, &MMU.SPI_CNT}, { "M_SC", 1, 2, &MMU.SPI_CMD}, { "MASX", 1, 2, &MMU.AUX_SPI_CNT}, - { "MASC", 1, 2, &MMU.AUX_SPI_CMD}, + //{ "MASC", 1, 2, &MMU.AUX_SPI_CMD}, //zero 20-aug-2013 - this seems pointless { "MWRA", 1, 2, &MMU.WRAMCNT}, diff --git a/desmume/src/slot1.cpp b/desmume/src/slot1.cpp index 7467b2792..e06cd362f 100644 --- a/desmume/src/slot1.cpp +++ b/desmume/src/slot1.cpp @@ -15,6 +15,15 @@ along with the this software. If not, see . */ +/* +Notes for future development: +Despite gbatek's specifications contrariwise, GCDATAIN is writeable. R4 uses this for writes to the card. +Despite gbatek's specifications contrariwise, GCROMCTRL[30] can take a value of 1 to indicate that the GC bus transaction should be writes. +It is unclear what kicks GC bus transactions. It's possibly bit 31 of GCROMCTRL, but normmatt thinks he might have had to hack around that to make something work, and that it might just be any write to GCROMCTRL. +Since GCROMCTRL[26:24] can't represent 'data block size' of 1 or 2, it is assumed that transactions always happen in 4 byte pieces. +...so, any 8/16bit accesses to GCDATAIN would transfer a whole 32bit unit and then just return the requested portion +*/ + #include #include "types.h" @@ -68,7 +77,7 @@ EMUFILE* slot1_GetFatImage() ISlot1Interface* slot1_List[NDS_SLOT1_COUNT]; ISlot1Interface* slot1_device = NULL; -NDS_SLOT1_TYPE slot1_device_type = NDS_SLOT1_RETAIL; //default for frontends that dont even configure this +NDS_SLOT1_TYPE slot1_device_type = NDS_SLOT1_RETAIL_AUTO; //default for frontends that dont even configure this void slot1_Init() @@ -80,13 +89,15 @@ void slot1_Init() //construct all devices extern TISlot1InterfaceConstructor construct_Slot1_None; - extern TISlot1InterfaceConstructor construct_Slot1_Retail; + extern TISlot1InterfaceConstructor construct_Slot1_Retail_Auto; extern TISlot1InterfaceConstructor construct_Slot1_R4; extern TISlot1InterfaceConstructor construct_Slot1_Retail_NAND; + extern TISlot1InterfaceConstructor construct_Slot1_Retail_MCROM; slot1_List[NDS_SLOT1_NONE] = construct_Slot1_None(); - slot1_List[NDS_SLOT1_RETAIL] = construct_Slot1_Retail(); + slot1_List[NDS_SLOT1_RETAIL_AUTO] = construct_Slot1_Retail_Auto(); slot1_List[NDS_SLOT1_R4] = construct_Slot1_R4(); slot1_List[NDS_SLOT1_RETAIL_NAND] = construct_Slot1_Retail_NAND(); + slot1_List[NDS_SLOT1_RETAIL_MCROM] = construct_Slot1_Retail_MCROM(); } void slot1_Shutdown() diff --git a/desmume/src/slot1.h b/desmume/src/slot1.h index 54e75b97d..616e7d90f 100644 --- a/desmume/src/slot1.h +++ b/desmume/src/slot1.h @@ -64,15 +64,22 @@ public: //called when the emulator shuts down, or when the device disappears from existence virtual void shutdown() { } - //called when the emulator write to the slot - virtual void write08(u8 PROCNUM, u32 adr, u8 val) { } - virtual void write16(u8 PROCNUM, u32 adr, u16 val) { } + //called when the emulator write to the slot (TODO - refactors necessary) + void write08(u8 PROCNUM, u32 adr, u8 val) { printf("WARNING: 8bit write to slot-1\n"); } + void write16(u8 PROCNUM, u32 adr, u16 val) { printf("WARNING: 16bit write to slot-1\n"); } virtual void write32(u8 PROCNUM, u32 adr, u32 val) { } - //called when the emulator reads from the slot - virtual u8 read08(u8 PROCNUM, u32 adr) { return 0xFF; } - virtual u16 read16(u8 PROCNUM, u32 adr) { return 0xFFFF; } + //called when the emulator reads from the slot (TODO - refactors necessary) + u8 read08(u8 PROCNUM, u32 adr) { printf("WARNING: 8bit read from slot-1\n"); return 0xFF; } + u16 read16(u8 PROCNUM, u32 adr) { printf("WARNING: 16bit read from slot-1\n"); return 0xFFFF; } virtual u32 read32(u8 PROCNUM, u32 adr) { return 0xFFFFFFFF; } + + //transfers a byte to the slot-1 device via auxspi, and returns the incoming byte + //cpu is provided for diagnostic purposes only.. the slot-1 device wouldn't know which CPU it is. + virtual u8 auxspi_transaction(int PROCNUM, u8 value) { return 0x00; } + + //called when the auxspi burst is ended (SPI chipselect in is going low) + virtual void auxspi_reset(int PROCNUM) {} }; typedef ISlot1Interface* TISlot1InterfaceConstructor(); @@ -80,13 +87,14 @@ typedef ISlot1Interface* TISlot1InterfaceConstructor(); enum NDS_SLOT1_TYPE { NDS_SLOT1_NONE, - NDS_SLOT1_RETAIL, - NDS_SLOT1_R4, - NDS_SLOT1_RETAIL_NAND, // used in Made in Ore/WarioWare D.I.Y. - NDS_SLOT1_COUNT // use for counter addons - MUST TO BE LAST!!! + NDS_SLOT1_RETAIL_AUTO, //autodetect which kind of retail card to use + NDS_SLOT1_R4, //R4 flash card + NDS_SLOT1_RETAIL_NAND, //Made in Ore/WarioWare D.I.Y. + NDS_SLOT1_RETAIL_MCROM, //a standard MC (eeprom, flash, fram) -bearing retail card. Also supports motion, for now, because that's the way we originally coded it + NDS_SLOT1_COUNT //use to count addons - MUST BE LAST!!! }; -extern ISlot1Interface* slot1_device; // current slot1 device +extern ISlot1Interface* slot1_device; //the current slot1 device instance extern ISlot1Interface* slot1_List[NDS_SLOT1_COUNT]; void slot1_Init(); diff --git a/desmume/src/utils/advanscene.cpp b/desmume/src/utils/advanscene.cpp new file mode 100644 index 000000000..fa23c67b4 --- /dev/null +++ b/desmume/src/utils/advanscene.cpp @@ -0,0 +1,253 @@ +/* + Copyright (C) 2011-2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +#include +#include + +#define TIXML_USE_STL +#include "utils/tinyxml/tinyxml.h" + +#include "advanscene.h" +#include "mc.h" + +ADVANsCEne advsc; + +#define _ADVANsCEne_BASE_ID "DeSmuME database (ADVANsCEne)\0x1A" +#define _ADVANsCEne_BASE_VERSION_MAJOR 1 +#define _ADVANsCEne_BASE_VERSION_MINOR 0 +#define _ADVANsCEne_BASE_NAME "ADVANsCEne Nintendo DS Collection" + +u8 ADVANsCEne::checkDB(const char *serial, u32 crc) +{ + loaded = false; + FILE *fp = fopen(database_path.c_str(), "rb"); + if (fp) + { + char buf[64]; + memset(buf, 0, sizeof(buf)); + if (fread(buf, 1, strlen(_ADVANsCEne_BASE_ID), fp) == strlen(_ADVANsCEne_BASE_ID)) + { + //printf("ID: %s\n", buf); + if (strcmp(buf, _ADVANsCEne_BASE_ID) == 0) + { + if (fread(&versionBase[0], 1, 2, fp) == 2) + { + //printf("Version base: %i.%i\n", versionBase[0], versionBase[1]); + if (fread(&version[0], 1, 4, fp) == 4) + { + //printf("Version: %c%c%c%c\n", version[3], version[2], version[1], version[0]); + if (fread(&createTime, 1, sizeof(time_t), fp) == sizeof(time_t)) + { + memset(buf, 0,sizeof(buf)); + // serial(8) + crc32(4) + save_type(1) = 13 + reserved(8) = 21 + while (true) + { + if (fread(buf, 1, 21, fp) != 21) break; + + bool serialFound = (memcmp(&buf[4], serial, 4) == 0); + u32 dbcrc = LE_TO_LOCAL_32(*(u32*)(buf+8)); + bool crcFound = (crc == dbcrc); + + if(serialFound || crcFound) + { + foundAsCrc = crcFound; + foundAsSerial = serialFound; + memcpy(&crc32, &buf[8], 4); + //printf("%s founded: crc32=%04X, save type %02X\n", serial, crc32, buf[12]); + saveType = buf[12]; + fclose(fp); + loaded = true; + return true; + } + } + } + } + } + } + } + fclose(fp); + } + return false; +} + + + +bool ADVANsCEne::getXMLConfig(const char *in_filaname) +{ + TiXmlDocument *xml = NULL; + TiXmlElement *el = NULL; + TiXmlElement *el_configuration = NULL; + TiXmlElement *el_newDat = NULL; + + xml = new TiXmlDocument(); + if (!xml) return false; + if (!xml->LoadFile(in_filaname)) return false; + el = xml->FirstChildElement("dat"); + if (!el) return false; + el_configuration = el->FirstChildElement("configuration"); + if (!el_configuration) return false; + el = el_configuration->FirstChildElement("datName"); if (el) { datName = el->GetText() ? el->GetText() : ""; } + el = el_configuration->FirstChildElement("datVersion"); if (el) { datVersion = el->GetText() ? el->GetText() : ""; } + + el_newDat = el_configuration->FirstChildElement("newDat"); + if (!el_newDat) return false; + el = el_newDat->FirstChildElement("datVersionURL"); if (el) { urlVersion = el->GetText() ? el->GetText() : ""; } + el = el_newDat->FirstChildElement("datURL"); if (el) { urlDat = el->GetText() ? el->GetText() : ""; } + + delete xml; + return true; +} + +u32 ADVANsCEne::convertDB(const char *in_filaname) +{ + //these strings are contained in the xml file, verbatim, so they function as enum values + //we leave the strings here rather than pooled elsewhere to remind us that theyre part of the advanscene format. + const char *saveTypeNames[] = { + "Eeprom - 4 kbit", // EEPROM 4kbit + "Eeprom - 64 kbit", // EEPROM 64kbit + "Eeprom - 512 kbit", // EEPROM 512kbit + "Fram - 256 kbit", // FRAM 256kbit ! + "Flash - 2 mbit", // FLASH 2Mbit + "Flash - 4 mbit", // FLASH 4Mbit + "Flash - 8 mbit", // FLASH 8Mbit + "Flash - 16 mbit", // FLASH 16Mbit ! + "Flash - 32 mbit", // FLASH 32Mbit ! + "Flash - 64 mbit", // FLASH 64Mbit + "Flash - 128 mbit", // FLASH 128Mbit ! + "Flash - 256 mbit", // FLASH 256Mbit ! + "Flash - 512 mbit" // FLASH 512Mbit ! + }; + + TiXmlDocument *xml = NULL; + TiXmlElement *el = NULL; + TiXmlElement *el_serial = NULL; + TiXmlElement *el_games = NULL; + TiXmlElement *el_crc32 = NULL; + TiXmlElement *el_saveType = NULL; + FILE *fp; + u32 crc32 = 0; + u32 reserved = 0; + + lastImportErrorMessage = ""; + + printf("Converting DB...\n"); + if (getXMLConfig(in_filaname)) + { + if (datName.size()==0) return 0; + if (datName != _ADVANsCEne_BASE_NAME) return 0; + } + + fp = fopen(database_path.c_str(), "wb"); + if (!fp) return 0; + + // Header + fwrite(_ADVANsCEne_BASE_ID, 1, strlen(_ADVANsCEne_BASE_ID), fp); + fputc(_ADVANsCEne_BASE_VERSION_MAJOR, fp); + fputc(_ADVANsCEne_BASE_VERSION_MINOR, fp); + if (datVersion.size()) + fwrite(&datVersion[0], 1, datVersion.size(), fp); + else + fputc(0, fp); + time_t __time = time(NULL); + fwrite(&__time, 1, sizeof(time_t), fp); + + xml = new TiXmlDocument(); + if (!xml) { fclose(fp); return 0; } + if (!xml->LoadFile(in_filaname)) { fclose(fp); return 0; } + el = xml->FirstChildElement("dat"); + if (!el) { fclose(fp); return 0; } + el_games = el->FirstChildElement("games"); + if (!el_games) { fclose(fp); return 0; } + el = el_games->FirstChildElement("game"); + if (!el) { fclose(fp); return 0; } + u32 count = 0; + while (el) + { + TiXmlElement* title = el->FirstChildElement("title"); + if(title) + { + //just a little diagnostic + //printf("Importing %s\n",title->GetText()); + } + else { fclose(fp); return 0; } + + el_serial = el->FirstChildElement("serial"); + + if(!el_serial) + { + lastImportErrorMessage = "Missing element. Did you use the right xml file? We need the RtoolDS one."; + fclose(fp); + return 0; + } + if (fwrite(el_serial->GetText(), 1, 8, fp) != 8) + { + lastImportErrorMessage = "Error writing output file"; + fclose(fp); return 0; + } + + + // CRC32 + el_crc32 = el->FirstChildElement("files"); + sscanf_s(el_crc32->FirstChildElement("romCRC")->GetText(), "%x", &crc32); + if (fwrite(&crc32, 1, sizeof(u32), fp) != sizeof(u32)) + { + fclose(fp); return 0; + } + // Save type + el_saveType = el->FirstChildElement("saveType"); + if (el_saveType) + { + const char *tmp = el_saveType->GetText(); + if (tmp) + { + if (strcmp(tmp, "None") == 0) + fputc(0xFE, fp); + else + { + bool bUnknown = true; + for (u8 i = 0; i < MAX_SAVE_TYPES; i++) + { + if (strcmp(saveTypeNames[i], "") == 0) continue; + if (strcasecmp(tmp, saveTypeNames[i]) == 0) + { + fputc(i, fp); + bUnknown = false; + break; + } + } + if (bUnknown) + fputc(0xFF, fp); // Unknown + } + } + else + fputc(0xFF, fp); // Unknown + } + fwrite(&reserved, 1, sizeof(u32), fp); + fwrite(&reserved, 1, sizeof(u32), fp); + count++; + el = el->NextSiblingElement("game"); + } + printf("\n"); + delete xml; + fclose(fp); + if (count > 0) + printf("done\n"); + else + printf("error\n"); + printf("ADVANsCEne converter: %i found\n", count); + return count; +} diff --git a/desmume/src/utils/advanscene.h b/desmume/src/utils/advanscene.h new file mode 100644 index 000000000..da961899a --- /dev/null +++ b/desmume/src/utils/advanscene.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2011-2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +#include +#include "types.h" + +class ADVANsCEne +{ +private: + std::string database_path; // DeSmuME save types + u8 versionBase[2]; + char version[4]; + time_t createTime; + u8 saveType; + u32 crc32; + bool loaded; + bool foundAsCrc, foundAsSerial; + + // XML + std::string datName; + std::string datVersion; + std::string urlVersion; + std::string urlDat; + bool getXMLConfig(const char *in_filaname); + +public: + ADVANsCEne() + : saveType(0xFF), + crc32(0), + loaded(false) + { + memset(versionBase, 0, sizeof(versionBase)); + memset(version, 0, sizeof(version)); + } + void setDatabase(const char *path) { loaded = false; database_path = path; } + u32 convertDB(const char *in_filaname); + u8 checkDB(const char *serial, u32 crc); + u32 getSaveType() { return saveType; } + u32 getCRC32() { return crc32; } + bool isLoaded() { return loaded; } + const char* getIdMethod() { + if(foundAsCrc) return "CRC"; + if(foundAsSerial) return "Serial"; + return ""; + } + std::string lastImportErrorMessage; +}; + +extern ADVANsCEne advsc; diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index a1fc3c642..5dc5fcca0 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -1549,6 +1549,14 @@ + + + + @@ -2196,13 +2204,33 @@ > + + + + + + + + + + diff --git a/desmume/src/windows/DeSmuME_2008.vcproj b/desmume/src/windows/DeSmuME_2008.vcproj index 332182aee..b43eb6401 100644 --- a/desmume/src/windows/DeSmuME_2008.vcproj +++ b/desmume/src/windows/DeSmuME_2008.vcproj @@ -1010,13 +1010,33 @@ > + + + + + + + + + + @@ -1065,6 +1085,14 @@ + + + + diff --git a/desmume/src/windows/DeSmuME_2010.vcxproj b/desmume/src/windows/DeSmuME_2010.vcxproj index 21d7a6617..b8ace2dcd 100644 --- a/desmume/src/windows/DeSmuME_2010.vcxproj +++ b/desmume/src/windows/DeSmuME_2010.vcxproj @@ -370,10 +370,13 @@ + + + + - @@ -427,6 +430,7 @@ + @@ -648,6 +652,8 @@ + + @@ -700,6 +706,7 @@ + diff --git a/desmume/src/windows/DeSmuME_2010.vcxproj.filters b/desmume/src/windows/DeSmuME_2010.vcxproj.filters index e6c5d60c2..df63bcdd2 100644 --- a/desmume/src/windows/DeSmuME_2010.vcxproj.filters +++ b/desmume/src/windows/DeSmuME_2010.vcxproj.filters @@ -393,9 +393,6 @@ Core\addons - - Core\addons - Core\addons @@ -783,6 +780,21 @@ Core + + Core\addons + + + Core\addons + + + Core\addons + + + Core\addons + + + Core\utils + @@ -1512,6 +1524,15 @@ Core + + Core\addons + + + Core\addons + + + Core\utils + diff --git a/desmume/src/windows/DeSmuME_2012.vcxproj b/desmume/src/windows/DeSmuME_2012.vcxproj index 4cf3be60b..f90843e1c 100644 --- a/desmume/src/windows/DeSmuME_2012.vcxproj +++ b/desmume/src/windows/DeSmuME_2012.vcxproj @@ -381,10 +381,13 @@ + + + + - @@ -438,6 +441,7 @@ + @@ -659,6 +663,8 @@ + + @@ -711,6 +717,7 @@ + diff --git a/desmume/src/windows/DeSmuME_2012.vcxproj.filters b/desmume/src/windows/DeSmuME_2012.vcxproj.filters index 939f7e469..290e9931c 100644 --- a/desmume/src/windows/DeSmuME_2012.vcxproj.filters +++ b/desmume/src/windows/DeSmuME_2012.vcxproj.filters @@ -198,9 +198,6 @@ Core\addons - - Core\addons - Core\addons @@ -775,6 +772,21 @@ Core + + Core\addons + + + Core\addons + + + Core\addons + + + Core\addons + + + Core\utils + @@ -1374,6 +1386,15 @@ Core + + Core\addons + + + Core\addons + + + Core\utils + diff --git a/desmume/src/windows/importSave.cpp b/desmume/src/windows/importSave.cpp index 2256967cf..e23f31fff 100644 --- a/desmume/src/windows/importSave.cpp +++ b/desmume/src/windows/importSave.cpp @@ -23,6 +23,7 @@ along with the this software. If not, see . #include "../NDSSystem.h" #include "resource.h" #include "importSave.h" +#include "utils/advanscene.h" char ImportSavFName[MAX_PATH] = {0}; u32 fileSaveSize = 0; diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 3a6ed8a1a..0c5567a3f 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -59,6 +59,7 @@ #include "../firmware.h" #include "../lua-engine.h" #include "../path.h" +#include "../utils/advanscene.h" //other random stuff #include "recentroms.h" @@ -3244,7 +3245,7 @@ int _main() slot1_Init(); //override slot1 type with commandline, if present - int slot1_device_type = (NDS_SLOT1_TYPE)GetPrivateProfileInt("Slot1", "type", NDS_SLOT1_RETAIL, IniName); + int slot1_device_type = (NDS_SLOT1_TYPE)GetPrivateProfileInt("Slot1", "type", NDS_SLOT1_RETAIL_AUTO, IniName); if(cmdline.slot1 != "") WritePrivateProfileInt("Slot1","type",slot1_device_type,IniName); else diff --git a/desmume/src/windows/slot1_config.cpp b/desmume/src/windows/slot1_config.cpp index 05faa76dc..1b37d5a1a 100644 --- a/desmume/src/windows/slot1_config.cpp +++ b/desmume/src/windows/slot1_config.cpp @@ -204,7 +204,8 @@ void slot1Dialog(HWND hwnd) else needReset_slot1 = false; break; - case NDS_SLOT1_RETAIL: + case NDS_SLOT1_RETAIL_AUTO: + case NDS_SLOT1_RETAIL_MCROM: break; case NDS_SLOT1_R4: if (strlen(tmp_fat_path))