diff --git a/Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp index c7b8483b2599..51279bf866e6 100644 --- a/Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp @@ -58,7 +58,7 @@ bool CBoot::EmulatedBS2_GC() Memory::Write_U32(0x10000006, 0x8000002C); // Console type - DevKit (retail ID == 0x00000003) see yagcd 4.2.1.1.2 Memory::Write_U32(SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC - ? 0 : 1, 0x800000CC); // fake the VI Init of the IPL (yagcd 4.2.1.4) + ? 6 : 6, 0x800000CC); // fake the VI Init of the IPL (yagcd 4.2.1.4) Memory::Write_U32(0x01000000, 0x800000d0); // ARAM Size. 16MB main + 4/16/32MB external (retail consoles have no external ARAM) @@ -154,6 +154,18 @@ bool CBoot::EmulatedBS2_GC() // If we have any patches that need to be applied very early, here's a good place PatchEngine::ApplyFramePatches(); + + int GCAM = ((SConfig::GetInstance().m_SIDevice[0] == SIDEVICE_AM_BASEBOARD) + && (SConfig::GetInstance().m_EXIDevice[2] == EXIDEVICE_AM_BASEBOARD)) + ? 1 : 0; + + //Clear mediaboard encryption seeds + if(GCAM) + { + char *ptr = (char*)(Memory::GetPointer(0)); + memset( ptr, 0, 12 ); + } + return true; } diff --git a/Source/Core/Core/Src/DSP/DSPCore.cpp b/Source/Core/Core/Src/DSP/DSPCore.cpp index 64206b3ee01d..4126f9973fc3 100644 --- a/Source/Core/Core/Src/DSP/DSPCore.cpp +++ b/Source/Core/Core/Src/DSP/DSPCore.cpp @@ -112,14 +112,14 @@ static bool VerifyRoms(const char *irom_filename, const char *coef_filename) return false; } - if (rom_idx == 1) - PanicAlertT("You are using an old free DSP ROM made by the Dolphin Team.\n" - "Only games using the Zelda UCode will work correctly.\n"); - - if (rom_idx == 2) - PanicAlertT("You are using a free DSP ROM made by the Dolphin Team.\n" - "All Wii games will work correctly, and most GC games should " - "also work fine, but the GBA/IPL/CARD UCodes will not work.\n"); + //if (rom_idx == 1) + // PanicAlertT("You are using an old free DSP ROM made by the Dolphin Team.\n" + // "Only games using the Zelda UCode will work correctly.\n"); + + //if (rom_idx == 2) + // PanicAlertT("You are using a free DSP ROM made by the Dolphin Team.\n" + // "All Wii games will work correctly, and most GC games should " + // "also work fine, but the GBA/IPL/CARD UCodes will not work.\n"); return true; } diff --git a/Source/Core/Core/Src/HW/DVDInterface.cpp b/Source/Core/Core/Src/HW/DVDInterface.cpp index 64cc123bc6d2..192a5ed6511c 100644 --- a/Source/Core/Core/Src/HW/DVDInterface.cpp +++ b/Source/Core/Core/Src/HW/DVDInterface.cpp @@ -195,13 +195,19 @@ static u32 CurrentStart; static u32 LoopLength; static u32 CurrentLength; +static FILE *m_netcfg; +static FILE *m_netctrl; +static FILE *m_dimm; +static u32 m_protocolversion; + u32 g_ErrorCode = 0; bool g_bDiscInside = false; bool g_bStream = false; int tc = 0; // GC-AM only -static unsigned char media_buffer[0x40]; +static unsigned char media_buffer[0x60]; +static unsigned char media_reply_buffer[0x20]; // Needed because data and streaming audio access needs to be managed by the "drive" // (both requests can happen at the same time, audio takes precedence) @@ -248,6 +254,8 @@ void TransferComplete(u64 userdata, int cyclesLate) void Init() { + char FilePath[_MAX_PATH]; + m_DISR.Hex = 0; m_DICVR.Hex = 0; m_DICMDBUF[0].Hex= 0; @@ -266,6 +274,42 @@ void Init() CurrentStart = 0; CurrentLength = 0; + m_protocolversion = 2; + + memset( media_buffer, 0, sizeof(media_buffer) ); + + m_netcfg = fopen("User/trinetcfg.bin","rb+"); + if( m_netcfg == (FILE*)NULL ) + { + m_netcfg = fopen("User/trinetcfg.bin","wb+"); + if( m_netcfg == (FILE*)NULL ) + { + PanicAlertT( "AM-BB Failed to open network config file" ); + } + } + + m_netctrl = fopen("User/trinetctrl.bin","rb+"); + if( m_netctrl == (FILE*)NULL ) + { + m_netctrl = fopen("User/trinetctrl.bin","wb+"); + if( m_netctrl == (FILE*)NULL ) + { + PanicAlertT( "AM-BB Failed to open network control file" ); + } + } + + sprintf_s( FilePath, _MAX_PATH, "User/tridimm_%s.bin", SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str() ); + + m_dimm = fopen( FilePath, "rb+" ); + if( m_dimm == (FILE*)NULL ) + { + m_dimm = fopen( FilePath, "wb+" ); + if( m_dimm == (FILE*)NULL ) + { + PanicAlertT( "AM-BB Failed to open DIMM file" ); + } + } + g_bStream = false; ejectDisc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback); @@ -561,13 +605,12 @@ void ExecuteCommand(UDICR& _DICR) if (GCAM) { - ERROR_LOG(DVDINTERFACE, + m_DICMDBUF[0].Hex <<= 24; + + NOTICE_LOG(DVDINTERFACE, "DVD: %08x, %08x, %08x, DMA=addr:%08x,len:%08x,ctrl:%08x", - m_DICMDBUF[0].Hex, m_DICMDBUF[1].Hex, m_DICMDBUF[2].Hex, + m_DICMDBUF[0].Hex, m_DICMDBUF[1].Hex<<2, m_DICMDBUF[2].Hex, m_DIMAR.Hex, m_DILENGTH.Hex, m_DICR.Hex); - // decrypt command. But we have a zero key, that simplifies things a lot. - // If you get crazy dvd command errors, make sure 0x80000000 - 0x8000000c is zero'd - m_DICMDBUF[0].Hex <<= 24; } @@ -576,9 +619,10 @@ void ExecuteCommand(UDICR& _DICR) case DVDLowInquiry: if (GCAM) { - // 0x29484100... - // was 21 i'm not entirely sure about this, but it works well. - m_DIIMMBUF.Hex = 0x29484100; + if( m_protocolversion == 2 ) + m_DIIMMBUF.Hex = 0xA9484100; + else + m_DIIMMBUF.Hex = 0x21000000; } else { @@ -622,50 +666,99 @@ void ExecuteCommand(UDICR& _DICR) if (GCAM) { + u32 len = m_DILENGTH.Length / 4; if (iDVDOffset & 0x80000000) // read request to hardware buffer { - u32 len = m_DILENGTH.Length / 4; switch (iDVDOffset) { case 0x80000000: - ERROR_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD STATUS (80000000)"); + NOTICE_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD STATUS (80000000)"); for (u32 i = 0; i < len; i++) Memory::Write_U32(0, m_DIMAR.Address + i * 4); break; + case 0x84000020: + NOTICE_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD STATUS (1) (84000020)"); + if( m_protocolversion == 2 ) + { + memcpy(Memory::GetPointer(m_DIMAR.Address), media_reply_buffer, m_DILENGTH.Length ); + + NOTICE_LOG(DVDINTERFACE, "GC-AM: %08x %08x %08x %08x", Memory::Read_U32(m_DIMAR.Address), + Memory::Read_U32(m_DIMAR.Address+4), + Memory::Read_U32(m_DIMAR.Address+8), + Memory::Read_U32(m_DIMAR.Address+12) ); + NOTICE_LOG(DVDINTERFACE, "GC-AM: %08x %08x %08x %08x", Memory::Read_U32(m_DIMAR.Address+16), + Memory::Read_U32(m_DIMAR.Address+20), + Memory::Read_U32(m_DIMAR.Address+24), + Memory::Read_U32(m_DIMAR.Address+28) ); + } + else + { + for (u32 i = 0; i < len; i++) + Memory::Write_U32(0, m_DIMAR.Address + i * 4); + } + break; case 0x80000040: - ERROR_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD STATUS (2) (80000040)"); + NOTICE_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD STATUS (2) (80000040)"); for (u32 i = 0; i < len; i++) Memory::Write_U32(~0, m_DIMAR.Address + i * 4); Memory::Write_U32(0x00000020, m_DIMAR.Address); // DIMM SIZE, LE Memory::Write_U32(0x4743414D, m_DIMAR.Address + 4); // GCAM signature break; case 0x80000120: - ERROR_LOG(DVDINTERFACE, "GC-AM: READ FIRMWARE STATUS (80000120)"); + NOTICE_LOG(DVDINTERFACE, "GC-AM: READ FIRMWARE STATUS (80000120)"); for (u32 i = 0; i < len; i++) Memory::Write_U32(0x01010101, m_DIMAR.Address + i * 4); break; case 0x80000140: - ERROR_LOG(DVDINTERFACE, "GC-AM: READ FIRMWARE STATUS (80000140)"); + NOTICE_LOG(DVDINTERFACE, "GC-AM: READ FIRMWARE STATUS (80000140)"); for (u32 i = 0; i < len; i++) Memory::Write_U32(0x01010101, m_DIMAR.Address + i * 4); break; - case 0x84000020: - ERROR_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD STATUS (1) (84000020)"); - for (u32 i = 0; i < len; i++) - Memory::Write_U32(0x00000000, m_DIMAR.Address + i * 4); - break; default: - ERROR_LOG(DVDINTERFACE, "GC-AM: UNKNOWN MEDIA BOARD LOCATION %x", iDVDOffset); + NOTICE_LOG(DVDINTERFACE, "GC-AM: UNKNOWN MEDIA BOARD LOCATION %x", iDVDOffset); break; } break; } + else if( (iDVDOffset >= 0x1F000000) && (iDVDOffset <= 0x1F300000) ) + { + u32 Offset = iDVDOffset - 0x1F000000; + + NOTICE_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD DIMM MEMORY (%08X)", Offset ); + + fseek( m_dimm, Offset, SEEK_SET ); + fread( Memory::GetPointer(m_DIMAR.Address), sizeof(char), len, m_dimm ); + } else if ((iDVDOffset == 0x1f900000) || (iDVDOffset == 0x1f900020)) { - ERROR_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD COMM AREA (1f900020)"); + NOTICE_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD COMM AREA (1F900020)"); memcpy(Memory::GetPointer(m_DIMAR.Address), media_buffer + iDVDOffset - 0x1f900000, m_DILENGTH.Length); - for (u32 i = 0; i < m_DILENGTH.Length; i += 4) - ERROR_LOG(DVDINTERFACE, "GC-AM: %08x", Memory::Read_U32(m_DIMAR.Address + i)); + NOTICE_LOG(DVDINTERFACE, "GC-AM: %08x %08x %08x %08x", Memory::Read_U32(m_DIMAR.Address), + Memory::Read_U32(m_DIMAR.Address+4), + Memory::Read_U32(m_DIMAR.Address+8), + Memory::Read_U32(m_DIMAR.Address+12) ); + NOTICE_LOG(DVDINTERFACE, "GC-AM: %08x %08x %08x %08x", Memory::Read_U32(m_DIMAR.Address+16), + Memory::Read_U32(m_DIMAR.Address+20), + Memory::Read_U32(m_DIMAR.Address+24), + Memory::Read_U32(m_DIMAR.Address+28) ); + break; + } else if( iDVDOffset == 0x1FFEFFE0 ) + { + NOTICE_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD NETWORK CONTROL (0x1FFEFFE0)"); + for (u32 i = 0; i < len; i++) + Memory::Write_U32(0x00000000, m_DIMAR.Address + i * 4); + + fseek( m_netctrl, 0, SEEK_SET ); + fread( Memory::GetPointer(m_DIMAR.Address), sizeof(char), m_DILENGTH.Length, m_netctrl ); + + break; + } else if( (iDVDOffset == 0) && (m_DILENGTH.Length == 0x80) ) { + + NOTICE_LOG(DVDINTERFACE, "GC-AM: READ MEDIA BOARD NETWORK CONFIG"); + + fseek( m_netcfg, 0, SEEK_SET ); + fread( Memory::GetPointer(m_DIMAR.Address), sizeof(char), m_DILENGTH.Length, m_netcfg ); + break; } } @@ -679,13 +772,14 @@ void ExecuteCommand(UDICR& _DICR) break; case 0x40: // Read DiscID + { _dbg_assert_(DVDINTERFACE, m_DICMDBUF[1].Hex == 0); _dbg_assert_(DVDINTERFACE, m_DICMDBUF[2].Hex == m_DILENGTH.Length); _dbg_assert_(DVDINTERFACE, m_DILENGTH.Length == 0x20); if (!DVDRead(m_DICMDBUF[1].Hex, m_DIMAR.Address, m_DILENGTH.Length)) PanicAlertT("Can't read from DVD_Plugin - DVD-Interface: Fatal Error"); WARN_LOG(DVDINTERFACE, "Read DiscID %08x", Memory::Read_U32(m_DIMAR.Address)); - break; + } break; default: _dbg_assert_msg_(DVDINTERFACE, 0, "Unknown Read Subcommand"); @@ -710,23 +804,25 @@ void ExecuteCommand(UDICR& _DICR) ERROR_LOG(DVDINTERFACE, "GC-AM: 0xAA, DMABuffer=%08x, DMALength=%08x", m_DIMAR.Address, m_DILENGTH.Length); u32 iDVDOffset = m_DICMDBUF[1].Hex << 2; unsigned int len = m_DILENGTH.Length; - int offset = iDVDOffset - 0x1F900000; + u32 offset = iDVDOffset - 0x1F900000; /* if (iDVDOffset == 0x84800000) { - ERROR_LOG(DVDINTERFACE, "Firmware upload"); + ERROR_LOG(DVDINTERFACE, "firmware upload"); } else*/ - if ((offset < 0) || ((offset + len) > 0x40) || len > 0x40) + + // Protocol version 2.xx and higher + if( (iDVDOffset >= 0x84000000) && (iDVDOffset < 0x84000060) ) { + offset = iDVDOffset - 0x84000000; + u32 addr = m_DIMAR.Address; - if (iDVDOffset == 0x84800000) - { - ERROR_LOG(DVDINTERFACE, "FIRMWARE UPLOAD"); - } - else + memcpy(media_buffer + offset, Memory::GetPointer(addr), len); + + if( (iDVDOffset == 0x84000040) && (media_buffer[0x40] == 1 ) ) { - ERROR_LOG(DVDINTERFACE, "ILLEGAL MEDIA WRITE"); + GCAMExecuteCommand(); } while (len >= 4) @@ -736,19 +832,57 @@ void ExecuteCommand(UDICR& _DICR) len -= 4; iDVDOffset += 4; } + } - else + // Set IP address + else if( iDVDOffset == 0x1F800200 ) + { + NOTICE_LOG(DVDINTERFACE, "MEDIA BOARD SET IP:%.13s", Memory::GetPointer(m_DIMAR.Address) ); + } + // DIMM memory + else if( (iDVDOffset >= 0x1F000000) && (iDVDOffset <= 0x1F300000) ) + { + u32 Offset = iDVDOffset - 0x1F000000; + NOTICE_LOG(DVDINTERFACE, "WRITE MEDIA BOARD DIMM MEMORY (%08X)", Offset ); + fseek( m_dimm, Offset, SEEK_SET ); + fwrite( Memory::GetPointer(m_DIMAR.Address), sizeof(char), len, m_dimm ); + fflush( m_dimm ); + } + else if( (iDVDOffset >= 0) && (iDVDOffset <= 0x80) ) + { + NOTICE_LOG(DVDINTERFACE, "GC-AM Media Board WRITE NETWORK CONFIG Type:%u Remote:%u", Memory::Read_U16(m_DIMAR.Address) , Memory::Read_U16(m_DIMAR.Address+2) ); + fseek( m_netcfg, iDVDOffset, SEEK_SET ); + fwrite( Memory::GetPointer(m_DIMAR.Address), sizeof(char), len, m_netcfg ); + fflush( m_netcfg ); + } + else if ((offset < 0) || ((offset + len) > 0x40) || len > 0x40) { u32 addr = m_DIMAR.Address; - memcpy(media_buffer + offset, Memory::GetPointer(addr), len); + if (iDVDOffset == 0x84800000) { + ERROR_LOG(DVDINTERFACE, "FIRMWARE UPLOAD"); + } else { + ERROR_LOG(DVDINTERFACE, "ILLEGAL MEDIA WRITE"); + } while (len >= 4) { - ERROR_LOG(DVDINTERFACE, "GC-AM Media Board WRITE (0xAA): %08x: %08x", iDVDOffset, Memory::Read_U32(addr)); + ERROR_LOG(DVDINTERFACE, "GC-AM Media Board WRITE (0xAA): %08x: %08x (ignored)", iDVDOffset, Memory::Read_U32(addr)); addr += 4; len -= 4; iDVDOffset += 4; } } + else + { + u32 addr = m_DIMAR.Address; + memcpy(media_buffer + offset, Memory::GetPointer(addr), len); + //while (len >= 4) + //{ + // ERROR_LOG(DVDINTERFACE, "GC-AM Media Board WRITE (0xAA): %08x: %08x", iDVDOffset, Memory::Read_U32(addr)); + // addr += 4; + // len -= 4; + // iDVDOffset += 4; + //} + } } break; @@ -761,75 +895,7 @@ void ExecuteCommand(UDICR& _DICR) } else { - memset(media_buffer, 0, 0x20); - media_buffer[0] = media_buffer[0x20]; // ID - media_buffer[2] = media_buffer[0x22]; - media_buffer[3] = media_buffer[0x23] | 0x80; - int cmd = (media_buffer[0x23]<<8)|media_buffer[0x22]; - ERROR_LOG(DVDINTERFACE, "GC-AM: execute buffer, cmd=%04x", cmd); - switch (cmd) - { - case 0x00: - media_buffer[4] = 1; - break; - case 0x1: - media_buffer[7] = 0x20; // DIMM Size - break; - case 0x100: - { - // urgh - static int percentage = 0; - static int status = 0; - percentage++; - if (percentage > 100) - { - status++; - percentage = 0; - } - media_buffer[4] = status; - /* status: - 0 - "Initializing media board. Please wait.." - 1 - "Checking network. Please wait..." - 2 - "Found a system disc. Insert a game disc" - 3 - "Testing a game program. %d%%" - 4 - "Loading a game program. %d%%" - 5 - go - 6 - error xx - */ - media_buffer[8] = percentage; - media_buffer[4] = 0x05; - media_buffer[8] = 0x64; - break; - } - case 0x101: - media_buffer[4] = 3; // version - media_buffer[5] = 3; - media_buffer[6] = 1; // xxx - media_buffer[8] = 1; - media_buffer[16] = 0xFF; - media_buffer[17] = 0xFF; - media_buffer[18] = 0xFF; - media_buffer[19] = 0xFF; - break; - case 0x102: // get error code - media_buffer[4] = 1; // 0: download incomplete (31), 1: corrupted, other error 1 - media_buffer[5] = 0; - break; - case 0x103: - memcpy(media_buffer + 4, "A89E27A50364511", 15); // serial - break; -#if 0 - case 0x301: // unknown - memcpy(media_buffer + 4, media_buffer + 0x24, 0x1c); - break; - case 0x302: - break; -#endif - default: - ERROR_LOG(DVDINTERFACE, "GC-AM: execute buffer (unknown)"); - break; - } - memset(media_buffer + 0x20, 0, 0x20); + GCAMExecuteCommand(); m_DIIMMBUF.Hex = 0x66556677; // just a random value that works. } break; @@ -840,7 +906,7 @@ void ExecuteCommand(UDICR& _DICR) // Request Error Code case DVDLowRequestError: - ERROR_LOG(DVDINTERFACE, "Requesting error... (0x%08x)", g_ErrorCode); + NOTICE_LOG(DVDINTERFACE, "Requesting error... (0x%08x)", g_ErrorCode); m_DIIMMBUF.Hex = g_ErrorCode; break; @@ -969,8 +1035,8 @@ void ExecuteCommand(UDICR& _DICR) break; default: - PanicAlertT("Unknown DVD command %08x - fatal error", m_DICMDBUF[0].Hex); - _dbg_assert_(DVDINTERFACE, 0); + // PanicAlertT("Unknown DVD command %08x - fatal error", m_DICMDBUF[0].Hex); + // _dbg_assert_(DVDINTERFACE, 0); break; } @@ -981,4 +1047,154 @@ void ExecuteCommand(UDICR& _DICR) g_ErrorCode = 0; } +static void GCAMExecuteCommand( void ) +{ + memset(media_reply_buffer, 0, 0x20); + + media_reply_buffer[0] = media_buffer[0x20]; // ID + media_reply_buffer[4] = media_buffer[0x22]; + media_reply_buffer[5] = media_buffer[0x23] | 0x80; + int cmd = (media_buffer[0x23]<<8)|media_buffer[0x22]; + ERROR_LOG(DVDINTERFACE, "GC-AM: execute buffer, cmd=%04x", cmd); + switch (cmd) + { + case 0x00: + break; + case 0x01: + // DIMM size + media_reply_buffer[7] = 0x20; + break; + case 0x100: + // Status + media_reply_buffer[4] = 0x05; + // Progress in % + media_reply_buffer[8] = 0x64; + break; + case 0x101: + // Media board version: 3.03 + media_reply_buffer[4] = 3; + media_reply_buffer[5] = 3; + media_reply_buffer[6] = 1; // xxx + media_reply_buffer[8] = 1; + media_reply_buffer[16] = 0xFF; + media_reply_buffer[17] = 0xFF; + media_reply_buffer[18] = 0xFF; + media_reply_buffer[19] = 0xFF; + break; + // System flags (Region,DevFlag) + case 0x102: + // Error: + // 0 (E01) Media Board doesn't support game + // 1 (E15) " + // 2 OK + media_reply_buffer[4] = 2; + media_reply_buffer[5] = 0; + // enable development mode (Sega Boot) + media_reply_buffer[6] = 1; + break; + case 0x103: + // Media board Serial + memcpy(media_reply_buffer + 4, "A89E27A50364511", 15); + break; + case 0x104: + media_reply_buffer[4] = 1; + break; + // Media Board Test + case 0x301: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x301: (%08X)", *(u32*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) ); + + Memory::Write_U32( 100, *(u32*)(media_buffer+0x28) ); + + *(u32*)(media_buffer+0x04) = *(u32*)(media_buffer+0x24); + break; + case 0x401: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x401: (%08X)", *(u32*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) ); + break; + case 0x403: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x403: (%08X)", *(u32*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) ); + media_buffer[4] = 1; + break; + case 0x404: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x404: (%08X)", *(u32*)(media_buffer+0x2C) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) ); + break; + case 0x408: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x408: (%08X)", *(u32*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) ); + break; + case 0x40B: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x40B: (%08X)", *(u32*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) ); + break; + case 0x40C: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x40C: (%08X)", *(u32*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x34) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x38) ); + break; + case 0x40E: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x40E: (%08X)", *(u32*)(media_buffer+0x28) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x34) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x38) ); + break; + case 0x410: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x410: (%08X)", *(u32*)(media_buffer+0x28) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x34) ); + break; + case 0x411: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x411: (%08X)", *(u32*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) ); + + *(u32*)(media_reply_buffer+4) = 0x46; + break; + case 0x415: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x415: (%08X)", *(u32*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) ); + break; + case 0x601: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x601"); + break; + case 0x606: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x606: (%04X)", *(u16*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%04X)", *(u16*)(media_buffer+0x26) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%02X)", *( u8*)(media_buffer+0x28) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%02X)", *( u8*)(media_buffer+0x29) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%04X)", *(u16*)(media_buffer+0x2A) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x2C) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x30) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x34) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x38) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x3C) ); + break; + case 0x607: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x607: (%04X)", *(u16*)(media_buffer+0x24) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%04X)", *(u16*)(media_buffer+0x26) ); + ERROR_LOG(DVDINTERFACE, "GC-AM: (%08X)", *(u32*)(media_buffer+0x28) ); + break; + case 0x614: + ERROR_LOG(DVDINTERFACE, "GC-AM: 0x601"); + break; + default: + ERROR_LOG(DVDINTERFACE, "GC-AM: execute buffer UNKNOWN:%03X", cmd ); + break; + } + memset( media_buffer + 0x20, 0, 0x20 ); +} + } // namespace diff --git a/Source/Core/Core/Src/HW/DVDInterface.h b/Source/Core/Core/Src/HW/DVDInterface.h index 8d9648510b9f..484295a49d23 100644 --- a/Source/Core/Core/Src/HW/DVDInterface.h +++ b/Source/Core/Core/Src/HW/DVDInterface.h @@ -39,6 +39,7 @@ void Read32(u32& _uReturnValue, const u32 _iAddress); // Write32 void Write32(const u32 _iValue, const u32 _iAddress); +void GCAMExecuteCommand( void ); // Not sure about endianness here. I'll just name them like this... enum DIErrorLow @@ -104,6 +105,15 @@ enum DICommand DVDLowAudioBufferConfig = 0xe4 }; +enum DINetworkTypes +{ + NETWORK_NONE = 0, + NETWORK_ETHER_MOBILE_DEFAULT_ETHER = 1, + NETWORK_ETHER_MOBILE_DEFAULT_MOBILE = 2, + NETWORK_ETHER = 3, + NETWORK_MOBILE = 4, +}; + } // end of namespace DVDInterface #endif diff --git a/Source/Core/Core/Src/HW/EXI_DeviceAMBaseboard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceAMBaseboard.cpp index 7da23dffc654..c303d19c3750 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceAMBaseboard.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceAMBaseboard.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "../Core.h" +#include "../ConfigManager.h" #include "EXI_Device.h" #include "EXI_DeviceAMBaseboard.h" @@ -11,53 +12,35 @@ CEXIAMBaseboard::CEXIAMBaseboard() : m_position(0) , m_have_irq(false) { - m_backup = fopen("User/tribackup.bin","rb+"); + char BackupPath[_MAX_PATH]; + + sprintf_s( BackupPath, _MAX_PATH, "User/tribackup_%s.bin", SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str() ); + + m_backup = fopen( BackupPath, "rb+" ); if( m_backup == (FILE*)NULL ) { - m_backup = fopen("User/tribackup.bin","wb+"); + m_backup = fopen( BackupPath, "wb+" ); if( m_backup == (FILE*)NULL ) { - ERROR_LOG( SP1, "AM-BB Failed to open backup file" ); + PanicAlertT( "AM-BB Failed to open/create backup file" ); } } } void CEXIAMBaseboard::SetCS(int cs) { - ERROR_LOG(SP1, "AM-BB ChipSelect=%d", cs); + DEBUG_LOG(SP1, "AM-BB ChipSelect=%d", cs); if (cs) m_position = 0; } bool CEXIAMBaseboard::IsPresent() { - return false; + return true; } void CEXIAMBaseboard::TransferByte(u8& _byte) { - /* - ID: - 00 00 xx xx xx xx - xx xx 06 04 10 00 - CMD: - 01 00 00 b3 xx - xx xx xx xx 04 - exi_lanctl_write: - ff 02 01 63 xx - xx xx xx xx 04 - exi_imr_read: - 86 00 00 f5 xx xx xx - xx xx xx xx 04 rr rr - exi_imr_write: - 87 80 5c 17 xx - xx xx xx xx 04 - - exi_isr_read: - 82 .. .. .. xx xx xx - xx xx xx xx 04 rr rr - 3 byte command, 1 byte checksum - */ DEBUG_LOG(SP1, "AM-BB > %02x", _byte); if (m_position < 4) { @@ -67,6 +50,7 @@ void CEXIAMBaseboard::TransferByte(u8& _byte) if ((m_position >= 2) && (m_command[0] == 0 && m_command[1] == 0)) { + // Read serial ID _byte = "\x06\x04\x10\x00"[(m_position-2)&3]; } else if (m_position == 3) @@ -93,28 +77,27 @@ void CEXIAMBaseboard::TransferByte(u8& _byte) { case 0x01: m_backoffset = (m_command[1] << 8) | m_command[2]; - DEBUG_LOG(SP1,"AM-BB COMMAND: Backup Offset:%04X", m_backoffset ); + INFO_LOG(SP1,"AM-BB COMMAND: Backup Offset:%04X", m_backoffset ); fseek( m_backup, m_backoffset, SEEK_SET ); _byte = 0x01; break; case 0x02: - DEBUG_LOG(SP1,"AM-BB COMMAND: Backup Write:%04X-%02X", m_backoffset, m_command[1] ); + INFO_LOG(SP1,"AM-BB COMMAND: Backup Write:%04X-%02X", m_backoffset, m_command[1] ); fputc( m_command[1], m_backup ); fflush(m_backup); _byte = 0x01; break; case 0x03: - { - DEBUG_LOG(SP1,"AM-BB COMMAND: Backup Read :%04X", m_backoffset ); + INFO_LOG(SP1,"AM-BB COMMAND: Backup Read :%04X", m_backoffset ); _byte = 0x01; - } break; + break; default: _byte = 4; - ERROR_LOG(SP1, "AM-BB COMMAND: %02x %02x %02x", m_command[0], m_command[1], m_command[2]); + INFO_LOG(SP1, "AM-BB COMMAND: %02x %02x %02x", m_command[0], m_command[1], m_command[2]); if ((m_command[0] == 0xFF) && (m_command[1] == 0) && (m_command[2] == 0)) - m_have_irq = false; - else if (m_command[0] == 0x82) + m_have_irq = true; + else if ((m_command[0] == 0x82) || (m_command[0] == 0x83)) m_have_irq = false; break; } @@ -123,24 +106,21 @@ void CEXIAMBaseboard::TransferByte(u8& _byte) { switch (m_command[0]) { + // Read backup - 1 byte out case 0x03: - _byte = (char)fgetc(m_backup); - break; - case 0xFF: // lan - _byte = 0x04; + _byte = fgetc(m_backup); break; - case 0x83: // ? - _byte = 0x04; - break; - case 0x86: // imr - _byte = 0x04; + // IMR - 2 byte out + case 0x82: + if( m_position == 6 ) + _byte = 0x02; + else + _byte = 0x00; break; + case 0x86: // ? case 0x87: // ? _byte = 0x04; break; - case 0x82: // isr - _byte = m_have_irq ? 0xFF : 0; - break; default: _dbg_assert_msg_(SP1, 0, "Unknown AM-BB command"); break; @@ -158,7 +138,7 @@ void CEXIAMBaseboard::TransferByte(u8& _byte) bool CEXIAMBaseboard::IsInterruptSet() { if (m_have_irq) - ERROR_LOG(SP1, "AM-BB IRQ"); + DEBUG_LOG(SP1, "AM-BB IRQ"); return m_have_irq; } diff --git a/Source/Core/Core/Src/HW/Memmap.h b/Source/Core/Core/Src/HW/Memmap.h index 8a3516e8b152..45d52dd9f56d 100644 --- a/Source/Core/Core/Src/HW/Memmap.h +++ b/Source/Core/Core/Src/HW/Memmap.h @@ -26,7 +26,7 @@ #if defined(_DEBUG) || defined(DEBUGFAST) #define ENABLE_MEM_CHECK #endif - +#define ENABLE_MEM_CHECK // Global declarations class PointerWrap; diff --git a/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp b/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp index f0537bf7745c..a73d97f03a12 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp @@ -84,46 +84,35 @@ class JVSIOMessage CSIDevice_AMBaseboard::CSIDevice_AMBaseboard(SIDevices device, int _iDeviceNumber) : ISIDevice(device, _iDeviceNumber) { - memset(coin, 0, sizeof(coin)); + memset(m_coin, 0, sizeof(m_coin)); - CARDMemSize = 0; - CARDInserted = 0; + m_card_memory_size = 0; + m_card_is_inserted = 0; - CARDROff = 0; - CARDCommand = 0; - CARDClean = 0; + m_card_offset = 0; + m_card_command = 0; + m_card_clean = 0; - CARDWriteLength = 0; - CARDWriteWrote = 0; + m_card_write_length = 0; + m_card_wrote = 0; - CARDReadLength = 0; - CARDReadRead = 0; + m_card_read_length = 0; + m_card_read = 0; - CARDBit = 0; - CardStateCallCount = 0; + m_card_bit = 0; + m_card_state_call_count = 0; - STRInit = 0; -} + m_controltype = 0; + + m_wheelinit = 0; -/* MKGP controls mapping: - stickX - steering - triggerRight - gas - triggerLeft - brake - A - Item button - B - Cancel button - Z - Coin - Y - Test mode (not working) - X - Service - - VS2002 controls mapping: - D-pad - movement - B - Short pass - A - Long pass - X - Shoot - Z - Coin - Y - Test mode - triggerRight - Service -*/ + m_motorinit = 0; + m_motorforce = 0; + m_motorforce_x = 0; + m_motorforce_y = 0; + + memset( m_motorreply, 0, sizeof(m_motorreply) ); +} int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) { // for debug logging only @@ -147,11 +136,9 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) break; case CMD_GCAM: { - int i; - // calculate checksum over buffer int csum = 0; - for (i=0; i<_iLength; ++i) + for( int i=0; i <_iLength; ++i ) csum += _pBuffer[i]; unsigned char res[0x80]; @@ -172,87 +159,87 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) switch (ptr(0)) { case 0x10: - { - DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 10, %02x (READ STATUS&SWITCHES)", ptr(1)); - SPADStatus PadStatus; - memset(&PadStatus, 0 ,sizeof(PadStatus)); - Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); - res[resp++] = 0x10; - res[resp++] = 0x2; - int d10_0 = 0xFF; - - /* baseboard test/service switches ???, disabled for a while - if (PadStatus.button & PAD_BUTTON_Y) // Test - d10_0 &= ~0x80; - if (PadStatus.button & PAD_BUTTON_X) // Service - d10_0 &= ~0x40; - */ - - res[resp++] = d10_0; - res[resp++] = d10_1; - break; - } + { + DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 10, %02x (READ STATUS&SWITCHES)", ptr(1)); + SPADStatus PadStatus; + memset(&PadStatus, 0 ,sizeof(PadStatus)); + Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); + res[resp++] = 0x10; + res[resp++] = 0x2; + int d10_0 = 0xFF; + + /* baseboard test/service switches ???, disabled for a while + if (PadStatus.button & PAD_BUTTON_Y) // Test + d10_0 &= ~0x80; + if (PadStatus.button & PAD_BUTTON_X) // Service + d10_0 &= ~0x40; + */ + + res[resp++] = d10_0; + res[resp++] = d10_1; + break; + } case 0x11: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: CMD 11, %02x (READ SERIAL NR)", ptr(1)); - char string[] = "AADE-01A14964511"; - res[resp++] = 0x11; - res[resp++] = 0x10; - memcpy(res + resp, string, 0x10); - resp += 0x10; - break; - } + { + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 11, %02x (READ SERIAL NR)", ptr(1)); + char string[] = "AADE-01A14964511"; + res[resp++] = 0x11; + res[resp++] = 0x10; + memcpy(res + resp, string, 0x10); + resp += 0x10; + break; + } case 0x12: - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: CMD 12, %02x %02x", ptr(1), ptr(2)); + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 12, %02x %02x", ptr(1), ptr(2)); res[resp++] = 0x12; res[resp++] = 0x00; break; case 0x15: - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: CMD 15, %02x (READ FIRM VERSION)", ptr(1)); + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 15, %02x (READ FIRM VERSION)", ptr(1)); res[resp++] = 0x15; res[resp++] = 0x02; + // FIRM VERSION res[resp++] = 0x00; - res[resp++] = 0x29; // FIRM VERSION + res[resp++] = 0x44; break; case 0x16: - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 16, %02x (READ FPGA VERSION)", ptr(1)); + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 16, %02x (READ FPGA VERSION)", ptr(1)); res[resp++] = 0x16; res[resp++] = 0x02; + // FPGAVERSION res[resp++] = 0x07; - res[resp++] = 0x06; // FPGAVERSION - /* - res[resp++] = 0x16; - res[resp++] = 0x00; - p += 2; - */ + res[resp++] = 0x09; break; case 0x1f: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 1f, %02x %02x %02x %02x %02x (REGION)", ptr(1), ptr(2), ptr(3), ptr(4), ptr(5)); - unsigned char string[] = - "\x00\x00\x30\x00" - //"\x01\xfe\x00\x00" // JAPAN - "\x02\xfd\x00\x00" // USA - //"\x03\xfc\x00\x00" // export - "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; - res[resp++] = 0x1f; - res[resp++] = 0x14; - - for (i=0; i<0x14; ++i) - res[resp++] = string[i]; - break; - } + { + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 1f, %02x %02x %02x %02x %02x (REGION)", ptr(1), ptr(2), ptr(3), ptr(4), ptr(5)); + unsigned char string[] = + "\x00\x00\x30\x00" + //"\x01\xfe\x00\x00" // JAPAN + "\x02\xfd\x00\x00" // USA + //"\x03\xfc\x00\x00" // export + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; + res[resp++] = 0x1f; + res[resp++] = 0x14; + + for( int i=0; i<0x14; ++i ) + res[resp++] = string[i]; + break; + } case 0x31: - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 31 (UNKNOWN)"); + // NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 31 (MOTOR) %02x %02x %02x %02x %02x", ptr(1), ptr(2), ptr(3), ptr(4), ptr(5)); + // Command Length if( ptr(1) ) { - u32 cmd =(ptr(2)^0x80) << 24; - cmd|= ptr(3) << 16; - cmd|= ptr(4) << 8; - // cmd|= ptr(5) << 0; // Checksum - - if( cmd == 0xffffff00 ) + u32 cmd =(ptr(2)^0x80) << 16; + cmd|= ptr(3) << 8; + cmd|= ptr(4); + + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 31 (SERIAL) Command:%06X", cmd ); + + // Serial - Wheel + if( cmd == 0x7FFFF0 ) { res[resp++] = 0x31; res[resp++] = 0x03; @@ -260,65 +247,87 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) res[resp++] = 'C'; res[resp++] = '0'; - if( STRInit == 0 ) + if( m_wheelinit == 0 ) { res[resp++] = '1'; - STRInit = 1; + m_wheelinit = 1; } else { res[resp++] = '6'; - } + } + break; + } + + // Serial - Motor + m_motorreply[0] = 0x31; + m_motorreply[1] = 0x04; - } else if( cmd == 0xff000000 ) { - - res[resp++] = 0x31; - res[resp++] = 0x03; - - res[resp++] = 'C'; - res[resp++] = '0'; - res[resp++] = '1'; + // Status + m_motorreply[2] = 0; + m_motorreply[3] = 0; + // error + m_motorreply[4] = 0; - } else { - - res[resp++] = 0x31; - res[resp++] = 0x03; - - res[resp++] = 'C'; - res[resp++] = '0'; - res[resp++] = '6'; + switch(cmd>>16) + { + case 0x00: + if( cmd == 0 ) + m_motorforce = 0; + break; + case 0x04: + m_motorforce = 1; + m_motorforce_x = (s16)(cmd<<4); + m_motorforce_y = m_motorforce_x; + break; + case 0x70: + m_motorforce = 0; + break; + case 0x7A: + m_motorforce = 1; + m_motorforce_x = (s16)(cmd & 0xFFFF); + m_motorforce_y = m_motorforce_x; + break; + default: + break; } + //Checksum + m_motorreply[5] = m_motorreply[2] ^ m_motorreply[3] ^ m_motorreply[4]; + resp += 6; + } else { - res[resp++] = 0x31; - res[resp++] = 0x03; - - res[resp++] = 'C'; - res[resp++] = '0'; - res[resp++] = '1'; + if( m_motorreply[0] ) + { + memcpy( res+resp, m_motorreply, sizeof(m_motorreply) ); + resp += sizeof(m_motorreply); + } else { + res[resp++] = 0x31; + res[resp++] = 0x00; + } } break; case 0x32: - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 32 (CARD-Interface)"); + // NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command 32 (CARD-Interface)"); if( ptr(1) ) { if( ptr(1) == 1 && ptr(2) == 0x05 ) { - if( CARDReadLength ) + if( m_card_read_length ) { res[resp++] = 0x32; - u32 ReadLength = CARDReadLength - CARDReadRead; + u32 ReadLength = m_card_read_length - m_card_read; if( ReadLength > 0x2F ) ReadLength = 0x2F; res[resp++] = ReadLength; // 0x2F (max size per packet) - memcpy( res+resp, CARDReadPacket+CARDReadRead, ReadLength ); + memcpy( res+resp, m_card_read_packet+m_card_read, ReadLength ); resp += ReadLength; - CARDReadRead += ReadLength; + m_card_read += ReadLength; - if( CARDReadRead >= CARDReadLength ) - CARDReadLength = 0; + if( m_card_read >= m_card_read_length ) + m_card_read_length = 0; break; } @@ -332,84 +341,72 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) res[resp++] = 0x00; // 0x00 len - switch(CARDCommand) + switch(m_card_command) { - case CARD_INIT: - { - res[resp++] = 0x10; // 0x01 - res[resp++] = 0x00; // 0x02 - res[resp++] = '0'; // 0x03 - } break; - case CARD_IS_PRESENT: - { - res[resp++] = 0x40; // 0x01 - res[resp++] = 0x22; // 0x02 - res[resp++] = '0'; // 0x03 - } break; - case CARD_GET_CARD_STATE: - { - res[resp++] = 0x20; // 0x01 - res[resp++] = 0x20|CARDBit; // 0x02 - /* - bit 0: PLease take your card - bit 1: endless waiting casues UNK_E to be called - */ - res[resp++] = 0x00; // 0x03 - } break; - case CARD_7A: - { - res[resp++] = 0x7A; // 0x01 - res[resp++] = 0x00; // 0x02 - res[resp++] = 0x00; // 0x03 - } break; - case CARD_78: - { - res[resp++] = 0x78; // 0x01 - res[resp++] = 0x00; // 0x02 - res[resp++] = 0x00; // 0x03 - } break; - case CARD_WRITE_INFO: - { - res[resp++] = 0x7C; // 0x01 - res[resp++] = 0x02; // 0x02 - res[resp++] = 0x00; // 0x03 - } break; - case CARD_D0: - { - res[resp++] = 0xD0; // 0x01 - res[resp++] = 0x00; // 0x02 - res[resp++] = 0x00; // 0x03 - } break; - case CARD_80: - { - res[resp++] = 0x80; // 0x01 - res[resp++] = 0x01; // 0x02 - res[resp++] = '0'; // 0x03 - } break; - case CARD_CLEAN_CARD: - { - res[resp++] = 0xA0; // 0x01 - res[resp++] = 0x02; // 0x02 - res[resp++] = 0x00; // 0x03 - } break; - case CARD_LOAD_CARD: - { - res[resp++] = 0xB0; // 0x01 - res[resp++] = 0x02; // 0x02 - res[resp++] = '0'; // 0x03 - } break; - case CARD_WRITE: - { - res[resp++] = 'S'; // 0x01 - res[resp++] = 0x02; // 0x02 - res[resp++] = 0x00; // 0x03 - } break; - case CARD_READ: - { - res[resp++] = 0x33; // 0x01 - res[resp++] = 0x02; // 0x02 - res[resp++] = 'S'; // 0x03 - } break; + case CARD_INIT: + res[resp++] = 0x10; // 0x01 + res[resp++] = 0x00; // 0x02 + res[resp++] = '0'; // 0x03 + break; + case CARD_IS_PRESENT: + res[resp++] = 0x40; // 0x01 + res[resp++] = 0x22; // 0x02 + res[resp++] = '0'; // 0x03 + break; + case CARD_GET_CARD_STATE: + res[resp++] = 0x20; // 0x01 + res[resp++] = 0x20|m_card_bit; // 0x02 + /* + bit 0: PLease take your card + bit 1: endless waiting casues UNK_E to be called + */ + res[resp++] = 0x00; // 0x03 + break; + case CARD_7A: + res[resp++] = 0x7A; // 0x01 + res[resp++] = 0x00; // 0x02 + res[resp++] = 0x00; // 0x03 + break; + case CARD_78: + res[resp++] = 0x78; // 0x01 + res[resp++] = 0x00; // 0x02 + res[resp++] = 0x00; // 0x03 + break; + case CARD_WRITE_INFO: + res[resp++] = 0x7C; // 0x01 + res[resp++] = 0x02; // 0x02 + res[resp++] = 0x00; // 0x03 + break; + case CARD_D0: + res[resp++] = 0xD0; // 0x01 + res[resp++] = 0x00; // 0x02 + res[resp++] = 0x00; // 0x03 + break; + case CARD_80: + res[resp++] = 0x80; // 0x01 + res[resp++] = 0x01; // 0x02 + res[resp++] = '0'; // 0x03 + break; + case CARD_CLEAN_CARD: + res[resp++] = 0xA0; // 0x01 + res[resp++] = 0x02; // 0x02 + res[resp++] = 0x00; // 0x03 + break; + case CARD_LOAD_CARD: + res[resp++] = 0xB0; // 0x01 + res[resp++] = 0x02; // 0x02 + res[resp++] = '0'; // 0x03 + break; + case CARD_WRITE: + res[resp++] = 'S'; // 0x01 + res[resp++] = 0x02; // 0x02 + res[resp++] = 0x00; // 0x03 + break; + case CARD_READ: + res[resp++] = 0x33; // 0x01 + res[resp++] = 0x02; // 0x02 + res[resp++] = 'S'; // 0x03 + break; } res[resp++] = '0'; // 0x04 @@ -431,206 +428,197 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) } else { for( u32 i=0; i < ptr(1); ++i ) - CARDRBuf[CARDROff+i] = ptr(2+i); + m_card_buffer[m_card_offset+i] = ptr(2+i); - CARDROff += ptr(1); + m_card_offset += ptr(1); //Check if we got complete CMD - if( CARDRBuf[0] == 0x02 ) - if( CARDRBuf[1] == CARDROff - 2 ) + if( m_card_buffer[0] == 0x02 ) + if( m_card_buffer[1] == m_card_offset - 2 ) { - if( CARDRBuf[CARDROff-2] == 0x03 ) + if( m_card_buffer[m_card_offset-2] == 0x03 ) { - u32 cmd = CARDRBuf[2] << 24; - cmd|= CARDRBuf[3] << 16; - cmd|= CARDRBuf[4] << 8; - cmd|= CARDRBuf[5] << 0; + u32 cmd = m_card_buffer[2] << 24; + cmd|= m_card_buffer[3] << 16; + cmd|= m_card_buffer[4] << 8; + cmd|= m_card_buffer[5] << 0; switch(cmd) { - default: - { - // ERROR_LOG(AMBASEBOARDDEBUG, "CARD:Unhandled cmd!"); - // ERROR_LOG(AMBASEBOARDDEBUG, "CARD:[%08X]", cmd ); - // hexdump( CARDRBuf, CARDROff ); - } break; - case 0x10000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Init"); - CARDCommand = CARD_INIT; - - CARDWriteLength = 0; - CARDBit = 0; - CARDMemSize = 0; - CardStateCallCount = 0; + case 0x10000000: + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Init"); + m_card_command = CARD_INIT; + + m_card_write_length = 0; + m_card_bit = 0; + m_card_memory_size = 0; + m_card_state_call_count = 0; + break; + case 0x20000000: + { + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD GetState(%02X)", m_card_bit ); + m_card_command = CARD_GET_CARD_STATE; - } break; - case 0x20000000: + if( m_card_memory_size ) { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD GetState(%02X)", CARDBit ); - CARDCommand = CARD_GET_CARD_STATE; - - if( CARDMemSize ) + m_card_state_call_count++; + if( m_card_state_call_count > 10 ) { - CardStateCallCount++; - if( CardStateCallCount > 10 ) - { - if( CARDBit & 2 ) - CARDBit &= ~2; - else - CARDBit |= 2; + if( m_card_bit & 2 ) + m_card_bit &= ~2; + else + m_card_bit |= 2; - CardStateCallCount = 0; - } + m_card_state_call_count = 0; } + } - if( CARDClean == 1 ) - { - CARDClean = 2; - } else if( CARDClean == 2 ) + if( m_card_clean == 1 ) + { + m_card_clean = 2; + } else if( m_card_clean == 2 ) + { + FILE *out = fopen("User/tricard.bin","rb+"); + if( out != NULL ) { - FILE *out = fopen("User/tricard.bin","rb+"); - if( out != NULL ) + fseek( out, 0, SEEK_END ); + if( ftell(out) > 0 ) { - fseek( out, 0, SEEK_END ); - if( ftell(out) > 0 ) - { - CARDMemSize = ftell(out); - CARDBit = 2; - } - fclose(out); + m_card_memory_size = ftell(out); + m_card_bit = 2; } - CARDClean = 0; + fclose(out); } - } break; - case 0x40000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD IsPresent"); - CARDCommand = CARD_IS_PRESENT; - } break; - case 0x7A000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Unknown7A"); - CARDCommand = CARD_7A; - } break; - case 0xB0000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD LoadCard"); - CARDCommand = CARD_LOAD_CARD; - } break; - case 0xA0000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD IsCleanCard"); - CARDCommand = CARD_CLEAN_CARD; - CARDClean = 1; - } break; - case 0x33000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Read"); - CARDCommand = CARD_READ; + m_card_clean = 0; + } + break; + } + case 0x40000000: + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD IsPresent"); + m_card_command = CARD_IS_PRESENT; + break; + case 0x7A000000: + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Unknown7A"); + m_card_command = CARD_7A; + break; + case 0xB0000000: + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD LoadCard"); + m_card_command = CARD_LOAD_CARD; + break; + case 0xA0000000: + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD IsCleanCard"); + m_card_command = CARD_CLEAN_CARD; + m_card_clean = 1; + break; + case 0x33000000: + { + NOTICE_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Read"); + m_card_command = CARD_READ; - //Prepare read packet - memset( CARDReadPacket, 0, 0xDB ); - u32 POff=0; + //Prepare read packet + memset( m_card_read_packet, 0, 0xDB ); + u32 POff=0; - FILE *card = fopen( "User/tricard.bin", "rb"); - if( card != NULL ) + FILE *card = fopen( "User/tricard.bin", "rb"); + if( card != NULL ) + { + if( m_card_memory_size == 0 ) { - if( CARDMemSize == 0 ) - { - fseek( card, 0, SEEK_END ); - CARDMemSize = ftell(card); - fseek( card, 0, SEEK_SET ); - } + fseek( card, 0, SEEK_END ); + m_card_memory_size = ftell(card); + fseek( card, 0, SEEK_SET ); + } - fread( CARDMem, sizeof(char), CARDMemSize, card ); - fclose( card ); + fread( m_card_memory, sizeof(char), m_card_memory_size, card ); + fclose( card ); - CARDInserted = 1; - } + m_card_is_inserted = 1; + } - CARDReadPacket[POff++] = 0x02; // SUB CMD - CARDReadPacket[POff++] = 0x00; // SUB CMDLen + m_card_read_packet[POff++] = 0x02; // SUB CMD + m_card_read_packet[POff++] = 0x00; // SUB CMDLen - CARDReadPacket[POff++] = 0x33; // CARD CMD + m_card_read_packet[POff++] = 0x33; // CARD CMD - if( CARDInserted ) - { - CARDReadPacket[POff++] = '1'; // CARD Status - } else { - CARDReadPacket[POff++] = '0'; // CARD Status - } + if( m_card_is_inserted ) + { + m_card_read_packet[POff++] = '1'; // CARD Status + } else { + m_card_read_packet[POff++] = '0'; // CARD Status + } - CARDReadPacket[POff++] = '0'; // - CARDReadPacket[POff++] = '0'; // + m_card_read_packet[POff++] = '0'; // + m_card_read_packet[POff++] = '0'; // - //Data reply - memcpy( CARDReadPacket + POff, CARDMem, CARDMemSize ); - POff += CARDMemSize; + //Data reply + memcpy( m_card_read_packet + POff, m_card_memory, m_card_memory_size ); + POff += m_card_memory_size; - CARDReadPacket[POff++] = 0x03; + m_card_read_packet[POff++] = 0x03; - CARDReadPacket[1] = POff-1; // SUB CMDLen + m_card_read_packet[1] = POff-1; // SUB CMDLen - u32 i; - for( i=0; i < POff-1; ++i ) - CARDReadPacket[POff] ^= CARDReadPacket[1+i]; + u32 i; + for( i=0; i < POff-1; ++i ) + m_card_read_packet[POff] ^= m_card_read_packet[1+i]; - POff++; + POff++; - CARDReadLength = POff; - CARDReadRead = 0; - } break; - case 0x53000000: - { - CARDCommand = CARD_WRITE; + m_card_read_length = POff; + m_card_read = 0; + break; + } + case 0x53000000: + { + m_card_command = CARD_WRITE; - CARDMemSize = CARDRBuf[1] - 9; + m_card_memory_size = m_card_buffer[1] - 9; - memcpy( CARDMem, CARDRBuf+9, CARDMemSize ); + memcpy( m_card_memory, m_card_buffer+9, m_card_memory_size ); - ERROR_LOG(AMBASEBOARDDEBUG, "CARDWrite: %u", CARDMemSize ); + NOTICE_LOG(AMBASEBOARDDEBUG, "CARDWrite: %u", m_card_memory_size ); - FILE *card = fopen( "User/tricard.bin", "wb"); - if( card != NULL ) - { - fwrite( CARDMem, sizeof(char), CARDMemSize, card ); - fclose( card ); - } + FILE *card = fopen( "User/tricard.bin", "wb"); + if( card != NULL ) + { + fwrite( m_card_memory, sizeof(char), m_card_memory_size, card ); + fclose( card ); + } - CARDBit = 2; + m_card_bit = 2; - CardStateCallCount = 0; - } break; - case 0x78000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Unknown78"); - CARDCommand = CARD_78; - } break; - case 0x7C000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD WriteCardInfo"); - CARDCommand = CARD_WRITE_INFO; - } break; - case 0x7D000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Print"); - CARDCommand = CARD_7D; - } break; - case 0x80000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Unknown80"); - CARDCommand = CARD_80; - } break; - case 0xD0000000: - { - ERROR_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD UnknownD0"); - CARDCommand = CARD_D0; - } break; + m_card_state_call_count = 0; + break; + } + case 0x78000000: + DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Unknown78"); + m_card_command = CARD_78; + break; + case 0x7C000000: + DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD WriteCardInfo"); + m_card_command = CARD_WRITE_INFO; + break; + case 0x7D000000: + DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Print"); + m_card_command = CARD_7D; + break; + case 0x80000000: + DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD Unknown80"); + m_card_command = CARD_80; + break; + case 0xD0000000: + DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: Command CARD UnknownD0"); + m_card_command = CARD_D0; + break; + default: + // NOTICE_LOG(AMBASEBOARDDEBUG, "CARD:Unhandled cmd!"); + // NOTICE_LOG(AMBASEBOARDDEBUG, "CARD:[%08X]", cmd ); + // hexdump( m_card_buffer, m_card_offset ); + break; } - CARDROff = 0; + m_card_offset = 0; } } @@ -671,21 +659,24 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) unsigned char jvs_io_buffer[0x80]; int nr_bytes = ptr(pptr + 2); // byte after e0 xx int jvs_io_length = 0; - for (i=0; i>8)&0x3f); - msg.addData(coin[i]&0xff); + m_coin_pressed[i]=PadStatus.button & PAD_TRIGGER_Z; + msg.addData((m_coin[i]>>8)&0x3f); + msg.addData(m_coin[i]&0xff); } - //ERROR_LOG(AMBASEBOARDDEBUG, "JVS-IO:Get Coins Slots:%u Unk:%u", slots, unk ); - } break; - case 0x22: // analogs + //NOTICE_LOG(AMBASEBOARDDEBUG, "JVS-IO:Get Coins Slots:%u Unk:%u", slots, unk ); + break; + } + // read analog inputs + case 0x22: { msg.addData(1); // status int analogs = *jvs_io++; SPADStatus PadStatus; Pad::GetStatus(0, &PadStatus); - if (!memcmp(SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), "GFXJ01", 6)) { - msg.addData(PadStatus.stickX); // steering - msg.addData((u8)0); - - msg.addData(PadStatus.stickY); // steering - msg.addData((u8)0); - - msg.addData((u8)0); // unused - msg.addData((u8)0); - - msg.addData((u8)0); // unused - msg.addData((u8)0); - - msg.addData(PadStatus.triggerRight);// gas - msg.addData((u8)0); - - msg.addData(PadStatus.triggerLeft); // brake - msg.addData((u8)0); - - msg.addData((u8)0); // unused - msg.addData((u8)0); - - msg.addData((u8)0); // unused - msg.addData((u8)0); - } else { - // 8 bit to 16 bit conversion - msg.addData(PadStatus.stickX); // steering - msg.addData(PadStatus.stickX); + switch(m_controltype) + { + // F-Zero AX + case 1: + // Steering + if( m_motorforce ) + { + msg.addData( m_motorforce_x >> 8 ); + msg.addData( m_motorforce_x & 0xFF ); - // 8 bit to 16 bit conversion - msg.addData(PadStatus.triggerRight); // gas - msg.addData(PadStatus.triggerRight); + msg.addData( m_motorforce_y >> 8); + msg.addData( m_motorforce_y & 0xFF ); + } + else + { + msg.addData(PadStatus.stickX); + msg.addData((u8)0); - // 8 bit to 16 bit conversion - msg.addData(PadStatus.triggerLeft); // brake - msg.addData(PadStatus.triggerLeft); + msg.addData(PadStatus.stickY); + msg.addData((u8)0); + } - for( i=0; i < (analogs - 3); i++ ) { - msg.addData( 0 ); - msg.addData( 0 ); - } + // Unused + msg.addData((u8)0); + msg.addData((u8)0); + msg.addData((u8)0); + msg.addData((u8)0); + + // Gas + msg.addData(PadStatus.triggerRight); + msg.addData((u8)0); + + // Brake + msg.addData(PadStatus.triggerLeft); + msg.addData((u8)0); + break; + // Virtua Strike games + case 2: + SPADStatus PadStatus2; + Pad::GetStatus(1, &PadStatus2); + + msg.addData(PadStatus.stickX); + msg.addData((u8)0); + msg.addData(PadStatus.stickY); + msg.addData((u8)0); + + msg.addData(PadStatus2.stickX); + msg.addData((u8)0); + msg.addData(PadStatus2.stickY); + msg.addData((u8)0); + break; + // Mario Kart and other games + case 3: + // Steering + msg.addData(PadStatus.stickX); + msg.addData((u8)0); + + // Gas + msg.addData(PadStatus.triggerRight); + msg.addData((u8)0); + + // Brake + msg.addData(PadStatus.triggerLeft); + msg.addData((u8)0); + break; } - } break; - case 0x30: // sub coins + } + // decrease number of coins + case 0x30: { int slot = *jvs_io++; - coin[slot]-= (*jvs_io++<<8)|*jvs_io++; + m_coin[slot]-= (*jvs_io++<<8)|*jvs_io++; msg.addData(1); - } break; - case 0x32: // General out + break; + } + // general-purpose output + case 0x32: { int bytes = *jvs_io++; while (bytes--) {*jvs_io++;} msg.addData(1); - } break; - case 0x35: // add coins + break; + } + // output the total number of coins + case 0x35: { int slot = *jvs_io++; - coin[slot]+= (*jvs_io++<<8)|*jvs_io++; + m_coin[slot]+= (*jvs_io++<<8)|*jvs_io++; msg.addData(1); - } break; + break; + } case 0x70: // custom namco's command subset { int cmd = *jvs_io++; @@ -905,7 +980,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) msg.addData(1); ///ERROR_LOG(AMBASEBOARDDEBUG, "JVS-IO:Unknown"); } - } break; + break; + } case 0xf0: if (*jvs_io++ == 0xD9) ERROR_LOG(AMBASEBOARDDEBUG, "JVS RESET"); @@ -920,11 +996,11 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) d10_1 &= ~1; break; default: + ERROR_LOG(AMBASEBOARDDEBUG, "JVS IO, node=%d, command=%02x", node, cmd); break; } pptr += jvs_io_length; - } msg.end(); @@ -934,7 +1010,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength) unsigned char *buf = msg.m_msg; int len = msg.m_ptr; res[resp++] = len; - for (i=0; i