diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 29c2b3645..09162204d 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -858,6 +858,7 @@ void MMU_Init(void) { //MMU.bupmem.fp = NULL; rtcInit(); addonsInit(); + slot1Init(); if(Mic_Init() == FALSE) INFO("Microphone init failed.\n"); else @@ -873,6 +874,7 @@ void MMU_DeInit(void) { // fclose(MMU.bupmem.fp); //mc_free(&MMU.bupmem); addonsClose(); + slot1Close(); Mic_DeInit(); } @@ -950,6 +952,7 @@ void MMU_Reset() rtcInit(); partie = 1; addonsReset(); + slot1Close(); Mic_Reset(); MMU.gfx3dCycles = 0; @@ -1078,7 +1081,10 @@ static void execdiv() { template void FASTCALL MMU_writeToGCControl(u32 val) { - nds_dscard& card = MMU.dscard[PROCNUM]; + const int TEST_PROCNUM = 0; //PROCNUM + nds_dscard& card = MMU.dscard[TEST_PROCNUM]; + + memcpy(&card.command[0], &MMU.MMU_MEM[TEST_PROCNUM][0x40][0x1A8], 8); if(!(val & 0x80000000)) { @@ -1086,11 +1092,17 @@ void FASTCALL MMU_writeToGCControl(u32 val) card.transfer_count = 0; val &= 0x7F7FFFFF; - T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val); + T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val); return; } - memcpy(&card.command[0], &MMU.MMU_MEM[PROCNUM][0x40][0x1A8], 8); + u32 shift = (val>>24&7); + if(shift == 7) + card.transfer_count = 1; + else if(shift == 0) + card.transfer_count = 0; + else + card.transfer_count = (0x100<> 2; - NDS_makeInt(PROCNUM, 20); - break; - } - break; - - // --- Ninja SD commands end --------------------------------- - - - default: - { - INFO("WRITE CARD command: %02X%02X%02X%02X%02X%02X%02X%02X\t", - card.command[0], card.command[1], card.command[2], card.command[3], - card.command[4], card.command[5], card.command[6], card.command[7]); - INFO("FROM: %08X\n", (PROCNUM ? NDS_ARM7:NDS_ARM9).instruct_adr); - - card.address = 0; - card.transfer_count = 0; - } - break; + case 0x3C: //Switch to KEY1 mode + card.mode = CardMode_KEY1; + break; + + default: + //fall through to the special slot1 handler + slot1_device.write32(REG_GCROMCTRL,val); + break; } if(card.transfer_count == 0) { val &= 0x7F7FFFFF; - T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val); + T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val); return; } val |= 0x00800000; - T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val); + T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, val); // Launch DMA if start flag was set to "DS Cart" //printf("triggering card dma\n"); @@ -1276,7 +1167,9 @@ void FASTCALL MMU_writeToGCControl(u32 val) template u32 MMU_readFromGC() { - nds_dscard& card = MMU.dscard[PROCNUM]; + const int TEST_PROCNUM = 0; //PROCNUM + + nds_dscard& card = MMU.dscard[TEST_PROCNUM]; u32 val = 0; if(card.transfer_count == 0) @@ -1284,130 +1177,16 @@ u32 MMU_readFromGC() switch(card.command[0]) { - // Dummy - case 0x9F: + case 0x9F: //Dummy + return 0xFFFFFFFF; + + case 0x3C: //Switch to KEY1 mode val = 0xFFFFFFFF; break; - // Nand Init? - case 0x94: - val = 0; //Unsure what to return here so return 0 for now - break; - - // Nand Status? - case 0xD6: - //0x80 == busy - // Made in Ore/WariWare D.I.Y. need set value to 0x80 - val = 0x20; //0x20 == ready - break; - - //case 0x8B: - case 0x85: - val = 0; //Unsure what to return here so return 0 for now - break; - - // Data read - case 0x00: - case 0xB7: - { - // Make sure any reads below 0x8000 redirect to 0x8000+(adr&0x1FF) as on real cart - if((card.command[0] == 0xB7) && (card.address < 0x8000)) - { - INFO("Read below 0x8000 (0x%04X) from: ARM%s %08X\n", - card.address, (PROCNUM ? "7":"9"), (PROCNUM ? NDS_ARM7:NDS_ARM9).instruct_adr); - - card.address = (0x8000 + (card.address&0x1FF)); - } - - if(card.address >= gameInfo.romsize) - { - DEBUG_Notify.ReadBeyondEndOfCart(card.address,gameInfo.romsize); - val = 0xFFFFFFFF; - } - else - //but, this is actually handled by the cart rom buffer being oversized and full of 0xFF. - //is this a good idea? We think so. - val = T1ReadLong(MMU.CART_ROM, card.address & MMU.CART_ROM_MASK); - } - break; - - // Get ROM chip ID - case 0x90: - case 0xB8: - { - // Note: the BIOS stores the chip ID in main memory - // Most games continuously compare the chip ID with - // the value in memory, probably to know if the card - // was removed. - // As DeSmuME boots directly from the game, the chip - // ID in main mem is zero and this value needs to be - // zero too. - - //staff of kings verifies this (it also uses the arm7 IRQ 20) - if(nds.cardEjected) - val = 0xFFFFFFFF; - else val = 0x00000000; - } - break; - - // Switch to KEY1 mode - case 0x3C: - val = 0xFFFFFFFF; - break; - - // --- 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 --------------------------------- - default: - INFO("READ CARD command: %02X%02X%02X%02X% 02X%02X%02X%02X\t", - card.command[0], card.command[1], card.command[2], card.command[3], - card.command[4], card.command[5], card.command[6], card.command[7]); - INFO("FROM: %08X\n", (PROCNUM ? NDS_ARM7:NDS_ARM9).instruct_adr); + val = slot1_device.read32(REG_GCDATAIN); break; - } card.address += 4; // increment address @@ -1417,77 +1196,17 @@ u32 MMU_readFromGC() return val; // return data // transfer is done - T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, - T1ReadLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4) & 0x7F7FFFFF); + T1WriteLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4, + T1ReadLong(MMU.MMU_MEM[TEST_PROCNUM][0x40], 0x1A4) & 0x7F7FFFFF); // if needed, throw irq for the end of transfer if(MMU.AUX_SPI_CNT & 0x4000) - NDS_makeInt(PROCNUM, 19); + NDS_makeInt(TEST_PROCNUM, 19); return val; } -//INLINE void check_access(u32 adr, u32 access) { -// /* every other mode: sys */ -// access |= 1; -// if ((NDS_ARM9.CPSR.val & 0x1F) == 0x10) { -// /* is user mode access */ -// access ^= 1 ; -// } -// if (armcp15_isAccessAllowed((armcp15_t *)NDS_ARM9.coproc[15],adr,access)==FALSE) { -// execute = FALSE ; -// } -//} -//INLINE void check_access_write(u32 adr) { -// u32 access = CP15_ACCESS_WRITE; -// check_access(adr, access) -//} -// -//u8 FASTCALL MMU_read8_acl(u32 proc, u32 adr, u32 access) -//{ -// /* on arm9 we need to check the MPU regions */ -// if (proc == ARMCPU_ARM9) -// check_access(u32 adr, u32 access); -// return MMU_read8(proc,adr); -//} -//u16 FASTCALL MMU_read16_acl(u32 proc, u32 adr, u32 access) -//{ -// /* on arm9 we need to check the MPU regions */ -// if (proc == ARMCPU_ARM9) -// check_access(u32 adr, u32 access); -// return MMU_read16(proc,adr); -//} -//u32 FASTCALL MMU_read32_acl(u32 proc, u32 adr, u32 access) -//{ -// /* on arm9 we need to check the MPU regions */ -// if (proc == ARMCPU_ARM9) -// check_access(u32 adr, u32 access); -// return MMU_read32(proc,adr); -//} -// -//void FASTCALL MMU_write8_acl(u32 proc, u32 adr, u8 val) -//{ -// /* check MPU region on ARM9 */ -// if (proc == ARMCPU_ARM9) -// check_access_write(adr); -// MMU_write8(proc,adr,val); -//} -//void FASTCALL MMU_write16_acl(u32 proc, u32 adr, u16 val) -//{ -// /* check MPU region on ARM9 */ -// if (proc == ARMCPU_ARM9) -// check_access_write(adr); -// MMU_write16(proc,adr,val) ; -//} -//void FASTCALL MMU_write32_acl(u32 proc, u32 adr, u32 val) -//{ -// /* check MPU region on ARM9 */ -// if (proc == ARMCPU_ARM9) -// check_access_write(adr); -// MMU_write32(proc,adr,val) ; -//} - //does some validation on the game's choice of IF value, correcting it if necessary static void validateIF_arm9() diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index b80e9e117..6fdd84aa1 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -49,7 +49,7 @@ libdesmume_a_SOURCES = \ utils/task.cpp utils/task.h \ utils/dlditool.cpp \ addons.cpp addons.h \ - addons/compactFlash.cpp addons/gbagame.cpp addons/none.cpp addons/rumblepak.cpp addons/guitarGrip.cpp addons/expMemory.cpp addons/piano.cpp fs.h \ + addons/compactFlash.cpp addons/gbagame.cpp addons/none.cpp addons/rumblepak.cpp addons/guitarGrip.cpp addons/expMemory.cpp addons/piano.cpp addons/slot1_none.cpp addons/slot1_r4.cpp addons/slot1_retail.cpp fs.h \ cheatSystem.cpp cheatSystem.h \ texcache.cpp texcache.h rasterize.cpp rasterize.h \ metaspu/metaspu.cpp metaspu/metaspu.h \ diff --git a/desmume/src/addons.cpp b/desmume/src/addons.cpp index 4fb642b79..41ce3d8b8 100644 --- a/desmume/src/addons.cpp +++ b/desmume/src/addons.cpp @@ -50,7 +50,7 @@ ADDONINTERFACE addonList[NDS_ADDON_COUNT] = { }; ADDONINTERFACE addon = addonCFlash; // default none pak -u8 addon_type = NDS_ADDON_CFLASH; +NDS_ADDON_TYPE addon_type = NDS_ADDON_CFLASH; BOOL addonsInit() { @@ -67,7 +67,7 @@ void addonsReset() addon.reset(); } -BOOL addonsChangePak(u8 type) +BOOL addonsChangePak(NDS_ADDON_TYPE type) { printf("addonsChangePak\n"); if (type > NDS_ADDON_COUNT) return FALSE; @@ -77,3 +77,44 @@ BOOL addonsChangePak(u8 type) return addon.init(); } +//-------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------- + +extern ADDONINTERFACE slot1None; +extern ADDONINTERFACE slot1Retail; +extern ADDONINTERFACE slot1R4; + +ADDONINTERFACE slot1List[NDS_SLOT1_COUNT] = { + slot1None, + slot1Retail, + slot1R4 +}; + +ADDONINTERFACE slot1_device = slot1Retail; //default for frontends that dont even configure this +u8 slot1_device_type = NDS_SLOT1_RETAIL; + +BOOL slot1Init() +{ + return slot1_device.init(); +} + +void slot1Close() +{ + slot1_device.close(); +} + +void slot1Reset() +{ + slot1_device.reset(); +} + +BOOL slot1Change(NDS_SLOT1_TYPE changeToType) +{ + printf("slot1Change to: %d\n", changeToType); + if (changeToType > NDS_SLOT1_COUNT || changeToType < 0) return FALSE; + slot1_device.close(); + slot1_device_type = changeToType; + slot1_device = slot1List[slot1_device_type]; + return slot1_device.init(); +} \ No newline at end of file diff --git a/desmume/src/addons.h b/desmume/src/addons.h index ef9f09f0a..ad69c21d9 100644 --- a/desmume/src/addons.h +++ b/desmume/src/addons.h @@ -1,5 +1,5 @@ /* Copyright (C) 2009 CrazyMax - Copyright (C) 2009 DeSmuME team + Copyright (C) 2009-2010 DeSmuME team This file is part of DeSmuME @@ -25,7 +25,7 @@ #include "types.h" #include "debug.h" -typedef struct +struct ADDONINTERFACE { // The name of the plugin, this name will appear in the plugins list const char * name; @@ -54,9 +54,10 @@ typedef struct //called when the user get info about addon pak (description) void (*info)(char *info); -} ADDONINTERFACE; +}; -enum { +enum NDS_ADDON_TYPE +{ NDS_ADDON_NONE, NDS_ADDON_CFLASH, // compact flash NDS_ADDON_RUMBLEPAK, // rumble pack @@ -79,7 +80,7 @@ inline bool CFlash_IsUsingPath() { return CFlash_Mode==ADDON_CFLASH_MODE_Path || extern ADDONINTERFACE addon; // current pak extern ADDONINTERFACE addonList[NDS_ADDON_COUNT]; // lists pointer on paks -extern u8 addon_type; // current type pak +extern NDS_ADDON_TYPE addon_type; // current type pak extern char GBAgameName[MAX_PATH]; // file name for GBA game (rom) extern void (*FeedbackON)(BOOL enable); // feedback on/off @@ -87,9 +88,25 @@ extern void (*FeedbackON)(BOOL enable); // feedback on/off extern BOOL addonsInit(); // Init addons extern void addonsClose(); // Shutdown addons extern void addonsReset(); // Reset addon -extern BOOL addonsChangePak(u8 type); // change current adddon +extern BOOL addonsChangePak(NDS_ADDON_TYPE type); // change current adddon extern void guitarGrip_setKey(bool green, bool red, bool yellow, bool blue); // Guitar grip keys extern void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, bool g, bool gs, bool a, bool as, bool b, bool hic); //piano keys -#endif +extern ADDONINTERFACE slot1_device; // current slot1 device + +enum NDS_SLOT1_TYPE +{ + NDS_SLOT1_NONE, + NDS_SLOT1_RETAIL, + NDS_SLOT1_R4, + NDS_SLOT1_COUNT // use for counter addons - MUST TO BE LAST!!! +}; + +BOOL slot1Init(); +void slot1Close(); +void slot1Reset(); +BOOL slot1Change(NDS_SLOT1_TYPE type); // change current adddon + + +#endif //__ADDONS_H__ diff --git a/desmume/src/addons/slot1_none.cpp b/desmume/src/addons/slot1_none.cpp new file mode 100644 index 000000000..1d27eb9cb --- /dev/null +++ b/desmume/src/addons/slot1_none.cpp @@ -0,0 +1,62 @@ +/* Copyright (C) 2010 DeSmuME team + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../addons.h" + +static void slot1_info(char *info) { strcpy(info, "Slot1 no-card emulation (card ejected!)"); } +static void slot1_config(void) {} + +static BOOL slot1_init() { return (TRUE); } + +static void slot1_reset() {} + +static void slot1_close() {} + + +static void slot1_write08(u32 adr, u8 val) {} +static void slot1_write16(u32 adr, u16 val) {} +static void slot1_write32(u32 adr, u32 val) {} + +static u8 slot1_read08(u32 adr) +{ + return 0xFF; +} +static u16 slot1_read16(u32 adr) +{ + return 0xFFFF; +} +static u32 slot1_read32(u32 adr) +{ + return 0xFFFFFFFF; +} + + +ADDONINTERFACE slot1None = { + "Slot1None", + slot1_init, + slot1_reset, + slot1_close, + slot1_config, + slot1_write08, + slot1_write16, + slot1_write32, + slot1_read08, + slot1_read16, + slot1_read32, + slot1_info}; diff --git a/desmume/src/addons/slot1_r4.cpp b/desmume/src/addons/slot1_r4.cpp new file mode 100644 index 000000000..93589b98f --- /dev/null +++ b/desmume/src/addons/slot1_r4.cpp @@ -0,0 +1,172 @@ +/* Copyright (C) 2010 DeSmuME team + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../addons.h" +#include "../registers.h" +#include "../mmu.h" +#include "../NDSSystem.h" +#include + +static FILE *img = NULL; +static u32 write_count = 0; +static u32 write_enabled = 0; +static int old_addr = 0; +static void init_r4_flash() +{ + srand(time(NULL)); + + if (!img) + img = fopen("DLDI_R4DS.img", "r+b"); + + if(!img) + { + INFO("DLDI_R4DS.img not found\n"); + } +} + +static void info(char *info) { strcpy(info, "Slot1 R4 Emulation"); } +static void config(void) {} + +static BOOL init() +{ + init_r4_flash(); + return TRUE; +} + +static void reset() {} + +static void close() {} + + +static void write08(u32 adr, u8 val) {} +static void write16(u32 adr, u16 val) {} + +static void write32_GCROMCTRL(u32 val) +{ + nds_dscard& card = MMU.dscard[0]; + + switch(card.command[0]) + { + case 0xB0: + break; + case 0xB9: + case 0xBA: + case 0xBB: + card.address = (card.command[1] << 24) | (card.command[2] << 16) | (card.command[3] << 8) | card.command[4]; + fseek(img,card.address,SEEK_SET); + break; + case 0xBC: + write_enabled = 1; + write_count = 0x80; + card.address = (card.command[1] << 24) | (card.command[2] << 16) | (card.command[3] << 8) | card.command[4]; + fseek(img,card.address,SEEK_SET); + write_count = 0x80; + break; + } +} + +static void write32(u32 adr, u32 val) +{ + switch(adr) + { + case REG_GCROMCTRL: + write32_GCROMCTRL(val); + break; + } +} + +static u8 read08(u32 adr) +{ + return 0xFF; +} +static u16 read16(u32 adr) +{ + return 0xFFFF; +} + + +static u32 read32_GCDATAIN() +{ + nds_dscard& card = MMU.dscard[0]; + + u32 val; + + switch(card.command[0]) + { + //Get ROM chip ID + case 0x90: + case 0xB8: + val = 0xFC2; + break; + + case 0xB0: + val = 0x1F4; + break; + case 0xB9: + { + /*if (addr == old_addr) + val = 0; + else + val = 0x1F4; + old_addr = addr;*/ + val = (rand() % 100) ? 0x1F4 : 0; + } + break; + case 0xBB: + case 0xBC: + val = 0; + break; + case 0xBA: + //INFO("Read from sd at sector %08X at adr %08X ",card.address/512,ftell(img)); + fread(&val, 1, 4, img); + //INFO("val %08X\n",val); + break; + + default: + val = 0; + } //switch(card.command[0]) + + return val; +} //read32_GCDATAIN + + +static u32 read32(u32 adr) +{ + switch(adr) + { + case REG_GCDATAIN: + return read32_GCDATAIN(); + default: + return 0; + } +} + +ADDONINTERFACE slot1R4 = { + "Slot1R4", + init, + reset, + close, + config, + write08, + write16, + write32, + read08, + read16, + read32, + info}; diff --git a/desmume/src/addons/slot1_retail.cpp b/desmume/src/addons/slot1_retail.cpp new file mode 100644 index 000000000..1c8dcc2d3 --- /dev/null +++ b/desmume/src/addons/slot1_retail.cpp @@ -0,0 +1,274 @@ +/* Copyright (C) 2010 DeSmuME team + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../addons.h" +#include "../registers.h" +#include "../mmu.h" +#include "../NDSSystem.h" + +static void info(char *info) { strcpy(info, "Slot1 Retail card emulation"); } +static void config(void) {} + +static BOOL init() { return (TRUE); } + +static void reset() {} + +static void close() {} + + +static void write08(u32 adr, u8 val) {} +static void write16(u32 adr, u16 val) {} + +static void write32_GCROMCTRL(u32 val) +{ + nds_dscard& card = MMU.dscard[0]; + + switch(card.command[0]) + { + case 0x00: //Data read + case 0xB7: + card.address = (card.command[1] << 24) | (card.command[2] << 16) | (card.command[3] << 8) | card.command[4]; + card.transfer_count = 0x80; + break; + default: + card.address = 0; + break; + } +} + +static void write32(u32 adr, u32 val) +{ + switch(adr) + { + case REG_GCROMCTRL: + write32_GCROMCTRL(val); + break; + } +} + +static u8 read08(u32 adr) +{ + return 0xFF; +} +static u16 read16(u32 adr) +{ + return 0xFFFF; +} + +static u32 read32_GCDATAIN() +{ + nds_dscard& card = MMU.dscard[0]; + + switch(card.command[0]) + { + //Get ROM chip ID + case 0x90: + case 0xB8: + { + // Note: the BIOS stores the chip ID in main memory + // Most games continuously compare the chip ID with + // the value in memory, probably to know if the card + // was removed. + // As DeSmuME boots directly from the game, the chip + // ID in main mem is zero and this value needs to be + // zero too. + + //staff of kings verifies this (it also uses the arm7 IRQ 20) + if(nds.cardEjected) //TODO - handle this with ejected card slot1 device (and verify using this case) + return 0xFFFFFFFF; + else return 0; + } + break; + + + // Data read + case 0x00: + case 0xB7: + { + // Make sure any reads below 0x8000 redirect to 0x8000+(adr&0x1FF) as on real cart + if((card.command[0] == 0xB7) && (card.address < 0x8000)) + { + //TODO - refactor this to include the PROCNUM, for debugging purposes if nothing else + //(can refactor gbaslot also) + + //INFO("Read below 0x8000 (0x%04X) from: ARM%s %08X\n", + // card.address, (PROCNUM ? "7":"9"), (PROCNUM ? NDS_ARM7:NDS_ARM9).instruct_adr); + + card.address = (0x8000 + (card.address&0x1FF)); + } + + if(card.address >= gameInfo.romsize) + { + DEBUG_Notify.ReadBeyondEndOfCart(card.address,gameInfo.romsize); + return 0xFFFFFFFF; + } + else + //but, this is actually handled by the cart rom buffer being oversized and full of 0xFF. + //is this a good idea? We think so. + + return T1ReadLong(MMU.CART_ROM, card.address & MMU.CART_ROM_MASK); + } + break; + default: + return 0; + } //switch(card.command[0]) +} //read32_GCDATAIN + +static u32 read32(u32 adr) +{ + switch(adr) + { + case REG_GCDATAIN: + return read32_GCDATAIN(); + default: + return 0; + } +} + + +ADDONINTERFACE slot1Retail = { + "Slot1Retail", + init, + reset, + close, + config, + write08, + write16, + write32, + read08, + read16, + read32, + info +}; + + + + // ///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/commandline.cpp b/desmume/src/commandline.cpp index ebcf40a97..c851b2007 100644 --- a/desmume/src/commandline.cpp +++ b/desmume/src/commandline.cpp @@ -29,6 +29,7 @@ #include "movie.h" #include "addons.h" #include "NDSSystem.h" +#include "utils/xstring.h" int scanline_filter_a = 2, scanline_filter_b = 4; int _commandline_linux_nojoy = 0; @@ -49,6 +50,7 @@ CommandLine::CommandLine() , _num_cores(-1) , _rigorous_timing(0) , _advanced_timing(-1) +, _slot1(NULL) { load_slot = 0; arm9_gdb_port = arm7_gdb_port = 0; @@ -88,6 +90,7 @@ void CommandLine::loadCommonOptions() { "scanline-filter-b", 0, 0, G_OPTION_ARG_INT, &scanline_filter_b, "Intensity of fadeout for scanlines filter (corner) (default 4)", "SCANLINE_FILTER_B"}, { "rigorous-timing", 0, 0, G_OPTION_ARG_INT, &_rigorous_timing, "Use some rigorous timings instead of unrealistically generous (default 0)", "RIGOROUS_TIMING"}, { "advanced-timing", 0, 0, G_OPTION_ARG_INT, &_advanced_timing, "Use advanced BUS-level timing (default 1)", "ADVANCED_TIMING"}, + { "slot1", 0, 0, G_OPTION_ARG_STRING, &_slot1, "Device to load in slot 1 (default retail)", "SLOT1"}, #ifndef _MSC_VER { "disable-sound", 0, 0, G_OPTION_ARG_NONE, &disable_sound, "Disables the sound emulation", NULL}, { "disable-limiter", 0, 0, G_OPTION_ARG_NONE, &disable_limiter, "Disables the 60fps limiter", NULL}, @@ -112,6 +115,8 @@ bool CommandLine::parse(int argc,char **argv) return false; } + if(_slot1) slot1 = _slot1; + if(slot1.size() != 0) str_lcase((char*)&slot1[0]); if(_play_movie_file) play_movie_file = _play_movie_file; if(_record_movie_file) record_movie_file = _record_movie_file; if(_cflash_image) cflash_image = _cflash_image; @@ -138,6 +143,14 @@ bool CommandLine::parse(int argc,char **argv) bool CommandLine::validate() { + if(slot1 != "") + { + if(slot1 != "r4" && slot1 != "retail" && slot1 != "none") { + g_printerr("Invalid slot1 device specified.\n"); + return false; + } + } + if (load_slot < 0 || load_slot > 10) { g_printerr("I only know how to load from slots 1-10, 0 means 'do not load savegame' and is default\n"); return false; @@ -208,5 +221,10 @@ void CommandLine::process_addonCommands() is_cflash_configured = true; } + if(slot1 == "retail") + slot1Change(NDS_SLOT1_RETAIL); + else if(slot1 == "r4") + slot1Change(NDS_SLOT1_R4); + } diff --git a/desmume/src/commandline.h b/desmume/src/commandline.h index 1e777fa3b..ef12a2f76 100644 --- a/desmume/src/commandline.h +++ b/desmume/src/commandline.h @@ -48,6 +48,7 @@ public: std::string cflash_image; std::string cflash_path; std::string gbaslot_rom; + std::string slot1; #ifndef _MSC_VER int disable_sound; int disable_limiter; @@ -88,6 +89,7 @@ private: int _num_cores; int _rigorous_timing; int _advanced_timing; + char* _slot1; }; #endif diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index 769ee3d3b..85f066776 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -1521,6 +1521,18 @@ RelativePath="..\addons\rumblepak.cpp" > + + + + + + + + + + + + + + + diff --git a/desmume/src/windows/DeSmuME_2010.vcxproj.filters b/desmume/src/windows/DeSmuME_2010.vcxproj.filters index f50138e3c..6be385b80 100644 --- a/desmume/src/windows/DeSmuME_2010.vcxproj.filters +++ b/desmume/src/windows/DeSmuME_2010.vcxproj.filters @@ -384,6 +384,15 @@ Core\utils + + Core\addons + + + Core\addons + + + Core\addons + diff --git a/desmume/src/windows/gbaslot_config.cpp b/desmume/src/windows/gbaslot_config.cpp index 65549ce22..1b4a27f28 100644 --- a/desmume/src/windows/gbaslot_config.cpp +++ b/desmume/src/windows/gbaslot_config.cpp @@ -618,7 +618,7 @@ void GBAslotDialog(HWND hwnd) Guitar.Enabled = false; WritePrivateProfileInt("GBAslot","type",temp_type,IniName); - addon_type = temp_type; + addon_type = (NDS_ADDON_TYPE)temp_type; addonsChangePak(addon_type); if (romloaded && needReset) NDS_Reset(); diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 564857c23..d87b32098 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -2461,7 +2461,7 @@ int _main() CommonSettings.cheatsDisable = GetPrivateProfileBool("General", "cheatsDisable", false, IniName); - addon_type = GetPrivateProfileInt("GBAslot", "type", NDS_ADDON_NONE, IniName); + addon_type = (NDS_ADDON_TYPE)GetPrivateProfileInt("GBAslot", "type", NDS_ADDON_NONE, IniName); win32_CFlash_cfgMode = GetPrivateProfileInt("GBAslot.CFlash", "fileMode", 2, IniName); win32_CFlash_cfgDirectory = GetPrivateProfileStdString("GBAslot.CFlash", "path", ""); win32_CFlash_cfgFileName = GetPrivateProfileStdString("GBAslot.CFlash", "filename", ""); @@ -2552,6 +2552,7 @@ int _main() cmdline.errorHelp(__argv[0]); return 1; } + cmdline.validate(); Desmume_InitOnce();