diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 7a2046131..43c22f773 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -2458,35 +2458,6 @@ u32 DmaController::read32() return ret; } -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) - { - case 16: - MMU.AUX_SPI_CNT = val; - 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) - { - case 0: - T1WriteByte((u8*)&MMU.AUX_SPI_CNT, 0, val); - if (val == 0) slot1_device->auxspi_reset(proc); - break; - case 1: - T1WriteByte((u8*)&MMU.AUX_SPI_CNT, 1, val); - break; - } - } -} - template bool validateIORegsWrite(u32 addr, u8 size, u32 val) { @@ -2744,6 +2715,7 @@ bool validateIORegsWrite(u32 addr, u8 size, u32 val) // 0x04100000 case REG_IPCFIFORECV: case REG_GCDATAIN: + //printf("MMU9 write%02d to register %08Xh = %08Xh (PC:%08X)\n", size, addr, val, ARMPROC.instruct_adr); return true; @@ -2838,6 +2810,7 @@ bool validateIORegsWrite(u32 addr, u8 size, u32 val) // 0x04100000 - IPC case REG_IPCFIFORECV: case REG_GCDATAIN: + //printf("MMU7 write%02d to register %08Xh = %08Xh (PC:%08X)\n", size, addr, val, ARMPROC.instruct_adr); return true; @@ -3111,6 +3084,7 @@ bool validateIORegsRead(u32 addr, u8 size) // 0x04100000 case REG_IPCFIFORECV: case REG_GCDATAIN: + //printf("MMU9 read%02d from register %08Xh = %08Xh (PC:%08X)\n", size, addr, T1ReadLong(MMU.ARM9_REG, addr & 0x00FFFFFF), ARMPROC.instruct_adr); return true; @@ -3205,7 +3179,8 @@ bool validateIORegsRead(u32 addr, u8 size) // 0x04100000 - IPC case REG_IPCFIFORECV: case REG_GCDATAIN: - //printf("MMU7 read%02d from register %08Xh = %08Xh (PC:%08X)\n", size, addr, T1ReadLong(MMU.ARM9_REG, addr & 0x00FFFFFF), ARMPROC.instruct_adr); + + //printf("MMU7 read%02d from register %08Xh = %08Xh (PC:%08X)\n", size, addr, T1ReadLong(MMU.ARM7_REG, addr & 0x00FFFFFF), ARMPROC.instruct_adr); return true; default: @@ -3428,17 +3403,12 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) case REG_AUXSPICNT: case REG_AUXSPICNT+1: - write_auxspicnt(ARMCPU_ARM9, 8, adr & 1, val); + slot1_device->auxspi_write(ARMCPU_ARM9, 8, adr & 1, (u16)val); return; case REG_AUXSPIDATA: - { - //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; - } + val = slot1_device->auxspi_transaction(ARMCPU_ARM9, val); + break; case REG_POWCNT1: writereg_POWCNT1(8,adr,val); break; @@ -3788,17 +3758,12 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) } case REG_AUXSPICNT: - write_auxspicnt(9, 16, 0, val); + slot1_device->auxspi_write(ARMCPU_ARM9, 16, 0, val); return; case REG_AUXSPIDATA: - { - //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; - } + val = slot1_device->auxspi_transaction(ARMCPU_ARM9, (u8)val); + break; case REG_DISPA_BG0CNT : //GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val); @@ -4474,6 +4439,10 @@ u8 FASTCALL _MMU_ARM9_read08(u32 adr) case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1D: case eng_3D_FOG_TABLE+0x1E: case eng_3D_FOG_TABLE+0x1F: return 0; + case REG_AUXSPICNT: + case REG_AUXSPICNT+1: + return (u8)slot1_device->auxspi_read(ARMCPU_ARM9, 8, adr & 1); + case REG_POWCNT1: case REG_POWCNT1+1: case REG_POWCNT1+2: @@ -4563,12 +4532,11 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr) case REG_IME : return (u16)MMU.reg_IME[ARMCPU_ARM9]; - case REG_IE : return (u16)MMU.reg_IE[ARMCPU_ARM9]; case REG_IE + 2 : return (u16)(MMU.reg_IE[ARMCPU_ARM9]>>16); - + case REG_IF: return MMU.gen_IF(); case REG_IF+2: return MMU.gen_IF()>>16; @@ -4579,7 +4547,7 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr) return read_timer(ARMCPU_ARM9,(adr&0xF)>>2); case REG_AUXSPICNT: - return MMU.AUX_SPI_CNT; + return slot1_device->auxspi_read(ARMCPU_ARM9, 16, 0); case REG_POWCNT1: case REG_POWCNT1+2: @@ -4835,17 +4803,12 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val) case REG_AUXSPICNT: case REG_AUXSPICNT+1: - write_auxspicnt(7, 8, adr & 1, val); - return; + slot1_device->auxspi_write(ARMCPU_ARM7, 8, adr & 1, (u16)val); + break; case REG_AUXSPIDATA: - { - //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 + val = slot1_device->auxspi_transaction(ARMCPU_ARM7, val); return; - } case REG_SPIDATA: // CrazyMax: 27 May 2013: BIOS write 8bit commands to flash controller when load firmware header @@ -4946,17 +4909,12 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) case REG_AUXSPICNT: - write_auxspicnt(7, 16, 0, val); - return; + slot1_device->auxspi_write(ARMCPU_ARM7, 16, 0, val); + return; case REG_AUXSPIDATA: - { - //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; - } + val = slot1_device->auxspi_transaction(ARMCPU_ARM7, val); + break; case REG_SPICNT : { @@ -5225,6 +5183,10 @@ u8 FASTCALL _MMU_ARM7_read08(u32 adr) case REG_DISPx_VCOUNT+1: return (nds.VCount>>8)&0xFF; case REG_WRAMSTAT: return MMU.WRAMCNT; + + case REG_AUXSPICNT: + case REG_AUXSPICNT+1: + return (u8)slot1_device->auxspi_read(ARMCPU_ARM7, 8, adr & 1); } return MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]]; @@ -5307,7 +5269,7 @@ u16 FASTCALL _MMU_ARM7_read16(u32 adr) break; case REG_AUXSPICNT: - return MMU.AUX_SPI_CNT; + return slot1_device->auxspi_read(ARMCPU_ARM7, 16, 0); case REG_KEYINPUT: //here is an example of what not to do: diff --git a/desmume/src/addons/slot1_retail_auto.cpp b/desmume/src/addons/slot1_retail_auto.cpp index 7a150889e..913c5c455 100644 --- a/desmume/src/addons/slot1_retail_auto.cpp +++ b/desmume/src/addons/slot1_retail_auto.cpp @@ -75,16 +75,26 @@ public: return mSelectedImplementation->read_GCDATAIN(PROCNUM); } - virtual u8 auxspi_transaction(int PROCNUM, u8 value) + virtual u8 auxspi_transaction(const u8 PROCNUM, u8 value) { return mSelectedImplementation->auxspi_transaction(PROCNUM, value); } - virtual void auxspi_reset(int PROCNUM) + virtual void auxspi_reset(const u8 PROCNUM) { mSelectedImplementation->auxspi_reset(PROCNUM); } + + virtual void auxspi_write(const u8 PROCNUM, const u8 size, const u8 adr, u16 cnt) + { + mSelectedImplementation->auxspi_write(PROCNUM, size, adr, cnt); + } + virtual u16 auxspi_read(const u8 PROCNUM, const u8 size, const u8 adr) + { + return mSelectedImplementation->auxspi_read(PROCNUM, size, adr); + } + virtual void post_fakeboot(int PROCNUM) { mSelectedImplementation->post_fakeboot(PROCNUM); diff --git a/desmume/src/addons/slot1_retail_mcrom.cpp b/desmume/src/addons/slot1_retail_mcrom.cpp index 7f6744d53..25ee8958c 100644 --- a/desmume/src/addons/slot1_retail_mcrom.cpp +++ b/desmume/src/addons/slot1_retail_mcrom.cpp @@ -50,15 +50,25 @@ public: protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0); } - virtual u8 auxspi_transaction(int PROCNUM, u8 value) + virtual u8 auxspi_transaction(const u8 PROCNUM, u8 value) { return g_Slot1Comp_MC.auxspi_transaction(PROCNUM,value); } - virtual void auxspi_reset(int PROCNUM) + virtual void auxspi_reset(const u8 PROCNUM) { g_Slot1Comp_MC.auxspi_reset(PROCNUM); } + + virtual void auxspi_write(const u8 PROCNUM, const u8 size, const u8 adr, u16 cnt) + { + g_Slot1Comp_MC.auxspi_write(PROCNUM, size, adr, cnt); + } + + virtual u16 auxspi_read(const u8 PROCNUM, const u8 size, const u8 adr) + { + return g_Slot1Comp_MC.auxspi_read(PROCNUM, size, adr); + } virtual void write_command(u8 PROCNUM, GC_Command command) { @@ -77,8 +87,8 @@ public: { rom.start(operation,protocol.address); } - - virtual void post_fakeboot(int PROCNUM) + + virtual void post_fakeboot(int PROCNUM) { // The BIOS leaves the card in NORMAL mode protocol.mode = eCardMode_NORMAL; diff --git a/desmume/src/addons/slot1_retail_mcrom_debug.cpp b/desmume/src/addons/slot1_retail_mcrom_debug.cpp index aa56abe81..46b9cd887 100644 --- a/desmume/src/addons/slot1_retail_mcrom_debug.cpp +++ b/desmume/src/addons/slot1_retail_mcrom_debug.cpp @@ -65,15 +65,25 @@ public: fs->rebuildFAT(pathData); } - virtual u8 auxspi_transaction(int PROCNUM, u8 value) + virtual u8 auxspi_transaction(const u8 PROCNUM, u8 value) { return g_Slot1Comp_MC.auxspi_transaction(PROCNUM,value); } - virtual void auxspi_reset(int PROCNUM) + virtual void auxspi_reset(const u8 PROCNUM) { g_Slot1Comp_MC.auxspi_reset(PROCNUM); } + + virtual void auxspi_write(const u8 PROCNUM, const u8 size, const u8 adr, u16 cnt) + { + g_Slot1Comp_MC.auxspi_write(PROCNUM, size, adr, cnt); + } + + virtual u16 auxspi_read(const u8 PROCNUM, const u8 size, const u8 adr) + { + return g_Slot1Comp_MC.auxspi_read(PROCNUM, size, adr); + } virtual void write_command(u8 PROCNUM, GC_Command command) { @@ -87,7 +97,7 @@ public: { return protocol.read_GCDATAIN(PROCNUM); } - + virtual void post_fakeboot(int PROCNUM) { // The BIOS leaves the card in NORMAL mode diff --git a/desmume/src/addons/slot1_retail_nand.cpp b/desmume/src/addons/slot1_retail_nand.cpp index 5ef130db4..7757affd1 100644 --- a/desmume/src/addons/slot1_retail_nand.cpp +++ b/desmume/src/addons/slot1_retail_nand.cpp @@ -233,7 +233,7 @@ public: break; } } - + virtual void post_fakeboot(int PROCNUM) { // The BIOS leaves the card in NORMAL mode diff --git a/desmume/src/addons/slot1comp_mc.cpp b/desmume/src/addons/slot1comp_mc.cpp index 035cfb3a1..42b544705 100644 --- a/desmume/src/addons/slot1comp_mc.cpp +++ b/desmume/src/addons/slot1comp_mc.cpp @@ -24,12 +24,59 @@ 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) +void Slot1Comp_MC::auxspi_reset(const u8 PROCNUM) { MMU_new.backupDevice.reset_command(); } +void Slot1Comp_MC::auxspi_write(const u8 PROCNUM, const u8 size, const u8 adr, u16 cnt) +{ + if (size == 8) + { + const u8 ofs = (adr << 3); + u8 oldCnt = T1ReadByte((u8*)&MMU.AUX_SPI_CNT, (1 - adr)); + cnt = (oldCnt << (8 - ofs)) | (cnt << ofs); + } + + MMU.AUX_SPI_CNT = cnt; + + //bool enabled = (cnt & (1 << 15))?true:false; + //bool irq = (cnt & (1 << 14))?true:false; + //bool spi = (cnt & (1 << 13))?true:false; + //bool cs = (cnt & (1 << 6))?true:false; + + //printf("MMU%c: write%02d%s to AUX cnt: %08X, CS:%d - %s%s\n", PROCNUM?'7':'9', size, (adr?"+1":""), cnt, cs, spi?"Backup":"NDS Slot", (cnt & (1 << 7))?" - BUSY":""); + + //if (!enabled && irq && !(cnt & 0x3) || spi) + if (!cnt) + { + //printf("MMU%c: reset command (cnt %04x)\n", PROCNUM?'7':'9', cnt); + auxspi_reset(PROCNUM); + } +} + +u16 Slot1Comp_MC::auxspi_read(const u8 PROCNUM, const u8 size, const u8 adr) +{ + u16 cnt = (MMU.AUX_SPI_CNT >> (adr << 3)); + + //bool cs = (cnt & (1 << 6))?true:false; + //bool spi = (cnt & (1 << 13))?true:false; + //printf("MMU%c: read%02d%s from AUX cnt: %08X, CS:%d - %s\n", PROCNUM?'7':'9', size, (adr?"+1":""), cnt, cs, spi?"Backup":"NDS Slot"); + + return cnt; +} + +u8 Slot1Comp_MC::auxspi_transaction(const u8 PROCNUM, u8 value) +{ + u16 cnt = MMU.AUX_SPI_CNT; + bool spi = (cnt & (1 << 13))?true:false; + bool cs = (cnt & (1 << 6))?true:false; + + if (spi) + { + value = MMU_new.backupDevice.data_command(value, PROCNUM); + MMU.AUX_SPI_CNT &= ~0x80; //remove busy flag + } + + return value; +} diff --git a/desmume/src/addons/slot1comp_mc.h b/desmume/src/addons/slot1comp_mc.h index e5dfe4f00..bfe6b3578 100644 --- a/desmume/src/addons/slot1comp_mc.h +++ b/desmume/src/addons/slot1comp_mc.h @@ -20,8 +20,10 @@ class Slot1Comp_MC { public: - u8 auxspi_transaction(int PROCNUM, u8 value); - void auxspi_reset(int PROCNUM); + u8 auxspi_transaction(const u8 PROCNUM, u8 value); + void auxspi_reset(const u8 PROCNUM); + void auxspi_write(const u8 PROCNUM, const u8 size, const u8 adr, u16 cnt); + u16 auxspi_read (const u8 PROCNUM, const u8 size, const u8 adr); }; extern Slot1Comp_MC g_Slot1Comp_MC; \ No newline at end of file diff --git a/desmume/src/slot1.h b/desmume/src/slot1.h index 417a1f6a3..9966705b4 100644 --- a/desmume/src/slot1.h +++ b/desmume/src/slot1.h @@ -76,11 +76,14 @@ public: //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; } + virtual u8 auxspi_transaction(const u8 PROCNUM, u8 value) { return 0x00; } //called when the auxspi burst is ended (SPI chipselect in is going low) - virtual void auxspi_reset(int PROCNUM) {} - + virtual void auxspi_reset(const u8 PROCNUM) {} + + virtual void auxspi_write(const u8 PROCNUM, const u8 size, const u8 adr, u16 cnt) {} + virtual u16 auxspi_read (const u8 PROCNUM, const u8 size, const u8 adr) { return 0x0000; } + //called when NDS_FakeBoot terminates, emulate in here the BIOS behaviour virtual void post_fakeboot(int PROCNUM) {}