Merge pull request #851 from dlbuhtig4096/master
Fix ensata sound register emulation.
This commit is contained in:
commit
fff5659879
|
@ -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)
|
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_l = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x180) & 0xFFFF;
|
||||||
u32 sync_r = T1ReadLong(MMU.MMU_MEM[proc^1][0x40], 0x180) & 0xFFFF;
|
u32 sync_r = T1ReadLong(MMU.MMU_MEM[proc^1][0x40], 0x180) & 0xFFFF;
|
||||||
|
u32 iter = (val & 0x0F00) >> 8;
|
||||||
|
|
||||||
sync_l = ( sync_l & 0x000F ) | ( val & 0x0F00 );
|
sync_l = ( sync_l & 0x000F ) | ( val & 0x6F00 );
|
||||||
sync_r = ( sync_r & 0x6F00 ) | ( (val >> 8) & 0x000F );
|
sync_r = ( sync_r & 0x6F00 ) | ( iter );
|
||||||
|
|
||||||
sync_l |= val & 0x6000;
|
// 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(nds.ensataEmulation && proc==1 && nds.ensataIpcSyncCounter<9) {
|
if (proc) {
|
||||||
u32 iteration = (val&0x0F00)>>8;
|
// 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(iteration==8-nds.ensataIpcSyncCounter)
|
if ((iter & 8) || (nds.ensataIpcSyncCounter)) {
|
||||||
nds.ensataIpcSyncCounter++;
|
// sync_r = (sync_r & 0xF0FF) | (iter << 8); // This is not necessary.
|
||||||
else printf("ERROR: ENSATA IPC SYNC HACK FAILED; BAD THINGS MAY HAPPEN\n");
|
sync_l = (sync_l & 0xFFF0) | iter;
|
||||||
|
nds.ensataIpcSyncCounter = iter;
|
||||||
//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
|
else {
|
||||||
sync_r &= 0xF0FF;
|
// After ensata handshake, arm9 will write 0x100 as a signal if Ensata is detected.
|
||||||
sync_r |= (iteration<<8);
|
// This will prevent reset from working, so we have to ignore this.
|
||||||
sync_l &= 0xFFF0;
|
if (nds.ensataHandshake == ENSATA_HANDSHAKE_complete) {
|
||||||
sync_l |= iteration;
|
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][0x40], 0x180, sync_l);
|
||||||
T1WriteLong(MMU.MMU_MEM[proc^1][0x40], 0x180, sync_r);
|
T1WriteLong(MMU.MMU_MEM[proc^1][0x40], 0x180, sync_r);
|
||||||
|
|
||||||
|
@ -2475,6 +2484,7 @@ bool validateIORegsWrite(u32 addr, u8 size, u32 val)
|
||||||
if(addrMasked == eng_3D_CLIPMTX_RESULT) return true;
|
if(addrMasked == eng_3D_CLIPMTX_RESULT) return true;
|
||||||
if(addrMasked == 0x04FFF000) return true;
|
if(addrMasked == 0x04FFF000) return true;
|
||||||
if(addrMasked == 0x04FFF010) return true;
|
if(addrMasked == 0x04FFF010) return true;
|
||||||
|
if(addrMasked == 0x04FFF200) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (addrMasked)
|
switch (addrMasked)
|
||||||
|
@ -3819,6 +3829,11 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
|
||||||
MMU_VRAMmapControl(adr-REG_VRAMCNTA, val);
|
MMU_VRAMmapControl(adr-REG_VRAMCNTA, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
// ensata sound register
|
||||||
|
case 0x04FFF200:
|
||||||
|
break;
|
||||||
|
|
||||||
#ifdef LOG_CARD
|
#ifdef LOG_CARD
|
||||||
case 0x040001A0 : /* TODO (clear): ??? */
|
case 0x040001A0 : /* TODO (clear): ??? */
|
||||||
case 0x040001A1 :
|
case 0x040001A1 :
|
||||||
|
@ -4963,7 +4978,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
||||||
//todo - these are usually write only regs (these and 1000 more)
|
//todo - these are usually write only regs (these and 1000 more)
|
||||||
//shouldnt we block them from getting written? ugh
|
//shouldnt we block them from getting written? ugh
|
||||||
case eng_3D_CLIPMTX_RESULT:
|
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");
|
printf("ENSATA HANDSHAKE BEGIN\n");
|
||||||
nds.ensataHandshake = ENSATA_HANDSHAKE_query;
|
nds.ensataHandshake = ENSATA_HANDSHAKE_query;
|
||||||
|
@ -5482,6 +5497,10 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr)
|
||||||
case REG_KEYINPUT:
|
case REG_KEYINPUT:
|
||||||
LagFrameFlag=0;
|
LagFrameFlag=0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Ensata sound register
|
||||||
|
case 0x04FFF200:
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
|
return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,8 @@ void OpenConsole()
|
||||||
//stdout is already connected to something. keep using it and dont let the console interfere
|
//stdout is already connected to something. keep using it and dont let the console interfere
|
||||||
bool shouldRedirectStdout = fileType == FILE_TYPE_UNKNOWN;
|
bool shouldRedirectStdout = fileType == FILE_TYPE_UNKNOWN;
|
||||||
bool attached = false;
|
bool attached = false;
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (!AllocConsole())
|
if (!AllocConsole())
|
||||||
{
|
{
|
||||||
HMODULE lib = LoadLibrary("kernel32.dll");
|
HMODULE lib = LoadLibrary("kernel32.dll");
|
||||||
|
@ -143,6 +145,9 @@ void OpenConsole()
|
||||||
SetConsoleCP(GetACP());
|
SetConsoleCP(GetACP());
|
||||||
SetConsoleOutputCP(GetACP());
|
SetConsoleOutputCP(GetACP());
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
attached = AttachConsole(-1) || AllocConsole();
|
||||||
|
#endif
|
||||||
|
|
||||||
//newer and improved console title:
|
//newer and improved console title:
|
||||||
SetConsoleTitleW(SkipEverythingButProgramInCommandLine(GetCommandLineW()).c_str());
|
SetConsoleTitleW(SkipEverythingButProgramInCommandLine(GetCommandLineW()).c_str());
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
#define BUFFER_SIZE 100
|
#define BUFFER_SIZE 100
|
||||||
HANDLE hConsole;
|
HANDLE hConsole = NULL;
|
||||||
void OpenConsole()
|
void OpenConsole()
|
||||||
{
|
{
|
||||||
COORD csize;
|
COORD csize;
|
||||||
|
@ -41,27 +41,33 @@ void OpenConsole()
|
||||||
//dont do anything if we're already attached
|
//dont do anything if we're already attached
|
||||||
if (hConsole) return;
|
if (hConsole) return;
|
||||||
|
|
||||||
|
#if 0
|
||||||
//attach to an existing console (if we can; this is circuitous because AttachConsole wasnt added until XP)
|
//attach to an existing console (if we can; this is circuitous because AttachConsole wasnt added until XP)
|
||||||
//remember to abstract this late bound function notion if we end up having to do this anywhere else
|
//remember to abstract this late bound function notion if we end up having to do this anywhere else
|
||||||
bool attached = false;
|
bool attached = false;
|
||||||
HMODULE lib = LoadLibrary("kernel32.dll");
|
|
||||||
if(lib)
|
// kernel32.dll is always loaded on windows.
|
||||||
|
HMODULE lib = GetModuleHandleA("kernel32.dll"); // LoadLibrary("kernel32.dll");
|
||||||
|
if (lib)
|
||||||
{
|
{
|
||||||
typedef BOOL (WINAPI *_TAttachConsole)(DWORD dwProcessId);
|
typedef BOOL (WINAPI *_TAttachConsole)(DWORD dwProcessId);
|
||||||
_TAttachConsole _AttachConsole = (_TAttachConsole)GetProcAddress(lib,"AttachConsole");
|
_TAttachConsole _AttachConsole = (_TAttachConsole)GetProcAddress(lib,"AttachConsole");
|
||||||
if(_AttachConsole)
|
if (_AttachConsole)
|
||||||
{
|
{
|
||||||
if(_AttachConsole(-1))
|
attached = (bool)_AttachConsole(-1);
|
||||||
attached = true;
|
|
||||||
}
|
}
|
||||||
FreeLibrary(lib);
|
// You cannot free kernel32.dll
|
||||||
|
// FreeLibrary(lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if we failed to attach, then alloc a new console
|
//if we failed to attach, then alloc a new console
|
||||||
if(!attached)
|
if (!attached)
|
||||||
{
|
{
|
||||||
AllocConsole();
|
AllocConsole();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (!AttachConsole(-1)) { AllocConsole(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
@ -91,9 +97,12 @@ void OpenConsole()
|
||||||
srect.Right = srect.Left + 99;
|
srect.Right = srect.Left + 99;
|
||||||
srect.Bottom = srect.Top + 64;
|
srect.Bottom = srect.Top + 64;
|
||||||
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &srect);
|
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &srect);
|
||||||
SetConsoleCP(GetACP());
|
|
||||||
SetConsoleOutputCP(GetACP());
|
// Use default code page.
|
||||||
if(attached) printf("\n");
|
// SetConsoleCP(GetACP());
|
||||||
|
// SetConsoleOutputCP(GetACP());
|
||||||
|
|
||||||
|
if (attached) printf("\n");
|
||||||
printf("%s\n",_TITLE);
|
printf("%s\n",_TITLE);
|
||||||
printf("- compiled: %s %s\n\n",__DATE__,__TIME__);
|
printf("- compiled: %s %s\n\n",__DATE__,__TIME__);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue