diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 7a2046131..74dafe124 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -2460,30 +2460,27 @@ 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... + //u16 oldCnt = MMU.AUX_SPI_CNT; + bool csOld = (MMU.AUX_SPI_CNT & (1 << 6))?true:false; 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; - } + T1WriteByte((u8*)&MMU.AUX_SPI_CNT, adr, val); + break; + } + + bool cs = (MMU.AUX_SPI_CNT & (1 << 6))?true:false; + + //printf("MMU%c: cnt %04X, old %04X\n", proc?'7':'9', MMU.AUX_SPI_CNT, oldCnt); + + if (!cs && csOld) + { + //printf("MMU%c: CS changed from HIGH to LOW *****\n", proc?'7':'9'); + slot1_device->auxspi_reset(proc); } } @@ -3115,7 +3112,7 @@ bool validateIORegsRead(u32 addr, u8 size) return true; default: - //printf("MMU9 read%02d from undefined register %08Xh = %08Xh (PC:%08X)\n", size, addr, T1ReadLong(MMU.ARM9_REG, addr & 0x00FFFFFF), ARMPROC.instruct_adr); + printf("MMU9 read%02d from undefined register %08Xh = %08Xh (PC:%08X)\n", size, addr, T1ReadLong(MMU.ARM9_REG, addr & 0x00FFFFFF), ARMPROC.instruct_adr); return false; } } @@ -3788,7 +3785,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) } case REG_AUXSPICNT: - write_auxspicnt(9, 16, 0, val); + write_auxspicnt(ARMCPU_ARM9, 16, 0, val); return; case REG_AUXSPIDATA: @@ -4835,7 +4832,7 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val) case REG_AUXSPICNT: case REG_AUXSPICNT+1: - write_auxspicnt(7, 8, adr & 1, val); + write_auxspicnt(ARMCPU_ARM7, 8, adr & 1, val); return; case REG_AUXSPIDATA: @@ -4946,7 +4943,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) case REG_AUXSPICNT: - write_auxspicnt(7, 16, 0, val); + write_auxspicnt(ARMCPU_ARM7, 16, 0, val); return; case REG_AUXSPIDATA: diff --git a/desmume/src/addons/slot1comp_mc.cpp b/desmume/src/addons/slot1comp_mc.cpp index 035cfb3a1..3b5cd7969 100644 --- a/desmume/src/addons/slot1comp_mc.cpp +++ b/desmume/src/addons/slot1comp_mc.cpp @@ -26,7 +26,7 @@ Slot1Comp_MC g_Slot1Comp_MC; u8 Slot1Comp_MC::auxspi_transaction(int PROCNUM, u8 value) { - return MMU_new.backupDevice.data_command((u8)value,ARMCPU_ARM9); + return MMU_new.backupDevice.data_command(value, PROCNUM); } void Slot1Comp_MC::auxspi_reset(int PROCNUM) { diff --git a/desmume/src/mc.cpp b/desmume/src/mc.cpp index 329d7935f..264a60391 100644 --- a/desmume/src/mc.cpp +++ b/desmume/src/mc.cpp @@ -28,6 +28,7 @@ #include "NDSSystem.h" #include "utils/advanscene.h" +//#define _ENABLE_MOTION #define BM_CMD_AUTODETECT 0xFF #define BM_CMD_WRITESTATUS 0x01 @@ -106,7 +107,7 @@ void backup_setManualBackupType(int type) bool BackupDevice::save_state(EMUFILE* os) { - u32 version = 2; + u32 version = 3; //v0 write32le(version,os); write32le(write_enable,os); @@ -121,6 +122,8 @@ bool BackupDevice::save_state(EMUFILE* os) //v2 write8le(motionInitState,os); write8le(motionFlag,os); + //v3 + writebool(reset_command_state,os); return true; } @@ -142,12 +145,18 @@ bool BackupDevice::load_state(EMUFILE* is) } if(version>=1) read32le(&addr,is); + if(version>=2) { read8le(&motionInitState,is); read8le(&motionFlag,is); } + if(version>=3) + { + readbool(&reset_command_state,is); + } + return true; } @@ -182,6 +191,7 @@ void BackupDevice::reset_hardware() motionInitState = MOTION_INIT_STATE_IDLE; motionFlag = MOTION_FLAG_NONE; state = DETECTING; + reset_command_state = false; flushPending = false; lazyFlushPending = false; } @@ -223,17 +233,9 @@ u8 BackupDevice::searchFileSaveType(u32 size) return 0xFF; } -void BackupDevice::reset_command() +void BackupDevice::detect() { - //printf("MC RESET\n"); - //for a performance hack, save files are only flushed after each reset command - //(hopefully, after each page) - if(flushPending) - { - flush(); - flushPending = false; - lazyFlushPending = false; - } + if (!reset_command_state) return; if(state == DETECTING && data_autodetect.size()>0) { @@ -285,13 +287,33 @@ void BackupDevice::reset_command() data_autodetect.resize(0); flush(); } - - com = 0; } + +void BackupDevice::checkReset() +{ + if (reset_command_state) + { + //printf("MC : reset command\n"); + + //for a performance hack, save files are only flushed after each reset command + //(hopefully, after each page) + if(flushPending) + { + flush(); + flushPending = false; + lazyFlushPending = false; + } + + com = 0; + reset_command_state = false; + } +} + u8 BackupDevice::data_command(u8 val, int cpu) { - //printf("MC CMD: (%02X) %02X\n",com,val); + //printf("MC%c : cmd %02X, val %02X\n", cpu?'7':'9', com, val); +#ifdef _ENABLE_MOTION //motion: some guessing here... hope it doesn't break anything if(com == BM_CMD_READLOW && motionInitState == MOTION_INIT_STATE_RECEIVED_4_B && val == 0) { @@ -306,6 +328,7 @@ u8 BackupDevice::data_command(u8 val, int cpu) { return 0; } +#endif if(com == BM_CMD_READLOW || com == BM_CMD_WRITELOW) { @@ -320,6 +343,7 @@ u8 BackupDevice::data_command(u8 val, int cpu) //just buffer the data until we're no longer detecting data_autodetect.push_back(val); val = 0; + detect(); } else { @@ -359,6 +383,7 @@ u8 BackupDevice::data_command(u8 val, int cpu) } addr++; + checkReset(); } } } @@ -366,6 +391,7 @@ u8 BackupDevice::data_command(u8 val, int cpu) { //handle request to read status //LOG("Backup Memory Read Status: %02X\n", write_enable << 1); + checkReset(); return (write_enable << 1) | (3<<2); } else @@ -375,6 +401,7 @@ u8 BackupDevice::data_command(u8 val, int cpu) { case 0: break; //?? +#ifdef _ENABLE_MOTION case 0xFE: if(motionInitState == MOTION_INIT_STATE_IDLE) { motionInitState = MOTION_INIT_STATE_FE; return 0; } break; @@ -402,28 +429,36 @@ u8 BackupDevice::data_command(u8 val, int cpu) return 0; } break; +#endif - case 8: + case 0x08: // IrDA - Pokemon HG/SS printf("COMMAND%c: Unverified Backup Memory command: %02X FROM %08X\n",(cpu==ARMCPU_ARM9)?'9':'7',val, (cpu==ARMCPU_ARM9)?NDS_ARM9.instruct_adr:NDS_ARM7.instruct_adr); val = 0xAA; + + checkReset(); break; case BM_CMD_WRITEDISABLE: +#ifdef _ENABLE_MOTION switch(motionInitState) { case MOTION_INIT_STATE_IDLE: motionInitState = MOTION_INIT_STATE_RECEIVED_4; break; case MOTION_INIT_STATE_RECEIVED_4: motionInitState = MOTION_INIT_STATE_RECEIVED_4_B; break; } +#endif write_enable = FALSE; + checkReset(); break; case BM_CMD_READSTATUS: com = BM_CMD_READSTATUS; val = (write_enable << 1) | (3<<2); + checkReset(); break; case BM_CMD_WRITEENABLE: write_enable = TRUE; + checkReset(); break; case BM_CMD_WRITELOW: @@ -456,8 +491,10 @@ u8 BackupDevice::data_command(u8 val, int cpu) break; } //switch(val) +#ifdef _ENABLE_MOTION //motion control state machine broke, return to ground motionInitState = MOTION_INIT_STATE_IDLE; +#endif } return val; } diff --git a/desmume/src/mc.h b/desmume/src/mc.h index 5001f855d..80e6c6d03 100644 --- a/desmume/src/mc.h +++ b/desmume/src/mc.h @@ -76,7 +76,7 @@ public: bool load_state(EMUFILE* is); //commands from mmu - void reset_command(); + void reset_command() { reset_command_state = true; }; u8 data_command(u8,int); std::vector data; @@ -123,9 +123,12 @@ public: bool isMovieMode; private: + void detect(); + std::string filename; bool write_enable; //is write enabled? + bool reset_command_state; u32 com; //persistent command actually handled u32 addr_size, addr_counter; u32 addr; @@ -155,6 +158,8 @@ private: void resize(u32 size); void resize(u32 size, u8 val); + + void checkReset(); };