Added support for AGP. Original patch by GreyRogue.
This commit is contained in:
parent
18cee2dcc7
commit
a7299a7fff
|
@ -91,6 +91,7 @@ set(SRCS ActionReplay.cpp
|
||||||
HW/EXI.cpp
|
HW/EXI.cpp
|
||||||
HW/EXI_Device.cpp
|
HW/EXI_Device.cpp
|
||||||
HW/EXI_DeviceAD16.cpp
|
HW/EXI_DeviceAD16.cpp
|
||||||
|
HW/EXI_DeviceAGP.cpp
|
||||||
HW/EXI_DeviceAMBaseboard.cpp
|
HW/EXI_DeviceAMBaseboard.cpp
|
||||||
HW/EXI_DeviceEthernet.cpp
|
HW/EXI_DeviceEthernet.cpp
|
||||||
HW/EXI_DeviceGecko.cpp
|
HW/EXI_DeviceGecko.cpp
|
||||||
|
|
|
@ -329,6 +329,8 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
||||||
core->Set("Latency", m_LocalCoreStartupParameter.iLatency);
|
core->Set("Latency", m_LocalCoreStartupParameter.iLatency);
|
||||||
core->Set("MemcardAPath", m_strMemoryCardA);
|
core->Set("MemcardAPath", m_strMemoryCardA);
|
||||||
core->Set("MemcardBPath", m_strMemoryCardB);
|
core->Set("MemcardBPath", m_strMemoryCardB);
|
||||||
|
core->Set("AgpCartAPath", m_strGbaCartA);
|
||||||
|
core->Set("AgpCartBPath", m_strGbaCartB);
|
||||||
core->Set("SlotA", m_EXIDevice[0]);
|
core->Set("SlotA", m_EXIDevice[0]);
|
||||||
core->Set("SlotB", m_EXIDevice[1]);
|
core->Set("SlotB", m_EXIDevice[1]);
|
||||||
core->Set("SerialPort1", m_EXIDevice[2]);
|
core->Set("SerialPort1", m_EXIDevice[2]);
|
||||||
|
@ -559,6 +561,8 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
||||||
core->Get("Latency", &m_LocalCoreStartupParameter.iLatency, 2);
|
core->Get("Latency", &m_LocalCoreStartupParameter.iLatency, 2);
|
||||||
core->Get("MemcardAPath", &m_strMemoryCardA);
|
core->Get("MemcardAPath", &m_strMemoryCardA);
|
||||||
core->Get("MemcardBPath", &m_strMemoryCardB);
|
core->Get("MemcardBPath", &m_strMemoryCardB);
|
||||||
|
core->Get("AgpCartAPath", &m_strGbaCartA);
|
||||||
|
core->Get("AgpCartBPath", &m_strGbaCartB);
|
||||||
core->Get("SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD);
|
core->Get("SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD);
|
||||||
core->Get("SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_NONE);
|
core->Get("SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_NONE);
|
||||||
core->Get("SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_NONE);
|
core->Get("SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_NONE);
|
||||||
|
|
|
@ -41,6 +41,8 @@ struct SConfig : NonCopyable
|
||||||
|
|
||||||
std::string m_strMemoryCardA;
|
std::string m_strMemoryCardA;
|
||||||
std::string m_strMemoryCardB;
|
std::string m_strMemoryCardB;
|
||||||
|
std::string m_strGbaCartA;
|
||||||
|
std::string m_strGbaCartB;
|
||||||
TEXIDevices m_EXIDevice[3];
|
TEXIDevices m_EXIDevice[3];
|
||||||
SIDevices m_SIDevice[4];
|
SIDevices m_SIDevice[4];
|
||||||
std::string m_bba_mac;
|
std::string m_bba_mac;
|
||||||
|
|
|
@ -122,6 +122,7 @@
|
||||||
<ClCompile Include="HW\EXI_Channel.cpp" />
|
<ClCompile Include="HW\EXI_Channel.cpp" />
|
||||||
<ClCompile Include="HW\EXI_Device.cpp" />
|
<ClCompile Include="HW\EXI_Device.cpp" />
|
||||||
<ClCompile Include="HW\EXI_DeviceAD16.cpp" />
|
<ClCompile Include="HW\EXI_DeviceAD16.cpp" />
|
||||||
|
<ClCompile Include="HW\EXI_DeviceAGP.cpp" />
|
||||||
<ClCompile Include="HW\EXI_DeviceAMBaseboard.cpp" />
|
<ClCompile Include="HW\EXI_DeviceAMBaseboard.cpp" />
|
||||||
<ClCompile Include="HW\EXI_DeviceEthernet.cpp" />
|
<ClCompile Include="HW\EXI_DeviceEthernet.cpp" />
|
||||||
<ClCompile Include="HW\EXI_DeviceGecko.cpp" />
|
<ClCompile Include="HW\EXI_DeviceGecko.cpp" />
|
||||||
|
@ -330,6 +331,7 @@
|
||||||
<ClInclude Include="HW\EXI_Channel.h" />
|
<ClInclude Include="HW\EXI_Channel.h" />
|
||||||
<ClInclude Include="HW\EXI_Device.h" />
|
<ClInclude Include="HW\EXI_Device.h" />
|
||||||
<ClInclude Include="HW\EXI_DeviceAD16.h" />
|
<ClInclude Include="HW\EXI_DeviceAD16.h" />
|
||||||
|
<ClInclude Include="HW\EXI_DeviceAGP.h" />
|
||||||
<ClInclude Include="HW\EXI_DeviceAMBaseboard.h" />
|
<ClInclude Include="HW\EXI_DeviceAMBaseboard.h" />
|
||||||
<ClInclude Include="HW\EXI_DeviceEthernet.h" />
|
<ClInclude Include="HW\EXI_DeviceEthernet.h" />
|
||||||
<ClInclude Include="HW\EXI_DeviceGecko.h" />
|
<ClInclude Include="HW\EXI_DeviceGecko.h" />
|
||||||
|
|
|
@ -385,6 +385,9 @@
|
||||||
<ClCompile Include="HW\EXI_DeviceAD16.cpp">
|
<ClCompile Include="HW\EXI_DeviceAD16.cpp">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="HW\EXI_DeviceAGP.cpp">
|
||||||
|
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="HW\EXI_DeviceAMBaseboard.cpp">
|
<ClCompile Include="HW\EXI_DeviceAMBaseboard.cpp">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -914,6 +917,9 @@
|
||||||
<ClInclude Include="HW\EXI_DeviceAD16.h">
|
<ClInclude Include="HW\EXI_DeviceAD16.h">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="HW\EXI_DeviceAGP.h">
|
||||||
|
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="HW\EXI_DeviceAMBaseboard.h">
|
<ClInclude Include="HW\EXI_DeviceAMBaseboard.h">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -1229,4 +1235,4 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="CMakeLists.txt" />
|
<Text Include="CMakeLists.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HW/EXI_Device.h"
|
#include "Core/HW/EXI_Device.h"
|
||||||
#include "Core/HW/EXI_DeviceAD16.h"
|
#include "Core/HW/EXI_DeviceAD16.h"
|
||||||
|
#include "Core/HW/EXI_DeviceAGP.h"
|
||||||
#include "Core/HW/EXI_DeviceAMBaseboard.h"
|
#include "Core/HW/EXI_DeviceAMBaseboard.h"
|
||||||
#include "Core/HW/EXI_DeviceEthernet.h"
|
#include "Core/HW/EXI_DeviceEthernet.h"
|
||||||
#include "Core/HW/EXI_DeviceGecko.h"
|
#include "Core/HW/EXI_DeviceGecko.h"
|
||||||
|
@ -84,6 +85,7 @@ public:
|
||||||
u32 ImmRead (u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s ImmRead", m_strName.c_str()); return 0;}
|
u32 ImmRead (u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s ImmRead", m_strName.c_str()); return 0;}
|
||||||
void DMAWrite(u32 addr, u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMAWrite: %08x bytes, from %08x to device", m_strName.c_str(), size, addr);}
|
void DMAWrite(u32 addr, u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMAWrite: %08x bytes, from %08x to device", m_strName.c_str(), size, addr);}
|
||||||
void DMARead (u32 addr, u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMARead: %08x bytes, from device to %08x", m_strName.c_str(), size, addr);}
|
void DMARead (u32 addr, u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMARead: %08x bytes, from device to %08x", m_strName.c_str(), size, addr);}
|
||||||
|
bool IsPresent() override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,6 +131,10 @@ IEXIDevice* EXIDevice_Create(TEXIDevices device_type, const int channel_num)
|
||||||
result = new CEXIGecko();
|
result = new CEXIGecko();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EXIDEVICE_AGP:
|
||||||
|
result = new CEXIAgp(channel_num);
|
||||||
|
break;
|
||||||
|
|
||||||
case EXIDEVICE_NONE:
|
case EXIDEVICE_NONE:
|
||||||
default:
|
default:
|
||||||
result = new IEXIDevice();
|
result = new IEXIDevice();
|
||||||
|
|
|
@ -19,6 +19,7 @@ enum TEXIDevices
|
||||||
EXIDEVICE_GECKO,
|
EXIDEVICE_GECKO,
|
||||||
EXIDEVICE_MEMORYCARDFOLDER, // Only used when creating a device by EXIDevice_Create
|
EXIDEVICE_MEMORYCARDFOLDER, // Only used when creating a device by EXIDevice_Create
|
||||||
// Converted to EXIDEVICE_MEMORYCARD internally
|
// Converted to EXIDEVICE_MEMORYCARD internally
|
||||||
|
EXIDEVICE_AGP,
|
||||||
EXIDEVICE_NONE = (u8)-1
|
EXIDEVICE_NONE = (u8)-1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
// Copyright 2013 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "Common/FileUtil.h"
|
||||||
|
#include "Common/MemoryUtil.h"
|
||||||
|
#include "Common/StdMakeUnique.h"
|
||||||
|
#include "Core/ConfigManager.h"
|
||||||
|
#include "Core/Core.h"
|
||||||
|
#include "Core/HW/EXI_Device.h"
|
||||||
|
#include "Core/HW/EXI_DeviceAGP.h"
|
||||||
|
#include "Core/HW/Memmap.h"
|
||||||
|
|
||||||
|
CEXIAgp::CEXIAgp(int index) :
|
||||||
|
m_slot(index)
|
||||||
|
{
|
||||||
|
// Create the ROM
|
||||||
|
m_pHashArray = (u8*)AllocateMemoryPages(HASH_SIZE);
|
||||||
|
m_rom_size = 0;
|
||||||
|
|
||||||
|
LoadRom();
|
||||||
|
|
||||||
|
m_address = 0;
|
||||||
|
m_rom_hash_loaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CEXIAgp::~CEXIAgp()
|
||||||
|
{
|
||||||
|
m_pROM = nullptr;
|
||||||
|
m_pHashArray = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEXIAgp::DoHash(u8* data, u32 size)
|
||||||
|
{
|
||||||
|
for (u32 it = 0; it < size; it++)
|
||||||
|
{
|
||||||
|
m_hash = m_hash ^ data[it];
|
||||||
|
m_hash = m_pHashArray[m_hash];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEXIAgp::LoadRom()
|
||||||
|
{
|
||||||
|
// Load whole ROM dump
|
||||||
|
std::string path;
|
||||||
|
std::string filename;
|
||||||
|
std::string ext;
|
||||||
|
std::string gbapath;
|
||||||
|
SplitPath(m_slot == 0 ? SConfig::GetInstance().m_strGbaCartA : SConfig::GetInstance().m_strGbaCartB, &path, &filename, &ext);
|
||||||
|
gbapath = path + filename;
|
||||||
|
LoadFileToROM(gbapath + ext);
|
||||||
|
INFO_LOG(EXPANSIONINTERFACE, "Loaded gba rom: %s card: %d", gbapath.c_str(), m_slot);
|
||||||
|
LoadFileToEEPROM(gbapath + ".sav");
|
||||||
|
INFO_LOG(EXPANSIONINTERFACE, "Loaded gba sav: %s card: %d", gbapath.c_str(), m_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEXIAgp::LoadFileToROM(std::string filename)
|
||||||
|
{
|
||||||
|
File::IOFile pStream(filename, "rb");
|
||||||
|
if (pStream)
|
||||||
|
{
|
||||||
|
u64 filesize = pStream.GetSize();
|
||||||
|
m_rom_size = filesize & 0xFFFFFFFF;
|
||||||
|
m_rom_mask = (m_rom_size - 1);
|
||||||
|
|
||||||
|
m_pROM = (u8*)AllocateMemoryPages(m_rom_size);
|
||||||
|
|
||||||
|
pStream.ReadBytes(m_pROM, filesize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// dummy rom data
|
||||||
|
m_pROM = (u8*)AllocateMemoryPages(0x2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEXIAgp::LoadFileToEEPROM(std::string filename)
|
||||||
|
{
|
||||||
|
File::IOFile pStream(filename, "rb");
|
||||||
|
if (pStream)
|
||||||
|
{
|
||||||
|
u64 filesize = pStream.GetSize();
|
||||||
|
m_eeprom_size = filesize & 0xFFFFFFFF;
|
||||||
|
m_eeprom_mask = (m_eeprom_size - 1);
|
||||||
|
|
||||||
|
m_pEEPROM = (u8*)AllocateMemoryPages(m_eeprom_size);
|
||||||
|
|
||||||
|
pStream.ReadBytes(m_pEEPROM, filesize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEXIAgp::LoadHash()
|
||||||
|
{
|
||||||
|
if (!m_rom_hash_loaded && m_rom_size > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 0x100; i++)
|
||||||
|
{
|
||||||
|
m_pHashArray[i] = Memory::ReadUnchecked_U8(0x0017e908 + i);
|
||||||
|
}
|
||||||
|
m_rom_hash_loaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CEXIAgp::ImmRead(u32 _uSize)
|
||||||
|
{
|
||||||
|
// We don't really care about _uSize
|
||||||
|
(void)_uSize;
|
||||||
|
u32 uData = 0;
|
||||||
|
u8 RomVal1, RomVal2, RomVal3, RomVal4;
|
||||||
|
|
||||||
|
switch (m_currrent_cmd)
|
||||||
|
{
|
||||||
|
case 0xAE000000:
|
||||||
|
uData = 0x5AAA5517; // 17 is precalculated hash
|
||||||
|
m_currrent_cmd = 0;
|
||||||
|
break;
|
||||||
|
case 0xAE010000:
|
||||||
|
uData = (m_return_pos == 0) ? 0x01020304 : 0xF0020304; // F0 is precalculated hash, 020304 is left over
|
||||||
|
if (m_return_pos == 1)
|
||||||
|
m_currrent_cmd = 0;
|
||||||
|
else
|
||||||
|
m_return_pos = 1;
|
||||||
|
break;
|
||||||
|
case 0xAE020000:
|
||||||
|
if (m_rw_offset == 0x8000000)
|
||||||
|
{
|
||||||
|
RomVal1 = 0x0;
|
||||||
|
RomVal2 = 0x1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RomVal1 = m_pROM[m_rw_offset++];
|
||||||
|
RomVal2 = m_pROM[m_rw_offset++];
|
||||||
|
LoadHash();
|
||||||
|
}
|
||||||
|
DoHash(&RomVal2, 1);
|
||||||
|
DoHash(&RomVal1, 1);
|
||||||
|
uData = (RomVal2 << 24) | (RomVal1 << 16) | (m_hash << 8);
|
||||||
|
m_currrent_cmd = 0;
|
||||||
|
break;
|
||||||
|
case 0xAE030000:
|
||||||
|
if (_uSize == 1)
|
||||||
|
{
|
||||||
|
uData = 0xFF000000;
|
||||||
|
m_currrent_cmd = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RomVal1 = m_pROM[m_rw_offset++];
|
||||||
|
RomVal2 = m_pROM[m_rw_offset++];
|
||||||
|
RomVal3 = m_pROM[m_rw_offset++];
|
||||||
|
RomVal4 = m_pROM[m_rw_offset++];
|
||||||
|
LoadHash();
|
||||||
|
DoHash(&RomVal2, 1);
|
||||||
|
DoHash(&RomVal1, 1);
|
||||||
|
DoHash(&RomVal4, 1);
|
||||||
|
DoHash(&RomVal3, 1);
|
||||||
|
uData = (RomVal2 << 24) | (RomVal1 << 16) | (RomVal4 << 8) | (RomVal3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xAE0B0000:
|
||||||
|
RomVal1 = m_eeprom_pos < 4 ? 0xA : (((u64*)m_pEEPROM)[(m_eeprom_cmd >> 1) & 0x3F] >> (m_eeprom_pos - 4)) & 0x1;
|
||||||
|
RomVal2 = 0;
|
||||||
|
DoHash(&RomVal2, 1);
|
||||||
|
DoHash(&RomVal1, 1);
|
||||||
|
uData = (RomVal2 << 24) | (RomVal1 << 16) | (m_hash << 8);
|
||||||
|
m_eeprom_pos++;
|
||||||
|
m_currrent_cmd = 0;
|
||||||
|
break;
|
||||||
|
case 0xAE0C0000:
|
||||||
|
uData = m_hash << 24;
|
||||||
|
m_currrent_cmd = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
uData = 0x0;
|
||||||
|
m_currrent_cmd = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
INFO_LOG(EXPANSIONINTERFACE, "AGP read %x", uData);
|
||||||
|
return uData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEXIAgp::ImmWrite(u32 _uData, u32 _uSize)
|
||||||
|
{
|
||||||
|
if ((_uSize == 1) && ((_uData & 0xFF000000) == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8 HashCmd;
|
||||||
|
u64 Mask;
|
||||||
|
INFO_LOG(EXPANSIONINTERFACE, "AGP command %x", _uData);
|
||||||
|
switch (m_currrent_cmd)
|
||||||
|
{
|
||||||
|
case 0xAE020000:
|
||||||
|
case 0xAE030000:
|
||||||
|
m_rw_offset = ((_uData & 0xFFFFFF00) >> 7) & m_rom_mask;
|
||||||
|
m_return_pos = 0;
|
||||||
|
HashCmd = (_uData & 0xFF000000) >> 24;
|
||||||
|
DoHash(&HashCmd, 1);
|
||||||
|
HashCmd = (_uData & 0x00FF0000) >> 16;
|
||||||
|
DoHash(&HashCmd, 1);
|
||||||
|
HashCmd = (_uData & 0x0000FF00) >> 8;
|
||||||
|
DoHash(&HashCmd, 1);
|
||||||
|
break;
|
||||||
|
case 0xAE0C0000:
|
||||||
|
if ((m_eeprom_pos < 0x8) || (m_eeprom_pos == ((m_eeprom_cmd & EE_READ) ? 0x8 : 0x48)))
|
||||||
|
{
|
||||||
|
Mask = (u64)(1 << (0x8-(m_eeprom_pos > 0x8 ? 0x8 : m_eeprom_pos)));
|
||||||
|
if ((_uData >> 16) & 0x1)
|
||||||
|
m_eeprom_cmd |= Mask;
|
||||||
|
else
|
||||||
|
m_eeprom_cmd &= ~Mask;
|
||||||
|
if (m_eeprom_pos == 0x48)
|
||||||
|
((u64*)(m_pEEPROM))[(m_eeprom_cmd >> 1) & 0x3F] = m_eeprom_data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Mask = (u64)(1 << (0x47 - m_eeprom_pos));
|
||||||
|
if ((_uData >> 16) & 0x1)
|
||||||
|
m_eeprom_data |= Mask;
|
||||||
|
else
|
||||||
|
m_eeprom_data &= ~Mask;
|
||||||
|
}
|
||||||
|
m_eeprom_pos++;
|
||||||
|
m_return_pos = 0;
|
||||||
|
HashCmd = (_uData & 0xFF000000) >> 24;
|
||||||
|
DoHash(&HashCmd, 1);
|
||||||
|
HashCmd = (_uData & 0x00FF0000) >> 16;
|
||||||
|
DoHash(&HashCmd, 1);
|
||||||
|
break;
|
||||||
|
case 0xAE0B0000:
|
||||||
|
break;
|
||||||
|
case 0xAE000000:
|
||||||
|
case 0xAE010000:
|
||||||
|
case 0xAE090000:
|
||||||
|
case 0xAE0A0000:
|
||||||
|
default:
|
||||||
|
m_eeprom_pos = 0;
|
||||||
|
m_currrent_cmd = _uData;
|
||||||
|
m_return_pos = 0;
|
||||||
|
m_hash = 0xFF;
|
||||||
|
HashCmd = (_uData & 0x00FF0000) >> 16;
|
||||||
|
DoHash(&HashCmd, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEXIAgp::DoState(PointerWrap &p)
|
||||||
|
{
|
||||||
|
p.Do(m_position);
|
||||||
|
p.Do(m_address);
|
||||||
|
p.Do(m_rw_offset);
|
||||||
|
p.Do(m_hash);
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright 2013 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include "Core/HW/EXI_Device.h"
|
||||||
|
|
||||||
|
class CEXIAgp
|
||||||
|
: public IEXIDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CEXIAgp(const int index);
|
||||||
|
virtual ~CEXIAgp() override;
|
||||||
|
bool IsPresent() override { return true; }
|
||||||
|
void ImmWrite(u32 _uData, u32 _uSize) override;
|
||||||
|
u32 ImmRead(u32 _uSize) override;
|
||||||
|
void DoState(PointerWrap &p) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
HASH_SIZE = 256,
|
||||||
|
HASH_MASK = (HASH_SIZE - 1),
|
||||||
|
EE_READ = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_slot;
|
||||||
|
|
||||||
|
//! ROM
|
||||||
|
u32 m_rom_size = 0;
|
||||||
|
u32 m_rom_mask = 0;
|
||||||
|
u32 m_eeprom_size = 0;
|
||||||
|
u32 m_eeprom_mask = 0;
|
||||||
|
u8* m_pROM;
|
||||||
|
u8* m_pEEPROM;
|
||||||
|
u8* m_pHashArray;
|
||||||
|
|
||||||
|
//! Helper
|
||||||
|
u32 m_position = 0;
|
||||||
|
u32 m_address = 0;
|
||||||
|
u32 m_rw_offset = 0;
|
||||||
|
u64 m_eeprom_data = 0;
|
||||||
|
u8 m_eeprom_pos = 0;
|
||||||
|
u16 m_eeprom_cmd = 0;
|
||||||
|
|
||||||
|
void LoadFileToROM(std::string filename);
|
||||||
|
void LoadFileToEEPROM(std::string filename);
|
||||||
|
void LoadHash();
|
||||||
|
void LoadRom();
|
||||||
|
void DoHash(u8* data, u32 size);
|
||||||
|
|
||||||
|
u8 m_hash = 0;
|
||||||
|
u32 m_currrent_cmd = 0;
|
||||||
|
u32 m_return_pos = 0;
|
||||||
|
|
||||||
|
bool m_rom_hash_loaded = false;
|
||||||
|
};
|
|
@ -111,6 +111,7 @@ static const wxLanguage langIds[] =
|
||||||
#define EXIDEV_MEMDIR_STR _trans("GCI Folder")
|
#define EXIDEV_MEMDIR_STR _trans("GCI Folder")
|
||||||
#define EXIDEV_MIC_STR _trans("Mic")
|
#define EXIDEV_MIC_STR _trans("Mic")
|
||||||
#define EXIDEV_BBA_STR "BBA"
|
#define EXIDEV_BBA_STR "BBA"
|
||||||
|
#define EXIDEV_AGP_STR "Advance Game Port"
|
||||||
#define EXIDEV_AM_BB_STR _trans("AM-Baseboard")
|
#define EXIDEV_AM_BB_STR _trans("AM-Baseboard")
|
||||||
#define EXIDEV_GECKO_STR "USBGecko"
|
#define EXIDEV_GECKO_STR "USBGecko"
|
||||||
|
|
||||||
|
@ -382,8 +383,9 @@ void CConfigMain::InitializeGUIValues()
|
||||||
SlotDevices.Add(_(DEV_NONE_STR));
|
SlotDevices.Add(_(DEV_NONE_STR));
|
||||||
SlotDevices.Add(_(DEV_DUMMY_STR));
|
SlotDevices.Add(_(DEV_DUMMY_STR));
|
||||||
SlotDevices.Add(_(EXIDEV_MEMCARD_STR));
|
SlotDevices.Add(_(EXIDEV_MEMCARD_STR));
|
||||||
SlotDevices.Add(_(EXIDEV_GECKO_STR));
|
|
||||||
SlotDevices.Add(_(EXIDEV_MEMDIR_STR));
|
SlotDevices.Add(_(EXIDEV_MEMDIR_STR));
|
||||||
|
SlotDevices.Add(_(EXIDEV_GECKO_STR));
|
||||||
|
SlotDevices.Add(_(EXIDEV_AGP_STR));
|
||||||
|
|
||||||
#if HAVE_PORTAUDIO
|
#if HAVE_PORTAUDIO
|
||||||
SlotDevices.Add(_(EXIDEV_MIC_STR));
|
SlotDevices.Add(_(EXIDEV_MIC_STR));
|
||||||
|
@ -415,10 +417,16 @@ void CConfigMain::InitializeGUIValues()
|
||||||
isMemcard = GCEXIDevice[i]->SetStringSelection(SlotDevices[2]);
|
isMemcard = GCEXIDevice[i]->SetStringSelection(SlotDevices[2]);
|
||||||
break;
|
break;
|
||||||
case EXIDEVICE_MEMORYCARDFOLDER:
|
case EXIDEVICE_MEMORYCARDFOLDER:
|
||||||
|
GCEXIDevice[i]->SetStringSelection(SlotDevices[3]);
|
||||||
|
break;
|
||||||
|
case EXIDEVICE_GECKO:
|
||||||
GCEXIDevice[i]->SetStringSelection(SlotDevices[4]);
|
GCEXIDevice[i]->SetStringSelection(SlotDevices[4]);
|
||||||
break;
|
break;
|
||||||
|
case EXIDEVICE_AGP:
|
||||||
|
isMemcard = GCEXIDevice[i]->SetStringSelection(SlotDevices[5]);
|
||||||
|
break;
|
||||||
case EXIDEVICE_MIC:
|
case EXIDEVICE_MIC:
|
||||||
GCEXIDevice[i]->SetStringSelection(SlotDevices[5]);
|
GCEXIDevice[i]->SetStringSelection(SlotDevices[6]);
|
||||||
break;
|
break;
|
||||||
case EXIDEVICE_ETH:
|
case EXIDEVICE_ETH:
|
||||||
GCEXIDevice[i]->SetStringSelection(SP1Devices[2]);
|
GCEXIDevice[i]->SetStringSelection(SP1Devices[2]);
|
||||||
|
@ -426,9 +434,6 @@ void CConfigMain::InitializeGUIValues()
|
||||||
case EXIDEVICE_AM_BASEBOARD:
|
case EXIDEVICE_AM_BASEBOARD:
|
||||||
GCEXIDevice[i]->SetStringSelection(SP1Devices[3]);
|
GCEXIDevice[i]->SetStringSelection(SP1Devices[3]);
|
||||||
break;
|
break;
|
||||||
case EXIDEVICE_GECKO:
|
|
||||||
GCEXIDevice[i]->SetStringSelection(SlotDevices[3]);
|
|
||||||
break;
|
|
||||||
case EXIDEVICE_DUMMY:
|
case EXIDEVICE_DUMMY:
|
||||||
default:
|
default:
|
||||||
GCEXIDevice[i]->SetStringSelection(SlotDevices[1]);
|
GCEXIDevice[i]->SetStringSelection(SlotDevices[1]);
|
||||||
|
@ -1015,68 +1020,98 @@ void CConfigMain::GCSettingsChanged(wxCommandEvent& event)
|
||||||
ChooseEXIDevice(event.GetString(), exidevice);
|
ChooseEXIDevice(event.GetString(), exidevice);
|
||||||
break;
|
break;
|
||||||
case ID_GC_EXIDEVICE_SLOTA_PATH:
|
case ID_GC_EXIDEVICE_SLOTA_PATH:
|
||||||
ChooseMemcardPath(SConfig::GetInstance().m_strMemoryCardA, true);
|
ChooseSlotPath(true, SConfig::GetInstance().m_EXIDevice[0]);
|
||||||
break;
|
break;
|
||||||
case ID_GC_EXIDEVICE_SLOTB_PATH:
|
case ID_GC_EXIDEVICE_SLOTB_PATH:
|
||||||
ChooseMemcardPath(SConfig::GetInstance().m_strMemoryCardB, false);
|
ChooseSlotPath(false, SConfig::GetInstance().m_EXIDevice[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigMain::ChooseMemcardPath(std::string& strMemcard, bool isSlotA)
|
void CConfigMain::ChooseSlotPath(bool isSlotA, TEXIDevices device_type)
|
||||||
{
|
{
|
||||||
|
bool memcard = (device_type == EXIDEVICE_MEMORYCARD);
|
||||||
|
std::string path;
|
||||||
|
std::string cardname;
|
||||||
|
std::string ext;
|
||||||
|
std::string pathA = SConfig::GetInstance().m_strMemoryCardA;
|
||||||
|
std::string pathB = SConfig::GetInstance().m_strMemoryCardB;
|
||||||
|
if (!memcard)
|
||||||
|
{
|
||||||
|
pathA = SConfig::GetInstance().m_strGbaCartA;
|
||||||
|
pathB = SConfig::GetInstance().m_strGbaCartB;
|
||||||
|
}
|
||||||
|
SplitPath(isSlotA ? pathA : pathB, &path, &cardname, &ext);
|
||||||
std::string filename = WxStrToStr(wxFileSelector(
|
std::string filename = WxStrToStr(wxFileSelector(
|
||||||
_("Choose a file to open"),
|
_("Choose a file to open"),
|
||||||
StrToWxStr(File::GetUserPath(D_GCUSER_IDX)),
|
StrToWxStr(path),
|
||||||
isSlotA ? GC_MEMCARDA : GC_MEMCARDB,
|
StrToWxStr(cardname),
|
||||||
wxEmptyString,
|
StrToWxStr(ext),
|
||||||
_("GameCube Memory Cards (*.raw,*.gcp)") + "|*.raw;*.gcp"));
|
memcard ? _("GameCube Memory Cards (*.raw,*.gcp)") + "|*.raw;*.gcp" : _("Game Boy Advance Carts (*.gba)") + "|*.gba"));
|
||||||
|
|
||||||
if (!filename.empty())
|
if (!filename.empty())
|
||||||
{
|
{
|
||||||
if (File::Exists(filename))
|
if (File::Exists(filename))
|
||||||
{
|
{
|
||||||
GCMemcard memorycard(filename);
|
if (memcard)
|
||||||
if (!memorycard.IsValid())
|
{
|
||||||
|
GCMemcard memorycard(filename);
|
||||||
|
if (!memorycard.IsValid())
|
||||||
|
{
|
||||||
|
WxUtils::ShowErrorDialog(wxString::Format(_("Cannot use that file as a memory card.\n%s\n" \
|
||||||
|
"is not a valid gamecube memory card file"), filename.c_str()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
WxUtils::ShowErrorDialog(wxString::Format(_("Cannot use that file as a memory card.\n%s\n" \
|
|
||||||
"is not a valid gamecube memory card file"), filename.c_str()));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (!strncmp(File::GetExeDirectory().c_str(), filename.c_str(), File::GetExeDirectory().size()))
|
if (!strncmp(File::GetExeDirectory().c_str(), filename.c_str(), File::GetExeDirectory().size()))
|
||||||
|
{
|
||||||
|
// If the Exe Directory Matches the prefix of the filename, we still need to verify
|
||||||
|
// that the next character is a directory separator character, otherwise we may create an invalid path
|
||||||
|
char next_char = filename.at(File::GetExeDirectory().size()) + 1;
|
||||||
|
if (next_char == '/' || next_char == '\\')
|
||||||
{
|
{
|
||||||
// If the Exe Directory Matches the prefix of the filename, we still need to verify
|
filename.erase(0, File::GetExeDirectory().size() + 1);
|
||||||
// that the next character is a directory separator character, otherwise we may create an invalid path
|
filename = "./" + filename;
|
||||||
char next_char = filename.at(File::GetExeDirectory().size())+1;
|
|
||||||
if (next_char == '/' || next_char == '\\')
|
|
||||||
{
|
|
||||||
filename.erase(0, File::GetExeDirectory().size() +1);
|
|
||||||
filename = "./" + filename;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// also check that the path isn't used for the other memcard...
|
// also check that the path isn't used for the other memcard...
|
||||||
if (filename.compare(isSlotA ? SConfig::GetInstance().m_strMemoryCardB
|
if (filename.compare(isSlotA ? pathB : pathA) != 0)
|
||||||
: SConfig::GetInstance().m_strMemoryCardA) != 0)
|
|
||||||
{
|
{
|
||||||
strMemcard = filename;
|
if (memcard)
|
||||||
|
{
|
||||||
|
if (isSlotA)
|
||||||
|
SConfig::GetInstance().m_strMemoryCardA = filename;
|
||||||
|
else
|
||||||
|
SConfig::GetInstance().m_strMemoryCardB = filename;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isSlotA)
|
||||||
|
SConfig::GetInstance().m_strGbaCartA = filename;
|
||||||
|
else
|
||||||
|
SConfig::GetInstance().m_strGbaCartB = filename;
|
||||||
|
}
|
||||||
|
|
||||||
if (Core::IsRunning())
|
if (Core::IsRunning())
|
||||||
{
|
{
|
||||||
// Change memcard to the new file
|
// Change memcard to the new file
|
||||||
ExpansionInterface::ChangeDevice(
|
ExpansionInterface::ChangeDevice(
|
||||||
isSlotA ? 0 : 1, // SlotA: channel 0, SlotB channel 1
|
isSlotA ? 0 : 1, // SlotA: channel 0, SlotB channel 1
|
||||||
EXIDEVICE_MEMORYCARD,
|
device_type,
|
||||||
0); // SP1 is device 2, slots are device 0
|
0); // SP1 is device 2, slots are device 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WxUtils::ShowErrorDialog(_("Cannot use that file as a memory card.\n"
|
WxUtils::ShowErrorDialog(_("Are you trying to use the same file in both slots?"));
|
||||||
"Are you trying to use the same file in both slots?"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1093,6 +1128,8 @@ void CConfigMain::ChooseEXIDevice(wxString deviceName, int deviceNum)
|
||||||
tempType = EXIDEVICE_MIC;
|
tempType = EXIDEVICE_MIC;
|
||||||
else if (!deviceName.compare(EXIDEV_BBA_STR))
|
else if (!deviceName.compare(EXIDEV_BBA_STR))
|
||||||
tempType = EXIDEVICE_ETH;
|
tempType = EXIDEVICE_ETH;
|
||||||
|
else if (!deviceName.compare(EXIDEV_AGP_STR))
|
||||||
|
tempType = EXIDEVICE_AGP;
|
||||||
else if (!deviceName.compare(_(EXIDEV_AM_BB_STR)))
|
else if (!deviceName.compare(_(EXIDEV_AM_BB_STR)))
|
||||||
tempType = EXIDEVICE_AM_BASEBOARD;
|
tempType = EXIDEVICE_AM_BASEBOARD;
|
||||||
else if (!deviceName.compare(EXIDEV_GECKO_STR))
|
else if (!deviceName.compare(EXIDEV_GECKO_STR))
|
||||||
|
@ -1102,8 +1139,8 @@ void CConfigMain::ChooseEXIDevice(wxString deviceName, int deviceNum)
|
||||||
else
|
else
|
||||||
tempType = EXIDEVICE_DUMMY;
|
tempType = EXIDEVICE_DUMMY;
|
||||||
|
|
||||||
// Gray out the memcard path button if we're not on a memcard
|
// Gray out the memcard path button if we're not on a memcard or AGP
|
||||||
if (tempType == EXIDEVICE_MEMORYCARD)
|
if (tempType == EXIDEVICE_MEMORYCARD || tempType == EXIDEVICE_AGP)
|
||||||
GCMemcardPath[deviceNum]->Enable();
|
GCMemcardPath[deviceNum]->Enable();
|
||||||
else if (deviceNum == 0 || deviceNum == 1)
|
else if (deviceNum == 0 || deviceNum == 1)
|
||||||
GCMemcardPath[deviceNum]->Disable();
|
GCMemcardPath[deviceNum]->Disable();
|
||||||
|
|
|
@ -254,7 +254,7 @@ private:
|
||||||
void AddAudioBackends();
|
void AddAudioBackends();
|
||||||
|
|
||||||
void GCSettingsChanged(wxCommandEvent& event);
|
void GCSettingsChanged(wxCommandEvent& event);
|
||||||
void ChooseMemcardPath(std::string& strMemcard, bool isSlotA);
|
void ChooseSlotPath(bool isSlotA, TEXIDevices device_type);
|
||||||
void ChooseEXIDevice(wxString deviceName, int deviceNum);
|
void ChooseEXIDevice(wxString deviceName, int deviceNum);
|
||||||
|
|
||||||
void WiiSettingsChanged(wxCommandEvent& event);
|
void WiiSettingsChanged(wxCommandEvent& event);
|
||||||
|
|
Loading…
Reference in New Issue