Skip to content

Commit

Permalink
Proper ensata handshake on reconnection.
Browse files Browse the repository at this point in the history
  • Loading branch information
dlbuhtig4096 committed Oct 20, 2024
1 parent 7984eae commit 85d4004
Showing 1 changed file with 31 additions and 22 deletions.
53 changes: 31 additions & 22 deletions desmume/src/MMU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1835,31 +1835,40 @@ static void writereg_POWCNT1(const int size, const u32 adr, const u32 val)

static INLINE void MMU_IPCSync(u8 proc, u32 val)
{
//INFO("IPC%s sync 0x%04X (0x%02X|%02X)\n", proc?"7":"9", val, val >> 8, val & 0xFF);

u32 sync_l = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x180) & 0xFFFF;
u32 sync_r = T1ReadLong(MMU.MMU_MEM[proc^1][0x40], 0x180) & 0xFFFF;

sync_l = ( sync_l & 0x000F ) | ( val & 0x0F00 );
sync_r = ( sync_r & 0x6F00 ) | ( (val >> 8) & 0x000F );

sync_l |= val & 0x6000;

if(nds.ensataEmulation && proc==1 && nds.ensataIpcSyncCounter<9) {
u32 iteration = (val&0x0F00)>>8;

if(iteration==8-nds.ensataIpcSyncCounter)
nds.ensataIpcSyncCounter++;
else printf("ERROR: ENSATA IPC SYNC HACK FAILED; BAD THINGS MAY HAPPEN\n");

//for some reason, the arm9 doesn't handshake when ensata is detected.
//so we complete the protocol here, which is to mirror the values 8..0 back to
//the arm7 as they are written by the arm7
sync_r &= 0xF0FF;
sync_r |= (iteration<<8);
sync_l &= 0xFFF0;
sync_l |= iteration;
u32 iterThis = (val & 0x0F00) >> 8;

sync_l = ( sync_l & 0x000F ) | ( val & 0x6F00 );
sync_r = ( sync_r & 0x6F00 ) | ( iterThis );

// For some reason, the arm9 doesn't handshake when ensata is detected.
// So we complete the protocol here, which is to mirror the values 8..0 back to
// The arm7 as they are written by the arm7
if (nds.ensataEmulation) {

if (proc) {
// However this hack would break soft reset because it also syncs through ipcsync.
// So we have to add some additional checks to ensure that it's handshake instead of reset.
if ((iterThis & 8) || (nds.ensataIpcSyncCounter)) {
// sync_r = (sync_r & 0xF0FF) | (iterThis << 8); // This is not necessary.
sync_l = (sync_l & 0xFFF0) | iterThis;
nds.ensataIpcSyncCounter = iterThis;
}
}
else {
// After ensata handshake, arm9 will write 0x100 as a signal if Ensata is detected.
// This will prevent reset from working, so we have to ignore this.
if (nds.ensataHandshake == ENSATA_HANDSHAKE_complete) {
nds.ensataHandshake = ENSATA_HANDSHAKE_none;
return;
}
}
}

// printf("IPCSync(%d, %04x): %04x %04x %d\n", proc, val, sync_l, sync_r, nds.ensataIpcSyncCounter);

T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x180, sync_l);
T1WriteLong(MMU.MMU_MEM[proc^1][0x40], 0x180, sync_r);

Expand Down Expand Up @@ -4969,7 +4978,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
//todo - these are usually write only regs (these and 1000 more)
//shouldnt we block them from getting written? ugh
case eng_3D_CLIPMTX_RESULT:
if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_none && val==0x2468ace0)
if(nds.ensataEmulation /* && nds.ensataHandshake == ENSATA_HANDSHAKE_none */&& val==0x2468ace0)
{
printf("ENSATA HANDSHAKE BEGIN\n");
nds.ensataHandshake = ENSATA_HANDSHAKE_query;
Expand Down

0 comments on commit 85d4004

Please sign in to comment.