reorganize SI and EXI interfaces, add a gui for picking devices. XK, that was annoying. Now, you can deal with SI_Channel. This commit changes how memcards are handled a little, now they are .REGION.raw, like .USA.raw, and can be in any dir.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2075 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman
2009-02-02 22:29:33 +00:00
parent cdf0349646
commit cfc128abff
26 changed files with 1199 additions and 837 deletions
+28 -26
View File
@@ -36,6 +36,7 @@
#define CACHE_DIR "Cache"
#define STATESAVES_DIR "StateSaves"
#define SCREENSHOTS_DIR "ScreenShots"
#define DUMP_DIR "Dump"
#define LOGS_DIR "Logs"
#define MAIL_LOGS_DIR "Mail"
@@ -48,10 +49,10 @@
#define DEBUGGER_CONFIG "Debugger.ini"
#define TOTALDB "totaldb.dsy"
#define DEFAULT_GFX_PLUGIN PLUGIN_PREFIX "Plugin_VideoOGL" PLUGIN_SUFFIX
#define DEFAULT_DSP_PLUGIN PLUGIN_PREFIX "Plugin_DSP_HLE" PLUGIN_SUFFIX
#define DEFAULT_PAD_PLUGIN PLUGIN_PREFIX "Plugin_PadSimple" PLUGIN_SUFFIX
#define DEFAULT_WIIMOTE_PLUGIN PLUGIN_PREFIX "Plugin_Wiimote" PLUGIN_SUFFIX
#define DEFAULT_GFX_PLUGIN PLUGIN_PREFIX "Plugin_VideoOGL" PLUGIN_SUFFIX
#define DEFAULT_DSP_PLUGIN PLUGIN_PREFIX "Plugin_DSP_HLE" PLUGIN_SUFFIX
#define DEFAULT_PAD_PLUGIN PLUGIN_PREFIX "Plugin_PadSimple" PLUGIN_SUFFIX
#define DEFAULT_WIIMOTE_PLUGIN PLUGIN_PREFIX "Plugin_Wiimote" PLUGIN_SUFFIX
#define FONT_ANSI "font_ansi.bin"
#define FONT_SJIS "font_sjis.bin"
@@ -61,8 +62,8 @@
#define GC_IPL "IPL.bin"
#define GC_SRAM "SRAM.raw"
#define GC_MEMCARDA "MemoryCardA.raw"
#define GC_MEMCARDB "MemoryCardB.raw"
#define GC_MEMCARDA "MemoryCardA"
#define GC_MEMCARDB "MemoryCardB"
#define WII_MASTERKEY "masterkey.bin"
#define WII_MASTERKEY_HEX "masterkey.txt"
@@ -76,54 +77,55 @@
// User dirs
#define FULL_USERDATA_DIR ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP
#define FULL_GC_USER_DIR FULL_USERDATA_DIR GC_USER_DIR DIR_SEP
#define FULL_GC_USER_DIR FULL_USERDATA_DIR GC_USER_DIR DIR_SEP
//#define GC_USER_EUR_DIR FULL_GC_USER_DIR EUR_DIR
//#define GC_USER_USA_DIR FULL_GC_USER_DIR USA_DIR
//#define GC_USER_JAP_DIR FULL_GC_USER_DIR JAP_DIR
#define FULL_WII_USER_DIR FULL_USERDATA_DIR WII_USER_DIR DIR_SEP
#define FULL_WII_ROOT_DIR FULL_USERDATA_DIR WII_USER_DIR // This is the "root" for Wii fs, so that it may be used with created devices
#define FULL_WII_USER_DIR FULL_USERDATA_DIR WII_USER_DIR DIR_SEP
#define FULL_WII_ROOT_DIR FULL_USERDATA_DIR WII_USER_DIR // This is the "root" for Wii fs, so that it may be used with created devices
#define FULL_GAMECONFIG_DIR FULL_USERDATA_DIR GAMECONFIG_DIR DIR_SEP
#define FULL_CONFIG_DIR FULL_USERDATA_DIR CONFIG_DIR DIR_SEP
#define FULL_CACHE_DIR FULL_USERDATA_DIR CACHE_DIR DIR_SEP
#define FULL_STATESAVES_DIR FULL_USERDATA_DIR STATESAVES_DIR DIR_SEP
#define FULL_SCREENSHOTS_DIR FULL_USERDATA_DIR SCREENSHOTS_DIR DIR_SEP
#define FULL_DUMP_DIR FULL_USERDATA_DIR DUMP_DIR DIR_SEP
#define FULL_LOGS_DIR FULL_USERDATA_DIR LOGS_DIR DIR_SEP
#define FULL_MAIL_LOGS_DIR FULL_LOGS_DIR MAIL_LOGS_DIR DIR_SEP
#define FULL_MAPS_DIR FULL_USERDATA_DIR MAPS_DIR DIR_SEP
#define FULL_MAIL_LOGS_DIR FULL_LOGS_DIR MAIL_LOGS_DIR DIR_SEP
#define FULL_MAPS_DIR FULL_USERDATA_DIR MAPS_DIR DIR_SEP
#define FULL_MEMORY_DUMP_DIR FULL_CACHE_DIR MEMORY_DUMP_FILE
// Sys dirs
#define FULL_SYSDATA_DIR ROOT_DIR DIR_SEP SYSDATA_DIR DIR_SEP
#define FULL_GC_SYS_DIR FULL_SYSDATA_DIR GC_SYS_DIR DIR_SEP
#define FULL_GC_SYS_DIR FULL_SYSDATA_DIR GC_SYS_DIR DIR_SEP
//#define GC_SYS_EUR_DIR FULL_GC_SYS_DIR EUR_DIR
//#define GC_SYS_USA_DIR FULL_GC_SYS_DIR USA_DIR
//#define GC_SYS_JAP_DIR FULL_GC_SYS_DIR JAP_DIR
#define FULL_WII_SYS_DIR FULL_SYSDATA_DIR WII_SYS_DIR DIR_SEP
#define FULL_WII_SYS_DIR FULL_SYSDATA_DIR WII_SYS_DIR DIR_SEP
// Shorts - files
// User files
#define CONFIG_FILE FULL_CONFIG_DIR DOLPHIN_CONFIG
#define DEBUGGER_CONFIG_FILE FULL_CONFIG_DIR DEBUGGER_CONFIG
#define TOTALDB_FILE FULL_SYSDATA_DIR TOTALDB
#define CONFIG_FILE FULL_CONFIG_DIR DOLPHIN_CONFIG
#define DEBUGGER_CONFIG_FILE FULL_CONFIG_DIR DEBUGGER_CONFIG
#define TOTALDB_FILE FULL_SYSDATA_DIR TOTALDB
#define GC_SRAM_FILE FULL_USERDATA_DIR GC_USER_DIR DIR_SEP GC_SRAM
#define GC_SRAM_FILE FULL_USERDATA_DIR GC_USER_DIR DIR_SEP GC_SRAM
// Sys files
#define FONT_ANSI_FILE FULL_GC_SYS_DIR FONT_ANSI
#define FONT_SJIS_FILE FULL_GC_SYS_DIR FONT_SJIS
#define FONT_ANSI_FILE FULL_GC_SYS_DIR FONT_ANSI
#define FONT_SJIS_FILE FULL_GC_SYS_DIR FONT_SJIS
#define DSP_ROM_FILE FULL_GC_SYS_DIR DSP_ROM
#define DSP_COEF_FILE FULL_GC_SYS_DIR DSP_COEF
#define DSP_ROM_FILE FULL_GC_SYS_DIR DSP_ROM
#define DSP_COEF_FILE FULL_GC_SYS_DIR DSP_COEF
#define WII_MASTERKEY_FILE FULL_WII_SYS_DIR WII_MASTERKEY
#define WII_MASTERKEY_FILE_HEX FULL_WII_SYS_DIR WII_MASTERKEY_HEX
#define WII_EUR_SETTING_FILE FULL_WII_SYS_DIR WII_EUR_SETTING
#define WII_USA_SETTING_FILE FULL_WII_SYS_DIR WII_USA_SETTING
#define WII_JAP_SETTING_FILE FULL_WII_SYS_DIR WII_JAP_SETTING
#define WII_MASTERKEY_FILE FULL_WII_SYS_DIR WII_MASTERKEY
#define WII_MASTERKEY_FILE_HEX FULL_WII_SYS_DIR WII_MASTERKEY_HEX
#define WII_EUR_SETTING_FILE FULL_WII_SYS_DIR WII_EUR_SETTING
#define WII_USA_SETTING_FILE FULL_WII_SYS_DIR WII_USA_SETTING
#define WII_JAP_SETTING_FILE FULL_WII_SYS_DIR WII_JAP_SETTING
#endif // PATHS_H
+10 -2
View File
@@ -618,6 +618,14 @@
RelativePath=".\Src\HW\SI.h"
>
</File>
<File
RelativePath=".\Src\HW\SI_Channel.cpp"
>
</File>
<File
RelativePath=".\Src\HW\SI_Channel.h"
>
</File>
<File
RelativePath=".\Src\HW\SI_Device.cpp"
>
@@ -627,11 +635,11 @@
>
</File>
<File
RelativePath=".\Src\HW\SI_DeviceGBAController.cpp"
RelativePath=".\Src\HW\SI_DeviceGBA.cpp"
>
</File>
<File
RelativePath=".\Src\HW\SI_DeviceGBAController.h"
RelativePath=".\Src\HW\SI_DeviceGBA.h"
>
</File>
<File
+37 -22
View File
@@ -76,19 +76,30 @@ void SConfig::SaveSettings()
ini.Set("Interface", "Language", m_InterfaceLanguage);
// Core
ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios);
ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseJIT);
ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore);
ini.Set("Core", "SkipIdle", m_LocalCoreStartupParameter.bSkipIdle);
ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads);
ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM);
ini.Set("Core", "DVDRoot", m_LocalCoreStartupParameter.m_strDVDRoot);
ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios);
ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseJIT);
ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore);
ini.Set("Core", "SkipIdle", m_LocalCoreStartupParameter.bSkipIdle);
ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads);
ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM);
ini.Set("Core", "DVDRoot", m_LocalCoreStartupParameter.m_strDVDRoot);
ini.Set("Core", "OptimizeQuantizers", m_LocalCoreStartupParameter.bOptimizeQuantizers);
ini.Set("Core", "EnableCheats", m_LocalCoreStartupParameter.bEnableCheats);
ini.Set("Core", "SelectedLanguage", m_LocalCoreStartupParameter.SelectedLanguage);
ini.Set("Core", "EnableCheats", m_LocalCoreStartupParameter.bEnableCheats);
ini.Set("Core", "SelectedLanguage", m_LocalCoreStartupParameter.SelectedLanguage);
ini.Set("Core", "MemcardA", m_strMemoryCardA);
ini.Set("Core", "MemcardB", m_strMemoryCardB);
ini.Set("Core", "SlotA", m_EXIDevice[0]);
ini.Set("Core", "SlotB", m_EXIDevice[1]);
ini.Set("Core", "SerialPort1", m_EXIDevice[2]);
char sidevicenum[16];
for (int i = 0; i < 4; ++i)
{
sprintf(sidevicenum, "SIDevice%i", i);
ini.Set("Core", sidevicenum, m_SIDevice[i]);
}
ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer);
ini.Set("Core", "RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient);
ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer);
ini.Set("Core", "RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient);
// Plugins
ini.Set("Core", "GFXPlugin", m_LocalCoreStartupParameter.m_strVideoPlugin);
@@ -98,9 +109,6 @@ void SConfig::SaveSettings()
ini.Set("Core", "Pad3Plugin", m_LocalCoreStartupParameter.m_strPadPlugin[2]);
ini.Set("Core", "Pad4Plugin", m_LocalCoreStartupParameter.m_strPadPlugin[3]);
ini.Set("Core", "WiiMote1Plugin", m_LocalCoreStartupParameter.m_strWiimotePlugin[0]);
ini.Set("Core", "WiiMote2Plugin", m_LocalCoreStartupParameter.m_strWiimotePlugin[1]);
ini.Set("Core", "WiiMote3Plugin", m_LocalCoreStartupParameter.m_strWiimotePlugin[2]);
ini.Set("Core", "WiiMote4Plugin", m_LocalCoreStartupParameter.m_strWiimotePlugin[3]);
}
ini.Save(CONFIG_FILE);
@@ -141,9 +149,9 @@ void SConfig::LoadSettings()
// Hard coded default plugin
{
m_DefaultGFXPlugin = PLUGINS_DIR DIR_SEP DEFAULT_GFX_PLUGIN;
m_DefaultDSPPlugin = PLUGINS_DIR DIR_SEP DEFAULT_DSP_PLUGIN;
m_DefaultPADPlugin = PLUGINS_DIR DIR_SEP DEFAULT_PAD_PLUGIN;
m_DefaultWiiMotePlugin = PLUGINS_DIR DIR_SEP DEFAULT_WIIMOTE_PLUGIN;
m_DefaultDSPPlugin = PLUGINS_DIR DIR_SEP DEFAULT_DSP_PLUGIN;
m_DefaultPADPlugin = PLUGINS_DIR DIR_SEP DEFAULT_PAD_PLUGIN;
m_DefaultWiiMotePlugin = PLUGINS_DIR DIR_SEP DEFAULT_WIIMOTE_PLUGIN;
}
#endif
// General
@@ -188,6 +196,17 @@ void SConfig::LoadSettings()
ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true);
ini.Get("Core", "EnableCheats", &m_LocalCoreStartupParameter.bEnableCheats, false);
ini.Get("Core", "SelectedLanguage", &m_LocalCoreStartupParameter.SelectedLanguage, 0);
ini.Get("Core", "MemcardA", &m_strMemoryCardA);
ini.Get("Core", "MemcardB", &m_strMemoryCardB);
ini.Get("Core", "SlotA", (int*)&m_EXIDevice[0]);
ini.Get("Core", "SlotB", (int*)&m_EXIDevice[1]);
ini.Get("Core", "SerialPort1", (int*)&m_EXIDevice[2]);
char sidevicenum[16];
for (int i = 0; i < 4; ++i)
{
sprintf(sidevicenum, "SIDevice%i", i);
ini.Get("Core", sidevicenum, (u32*)&m_SIDevice[i]);
}
ini.Get("Core", "RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false);
ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false);
@@ -201,10 +220,6 @@ void SConfig::LoadSettings()
std::string TmpName = StringFromFormat("Pad%iPlugin", (i + 1));
ini.Get("Core", TmpName.c_str(), &m_LocalCoreStartupParameter.m_strPadPlugin[i], m_DefaultPADPlugin.c_str());
}
for (int i = 0; i < MAXWIIMOTES; i++)
{
std::string TmpName = StringFromFormat("WiiMote%iPlugin", (i + 1));
ini.Get("Core", "WiiMote1Plugin", &m_LocalCoreStartupParameter.m_strWiimotePlugin[i], m_DefaultWiiMotePlugin.c_str());
}
ini.Get("Core", "WiiMote1Plugin", &m_LocalCoreStartupParameter.m_strWiimotePlugin[0], m_DefaultWiiMotePlugin.c_str());
}
}
+7
View File
@@ -22,6 +22,8 @@
#include <vector>
#include "Boot/Boot.h"
#include "HW/EXI_Device.h"
#include "HW/SI_Device.h"
// HyperIris: not sure but a temporary implement
enum INTERFACE_LANGUAGE
@@ -52,6 +54,11 @@ struct SConfig
SCoreStartupParameter m_LocalCoreStartupParameter;
std::string m_strMemoryCardA;
std::string m_strMemoryCardB;
TEXIDevices m_EXIDevice[3];
TSIDevices m_SIDevice[4];
// interface language
INTERFACE_LANGUAGE m_InterfaceLanguage;
// save settings
+52 -4
View File
@@ -24,6 +24,7 @@
#include "Boot/Boot.h" // Core
#include "Boot/Boot_DOL.h"
#include "CoreParameter.h"
#include "ConfigManager.h"
#include "Core.h" // for bWii
SCoreStartupParameter::SCoreStartupParameter()
@@ -155,10 +156,10 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
}
// Setup paths
m_strBios = FULL_GC_SYS_DIR + Region + DIR_SEP GC_IPL;
m_strMemoryCardA = FULL_GC_USER_DIR + Region + DIR_SEP GC_MEMCARDA;
m_strMemoryCardB = FULL_GC_USER_DIR + Region + DIR_SEP GC_MEMCARDB;
m_strSRAM = GC_SRAM_FILE;
CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, Region, true);
CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, Region, false);
m_strSRAM = GC_SRAM_FILE;
m_strBios = FULL_GC_SYS_DIR + Region + DIR_SEP GC_IPL;
if (!File::Exists(m_strBios.c_str())) {
LOG(BOOT, "BIOS file %s not found - using HLE.", m_strBios.c_str());
bHLEBios = true;
@@ -166,3 +167,50 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
return true;
}
void SCoreStartupParameter::CheckMemcardPath(std::string& memcardPath, std::string gameRegion, bool isSlotA)
{
std::string ext("." + gameRegion + ".raw");
if (memcardPath.empty())
{
// Use default memcard path if there is no user defined name
std::string defaultFilename = isSlotA ? GC_MEMCARDA : GC_MEMCARDB;
memcardPath = FULL_GC_USER_DIR + defaultFilename + ext;
}
else
{
std::string filename = memcardPath;
std::string region = filename.substr(filename.size()-7, 3);
bool hasregion = false;
hasregion |= region.compare(USA_DIR) == 0;
hasregion |= region.compare(JAP_DIR) == 0;
hasregion |= region.compare(EUR_DIR) == 0;
if (!hasregion)
{
// filename doesn't have region in the extension
if (File::Exists(filename.c_str()))
{
// If the old file exists we are polite and ask if we should copy it
std::string oldFilename = filename;
filename.replace(filename.size()-4, 4, ext);
if (PanicYesNo("Memory Card filename in Slot %c is incorrect\n"
"Region not specified\n\n"
"Slot %c path was changed to\n"
"%s\n"
"Would you like to copy the old file to this new location?\n",
isSlotA ? 'A':'B', isSlotA ? 'A':'B', filename.c_str()))
{
if (!File::Copy(oldFilename.c_str(), filename.c_str()))
PanicAlert("Copy failed");
}
}
memcardPath = filename; // Always correct the path!
}
else if (region.compare(gameRegion) != 0)
{
// filename has region, but it's not == gameRegion
// Just set the correct filename, the EXI Device will create it if it doesn't exist
memcardPath = filename.replace(filename.size()-ext.size(), ext.size(), ext);;
}
}
}
+8 -11
View File
@@ -40,7 +40,7 @@ struct SCoreStartupParameter
bool bEnableDebugging; bool bAutomaticStart; bool bBootToPause;
bool bUseJIT;
// JIT
// JIT
bool bJITUnlimitedCache, bJITBlockLinking;
bool bJITOff;
bool bJITLoadStoreOff, bJITLoadStorelXzOff, bJITLoadStorelwzOff, bJITLoadStorelbzxOff;
@@ -69,9 +69,11 @@ struct SCoreStartupParameter
int SelectedLanguage;
bool bWii; bool bWiiLeds; bool bWiiSpeakers; // Wii settings
// Wii settings
bool bWii; bool bWiiLeds; bool bWiiSpeakers;
bool bConfirmStop, bHideCursor, bAutoHideCursor; // Interface settings
// Interface settings
bool bConfirmStop, bHideCursor, bAutoHideCursor;
int iTheme;
enum EBootBios
@@ -98,25 +100,20 @@ struct SCoreStartupParameter
std::string m_strWiimotePlugin[MAXWIIMOTES];
std::string m_strFilename;
std::string m_strBios;
std::string m_strMemoryCardA;
std::string m_strMemoryCardB;
std::string m_strBios;
std::string m_strSRAM;
std::string m_strDefaultGCM;
std::string m_strDVDRoot;
std::string m_strUniqueID;
std::string m_strName;
//
// Constructor just calls LoadDefaults
SCoreStartupParameter();
void LoadDefaults();
bool AutoSetup(EBootBios _BootBios);
const std::string &GetUniqueID() const { return m_strUniqueID; }
void CheckMemcardPath(std::string& memcardPath, std::string Region, bool isSlotA);
};
#endif
+11 -9
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -17,11 +17,11 @@
#include "Common.h"
#include "ChunkFile.h"
#include "../ConfigManager.h"
#include "PeripheralInterface.h"
#include "../PowerPC/PowerPC.h"
#include "EXI_Device.h"
#include "EXI_Channel.h"
namespace ExpansionInterface
@@ -36,17 +36,19 @@ CEXIChannel *g_Channels;
void Init()
{
g_Channels = new CEXIChannel[3];
g_Channels = new CEXIChannel[NUM_CHANNELS];
g_Channels[0].m_ChannelId = 0;
g_Channels[1].m_ChannelId = 1;
g_Channels[2].m_ChannelId = 2;
g_Channels[0].AddDevice(EXIDEVICE_MEMORYCARD_A, 0);
g_Channels[0].AddDevice(EXIDEVICE_IPL, 1);
g_Channels[1].AddDevice(EXIDEVICE_MEMORYCARD_B, 0);
//g_Channels[0].AddDevice(EXIDEVICE_ETH, 2);
//g_Channels[1].AddDevice(EXIDEVICE_MIC, 0);
g_Channels[2].AddDevice(EXIDEVICE_AD16, 0);
// m_EXIDevice[0] = SlotA
// m_EXIDevice[1] = SlotB
// m_EXIDevice[2] = Serial Port 1 (ETH)
g_Channels[0].AddDevice(SConfig::GetInstance().m_EXIDevice[0], 0);
g_Channels[0].AddDevice(EXIDEVICE_IPL, 1);
g_Channels[0].AddDevice(SConfig::GetInstance().m_EXIDevice[2], 2);
g_Channels[1].AddDevice(SConfig::GetInstance().m_EXIDevice[1], 0);
g_Channels[2].AddDevice(EXIDEVICE_AD16, 0);
}
void Shutdown()
+1 -2
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -36,4 +36,3 @@ void HWCALL Write32(const u32 _iValue, const u32 _iAddress);
} // end of namespace ExpansionInterface
#endif
+14 -13
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/
#include "EXI_Channel.h"
#include "EXI_Device.h"
#include "EXI.h"
#define EXI_READ 0
@@ -28,7 +29,7 @@
CEXIChannel::CEXIChannel() :
m_DMAMemoryAddress(0),
m_DMALength(0),
m_DMALength(0),
m_ImmData(0),
m_ChannelId(-1)
{
@@ -53,7 +54,7 @@ CEXIChannel::~CEXIChannel()
void CEXIChannel::RemoveDevices()
{
for (int i = 0; i < NUM_DEVICES; i++)
for (int i = 0; i < NUM_DEVICES; i++)
{
if (m_pDevices[i] != NULL)
{
@@ -101,7 +102,7 @@ bool CEXIChannel::IsCausingInterrupt()
if ((m_Status.EXIINT & m_Status.EXIINTMASK) ||
(m_Status.TCINT & m_Status.TCINTMASK) ||
(m_Status.EXTINT & m_Status.EXTINTMASK))
(m_Status.EXTINT & m_Status.EXTINTMASK))
{
return true;
}
@@ -113,7 +114,7 @@ bool CEXIChannel::IsCausingInterrupt()
IEXIDevice* CEXIChannel::GetDevice(u8 _CHIP_SELECT)
{
switch(_CHIP_SELECT)
switch(_CHIP_SELECT)
{
case 1: return m_pDevices[0];
case 2: return m_pDevices[1];
@@ -164,7 +165,7 @@ void CEXIChannel::Read32(u32& _uReturnValue, const u32 _iRegister)
_uReturnValue = m_Control.hex;
break;
case EXI_IMMDATA:
case EXI_IMMDATA:
_uReturnValue = m_ImmData;
break;
@@ -172,7 +173,7 @@ void CEXIChannel::Read32(u32& _uReturnValue, const u32 _iRegister)
_dbg_assert_(EXPANSIONINTERFACE, 0);
_uReturnValue = 0xDEADBEEF;
}
}
void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister)
@@ -185,12 +186,12 @@ void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister)
{
UEXI_STATUS newStatus(_iValue);
// static
// static
m_Status.EXIINTMASK = newStatus.EXIINTMASK;
m_Status.TCINTMASK = newStatus.TCINTMASK;
m_Status.EXTINTMASK = newStatus.EXTINTMASK;
m_Status.CLK = newStatus.CLK;
m_Status.ROMDIS = newStatus.ROMDIS;
m_Status.ROMDIS = newStatus.ROMDIS;
// Device
if (m_Status.CHIP_SELECT != newStatus.CHIP_SELECT)
@@ -200,7 +201,7 @@ void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister)
u8 dwDeviceMask = 1 << i;
IEXIDevice* pDevice = GetDevice(dwDeviceMask);
if (pDevice != NULL)
{
{
if (((newStatus.CHIP_SELECT & dwDeviceMask) == dwDeviceMask) &&
((m_Status.CHIP_SELECT & dwDeviceMask) == 0))
// device gets activated
@@ -211,8 +212,8 @@ void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister)
// device gets deactivated
pDevice->SetCS(0);
}
}
m_Status.CHIP_SELECT = newStatus.CHIP_SELECT;
}
m_Status.CHIP_SELECT = newStatus.CHIP_SELECT;
}
// External Status
@@ -262,7 +263,7 @@ void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister)
pDevice->ImmWrite(m_ImmData, m_Control.TLEN + 1);
m_ImmData = pDevice->ImmRead(m_Control.TLEN + 1); */
break;
default: _dbg_assert_msg_(EXPANSIONINTERFACE,0,"EXI Imm: Unknown transfer type %i", m_Control.RW);
}
m_Control.TSTART = 0;
+12 -12
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -40,18 +40,18 @@ private:
u32 hex;
struct
{
unsigned EXIINTMASK : 1; // 31
unsigned EXIINTMASK : 1; //31
unsigned EXIINT : 1; //30
unsigned TCINTMASK : 1; //29
unsigned TCINT : 1; //28
unsigned CLK : 3; //27
unsigned CLK : 3; //27
unsigned CHIP_SELECT : 3; //24
unsigned EXTINTMASK : 1; //21
unsigned EXTINT : 1; //20
unsigned EXT : 1; // External Insertion Status (1: External EXI device present) //19
unsigned ROMDIS : 1; // ROM Disable //18
unsigned EXT : 1; //19 // External Insertion Status (1: External EXI device present)
unsigned ROMDIS : 1; //18 // ROM Disable
unsigned :18;
};
};
UEXI_STATUS() {hex = 0;}
UEXI_STATUS(u32 _hex) {hex = _hex;}
};
@@ -60,7 +60,7 @@ private:
union UEXI_CONTROL
{
u32 hex;
struct
struct
{
unsigned TSTART : 1;
unsigned DMA : 1;
@@ -73,13 +73,13 @@ private:
// STATE_TO_SAVE
UEXI_STATUS m_Status;
UEXI_CONTROL m_Control;
u32 m_DMAMemoryAddress;
u32 m_DMALength;
u32 m_ImmData;
u32 m_DMAMemoryAddress;
u32 m_DMALength;
u32 m_ImmData;
// get device
IEXIDevice* GetDevice(u8 _CHIP_SELECT);
// Devices
enum
{
+28 -30
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,10 +26,10 @@
#include "../Core.h"
#include "../ConfigManager.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////
// --- interface IEXIDevice ---
/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// --- interface IEXIDevice ---
//////////////////////////////////////////////////////////////////////////
void IEXIDevice::ImmWrite(u32 _uData, u32 _uSize)
{
while (_uSize--)
@@ -56,21 +56,21 @@ u32 IEXIDevice::ImmRead(u32 _uSize)
void IEXIDevice::DMAWrite(u32 _uAddr, u32 _uSize)
{
// _dbg_assert_(EXPANSIONINTERFACE, 0);
while (_uSize--)
{
u8 uByte = Memory::Read_U8(_uAddr++);
TransferByte(uByte);
}
while (_uSize--)
{
u8 uByte = Memory::Read_U8(_uAddr++);
TransferByte(uByte);
}
}
void IEXIDevice::DMARead(u32 _uAddr, u32 _uSize)
void IEXIDevice::DMARead(u32 _uAddr, u32 _uSize)
{
// _dbg_assert_(EXPANSIONINTERFACE, 0);
while (_uSize--)
{
u8 uByte = 0;
TransferByte(uByte);
Memory::Write_U8(uByte, _uAddr++);
while (_uSize--)
{
u8 uByte = 0;
TransferByte(uByte);
Memory::Write_U8(uByte, _uAddr++);
}
};
@@ -92,11 +92,10 @@ void IEXIDevice::SetCS(int _iCS)
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// --- class CEXIDummy ---
/////////////////////////////////////////////////////////////////////////////////////////////////////
// just a dummy that logs reads and writes
//////////////////////////////////////////////////////////////////////////
// Just a dummy that logs reads and writes
// to be used for EXI devices we haven't emulated
class CEXIDummy : public IEXIDevice
{
@@ -112,15 +111,15 @@ public:
virtual ~CEXIDummy(){}
void ImmWrite(u32 data, u32 size){LOG(EXPANSIONINTERFACE, "EXI DUMMY %s ImmWrite: %08x",m_strName.c_str(),data);}
u32 ImmRead (u32 size) {LOG(EXPANSIONINTERFACE, "EXI DUMMY %s ImmRead",m_strName.c_str()); return 0;}
void DMAWrite(u32 addr, u32 size) {LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMAWrite: %08x bytes, from %08x to device",m_strName.c_str(),size,addr);}
void DMARead (u32 addr, u32 size) {LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMARead: %08x bytes, from device to %08x",m_strName.c_str(),size,addr);}
void ImmWrite(u32 data, u32 size) {LOG(EXPANSIONINTERFACE, "EXI DUMMY %s ImmWrite: %08x", m_strName.c_str(), data);}
u32 ImmRead (u32 size) {LOG(EXPANSIONINTERFACE, "EXI DUMMY %s ImmRead", m_strName.c_str()); return 0;}
void DMAWrite(u32 addr, u32 size) {LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMAWrite: %08x bytes, from %08x to device", m_strName.c_str(), size, addr);}
void DMARead (u32 addr, u32 size) {LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMARead: %08x bytes, from device to %08x", m_strName.c_str(), size, addr);}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////
// F A C T O R Y ////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// F A C T O R Y /////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
IEXIDevice* EXIDevice_Create(TEXIDevices _EXIDevice)
{
@@ -131,11 +130,11 @@ IEXIDevice* EXIDevice_Create(TEXIDevices _EXIDevice)
break;
case EXIDEVICE_MEMORYCARD_A:
return new CEXIMemoryCard("MemoryCardA", SConfig::GetInstance().m_LocalCoreStartupParameter.m_strMemoryCardA, 0);
return new CEXIMemoryCard("MemoryCardA", SConfig::GetInstance().m_strMemoryCardA, 0);
break;
case EXIDEVICE_MEMORYCARD_B:
return new CEXIMemoryCard("MemoryCardB", SConfig::GetInstance().m_LocalCoreStartupParameter.m_strMemoryCardB, 1);
return new CEXIMemoryCard("MemoryCardB", SConfig::GetInstance().m_strMemoryCardB, 1);
break;
case EXIDEVICE_IPL:
@@ -145,7 +144,7 @@ IEXIDevice* EXIDevice_Create(TEXIDevices _EXIDevice)
case EXIDEVICE_AD16:
return new CEXIAD16();
break;
case EXIDEVICE_MIC:
return new CEXIMic(1);
break;
@@ -157,4 +156,3 @@ IEXIDevice* EXIDevice_Create(TEXIDevices _EXIDevice)
}
return NULL;
}
+6 -6
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -23,25 +23,25 @@
class IEXIDevice
{
private:
// byte transfer function for this device
// Byte transfer function for this device
virtual void TransferByte(u8& _byte) {};
public:
// immediate copy functions
// Immediate copy functions
virtual void ImmWrite(u32 _uData, u32 _uSize);
virtual u32 ImmRead(u32 _uSize);
// dma copy functions
// DMA copy functions
virtual void DMAWrite(u32 _uAddr, u32 _uSize);
virtual void DMARead (u32 _uAddr, u32 _uSize);
virtual bool IsPresent();
virtual void SetCS(int _iCS);
// update
// Update
virtual void Update();
// is generating interrupt ?
// Is generating interrupt ?
virtual bool IsInterruptSet();
virtual ~IEXIDevice() {};
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -33,4 +33,5 @@ void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);
}; // end of namespace SerialInterface
#endif
+257
View File
@@ -0,0 +1,257 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "SI_Channel.h"
#include "SI.h"
#include "PeripheralInterface.h"
#include "../PowerPC/PowerPC.h"
#include "SI.cpp"
using namespace SerialInterface;
CSIChannel::CSIChannel()
{
m_Out.Hex = 0;
m_InHi.Hex = 0;
m_InLo.Hex = 0;
m_pDevice = SIDevice_Create(SI_DUMMY, m_ChannelId);
_dbg_assert_(SERIALINTERFACE, m_pDevice != NULL);
}
CSIChannel::~CSIChannel()
{
RemoveDevice();
}
void CSIChannel::AddDevice(const TSIDevices _device, int _iDeviceNumber)
{
//_dbg_assert_(SERIALINTERFACE, _iSlot < NUM_DEVICES);
// delete the old device
RemoveDevice();
// create the new one
m_pDevice = SIDevice_Create(_device, _iDeviceNumber);
_dbg_assert_(SERIALINTERFACE, m_pDevice != NULL);
}
void CSIChannel::RemoveDevice()
{
if (m_pDevice != NULL)
{
delete m_pDevice;
m_pDevice = NULL;
}
}
void CSIChannel::Read32(u32& _uReturnValue, const u32 _iAddr)
{
// registers
switch (_iAddr)
{
//////////////////////////////////////////////////////////////////////////
// Channel 0
//////////////////////////////////////////////////////////////////////////
case SI_CHANNEL_0_OUT:
_uReturnValue = m_Out.Hex;
return;
case SI_CHANNEL_0_IN_HI:
g_StatusReg.RDST0 = 0;
UpdateInterrupts();
_uReturnValue = m_InHi.Hex;
return;
case SI_CHANNEL_0_IN_LO:
g_StatusReg.RDST0 = 0;
UpdateInterrupts();
_uReturnValue = m_InLo.Hex;
return;
//////////////////////////////////////////////////////////////////////////
// Channel 1
//////////////////////////////////////////////////////////////////////////
case SI_CHANNEL_1_OUT:
_uReturnValue = m_Out.Hex;
return;
case SI_CHANNEL_1_IN_HI:
g_StatusReg.RDST1 = 0;
UpdateInterrupts();
_uReturnValue = m_InHi.Hex;
return;
case SI_CHANNEL_1_IN_LO:
g_StatusReg.RDST1 = 0;
UpdateInterrupts();
_uReturnValue = m_InLo.Hex;
return;
//////////////////////////////////////////////////////////////////////////
// Channel 2
//////////////////////////////////////////////////////////////////////////
case SI_CHANNEL_2_OUT:
_uReturnValue = m_Out.Hex;
return;
case SI_CHANNEL_2_IN_HI:
g_StatusReg.RDST2 = 0;
UpdateInterrupts();
_uReturnValue = m_InHi.Hex;
return;
case SI_CHANNEL_2_IN_LO:
g_StatusReg.RDST2 = 0;
UpdateInterrupts();
_uReturnValue = m_InLo.Hex;
return;
//////////////////////////////////////////////////////////////////////////
// Channel 3
//////////////////////////////////////////////////////////////////////////
case SI_CHANNEL_3_OUT:
_uReturnValue = m_Out.Hex;
return;
case SI_CHANNEL_3_IN_HI:
g_StatusReg.RDST3 = 0;
UpdateInterrupts();
_uReturnValue = m_InHi.Hex;
return;
case SI_CHANNEL_3_IN_LO:
g_StatusReg.RDST3 = 0;
UpdateInterrupts();
_uReturnValue = m_InLo.Hex;
return;
case SI_POLL: _uReturnValue = g_Poll.Hex; return;
case SI_COM_CSR: _uReturnValue = g_ComCSR.Hex; return;
case SI_STATUS_REG: _uReturnValue = g_StatusReg.Hex; return;
case SI_EXI_CLOCK_COUNT: _uReturnValue = g_EXIClockCount.Hex; return;
default:
// (shuffle2) FIX!
//LOG(SERIALINTERFACE, "(r32-unk): 0x%08x", _iAddress);
_dbg_assert_(SERIALINTERFACE, 0);
break;
}
// error
_uReturnValue = 0xdeadbeef;
}
void CSIChannel::Write32(const u32 _iValue, const u32 iAddr)
{
// registers
switch (iAddr)
{
case SI_CHANNEL_0_OUT: m_Out.Hex = _iValue; break;
case SI_CHANNEL_0_IN_HI: m_InHi.Hex = _iValue; break;
case SI_CHANNEL_0_IN_LO: m_InLo.Hex = _iValue; break;
case SI_CHANNEL_1_OUT: m_Out.Hex = _iValue; break;
case SI_CHANNEL_1_IN_HI: m_InHi.Hex = _iValue; break;
case SI_CHANNEL_1_IN_LO: m_InLo.Hex = _iValue; break;
case SI_CHANNEL_2_OUT: m_Out.Hex = _iValue; break;
case SI_CHANNEL_2_IN_HI: m_InHi.Hex = _iValue; break;
case SI_CHANNEL_2_IN_LO: m_InLo.Hex = _iValue; break;
case SI_CHANNEL_3_OUT: m_Out.Hex = _iValue; break;
case SI_CHANNEL_3_IN_HI: m_InHi.Hex = _iValue; break;
case SI_CHANNEL_3_IN_LO: m_InLo.Hex = _iValue; break;
case SI_POLL:
g_Poll.Hex = _iValue;
break;
case SI_COM_CSR:
{
USIComCSR tmpComCSR(_iValue);
g_ComCSR.CHANNEL = tmpComCSR.CHANNEL;
g_ComCSR.INLNGTH = tmpComCSR.INLNGTH;
g_ComCSR.OUTLNGTH = tmpComCSR.OUTLNGTH;
g_ComCSR.RDSTINTMSK = tmpComCSR.RDSTINTMSK;
g_ComCSR.TCINTMSK = tmpComCSR.TCINTMSK;
g_ComCSR.COMERR = 0;
if (tmpComCSR.RDSTINT) g_ComCSR.RDSTINT = 0;
if (tmpComCSR.TCINT) g_ComCSR.TCINT = 0;
// be careful: RunSIBuffer after updating the INT flags
if (tmpComCSR.TSTART) RunSIBuffer();
UpdateInterrupts();
}
break;
case SI_STATUS_REG:
{
USIStatusReg tmpStatus(_iValue);
// just update the writable bits
g_StatusReg.NOREP0 = tmpStatus.NOREP0 ? 1 : 0;
g_StatusReg.COLL0 = tmpStatus.COLL0 ? 1 : 0;
g_StatusReg.OVRUN0 = tmpStatus.OVRUN0 ? 1 : 0;
g_StatusReg.UNRUN0 = tmpStatus.UNRUN0 ? 1 : 0;
g_StatusReg.NOREP1 = tmpStatus.NOREP1 ? 1 : 0;
g_StatusReg.COLL1 = tmpStatus.COLL1 ? 1 : 0;
g_StatusReg.OVRUN1 = tmpStatus.OVRUN1 ? 1 : 0;
g_StatusReg.UNRUN1 = tmpStatus.UNRUN1 ? 1 : 0;
g_StatusReg.NOREP2 = tmpStatus.NOREP2 ? 1 : 0;
g_StatusReg.COLL2 = tmpStatus.COLL2 ? 1 : 0;
g_StatusReg.OVRUN2 = tmpStatus.OVRUN2 ? 1 : 0;
g_StatusReg.UNRUN2 = tmpStatus.UNRUN2 ? 1 : 0;
g_StatusReg.NOREP3 = tmpStatus.NOREP3 ? 1 : 0;
g_StatusReg.COLL3 = tmpStatus.COLL3 ? 1 : 0;
g_StatusReg.OVRUN3 = tmpStatus.OVRUN3 ? 1 : 0;
g_StatusReg.UNRUN3 = tmpStatus.UNRUN3 ? 1 : 0;
// send command to devices
if (tmpStatus.WR)
{
g_StatusReg.WR = 0;
m_pDevice->SendCommand(m_Out.Hex);
m_pDevice->SendCommand(m_Out.Hex);
m_pDevice->SendCommand(m_Out.Hex);
m_pDevice->SendCommand(m_Out.Hex);
g_StatusReg.WRST0 = 0;
g_StatusReg.WRST1 = 0;
g_StatusReg.WRST2 = 0;
g_StatusReg.WRST3 = 0;
}
}
break;
case SI_EXI_CLOCK_COUNT:
g_EXIClockCount.Hex = _iValue;
break;
case 0x80:
LOG(SERIALINTERFACE, "WII something at 0xCD006480");
break;
default:
_dbg_assert_(SERIALINTERFACE,0);
break;
}
}
+111
View File
@@ -0,0 +1,111 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _SICHANNEL_H
#define _SICHANNEL_H
#include "Common.h"
#include "SI_Device.h"
class CSIChannel
{
private:
// SI Internal Hardware Addresses
enum
{
SI_CHANNEL_0_OUT = 0x00,
SI_CHANNEL_0_IN_HI = 0x04,
SI_CHANNEL_0_IN_LO = 0x08,
SI_CHANNEL_1_OUT = 0x0C,
SI_CHANNEL_1_IN_HI = 0x10,
SI_CHANNEL_1_IN_LO = 0x14,
SI_CHANNEL_2_OUT = 0x18,
SI_CHANNEL_2_IN_HI = 0x1C,
SI_CHANNEL_2_IN_LO = 0x20,
SI_CHANNEL_3_OUT = 0x24,
SI_CHANNEL_3_IN_HI = 0x28,
SI_CHANNEL_3_IN_LO = 0x2C,
SI_POLL = 0x30,
SI_COM_CSR = 0x34,
SI_STATUS_REG = 0x38,
SI_EXI_CLOCK_COUNT = 0x3C,
};
// SI Channel Output
union USIChannelOut
{
u32 Hex;
struct
{
unsigned OUTPUT1 : 8;
unsigned OUTPUT0 : 8;
unsigned CMD : 8;
unsigned : 8;
};
};
// SI Channel Input High u32
union USIChannelIn_Hi
{
u32 Hex;
struct
{
unsigned INPUT3 : 8;
unsigned INPUT2 : 8;
unsigned INPUT1 : 8;
unsigned INPUT0 : 6;
unsigned ERRLATCH : 1; // 0: no error 1: Error latched. Check SISR.
unsigned ERRSTAT : 1; // 0: no error 1: error on last transfer
};
};
// SI Channel Input Low u32
union USIChannelIn_Lo
{
u32 Hex;
struct
{
unsigned INPUT7 : 8;
unsigned INPUT6 : 8;
unsigned INPUT5 : 8;
unsigned INPUT4 : 8;
};
};
public: // HAX
// SI Channel
USIChannelOut m_Out;
USIChannelIn_Hi m_InHi;
USIChannelIn_Lo m_InLo;
ISIDevice* m_pDevice;
//public:
// ChannelId for debugging
u32 m_ChannelId;
CSIChannel();
~CSIChannel();
void AddDevice(const TSIDevices _device, int _iSlot);
// Remove the device
void RemoveDevice();
void Read32(u32& _uReturnValue, const u32 _iRegister);
void Write32(const u32 _iValue, const u32 _iRegister);
};
#endif
+52 -25
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,11 +16,12 @@
// http://code.google.com/p/dolphin-emu/
#include "SI_Device.h"
#include "SI_DeviceGCController.h"
#include "SI_DeviceGBA.h"
// =====================================================================================================
// --- base class ---
// =====================================================================================================
//////////////////////////////////////////////////////////////////////////
// --- interface ISIDevice ---
//////////////////////////////////////////////////////////////////////////
int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength)
{
#ifdef _DEBUG
@@ -29,7 +30,7 @@ int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength)
char szTemp[256] = "";
int num = 0;
while(num < _iLength)
{
{
char szTemp2[128] = "";
sprintf(szTemp2, "0x%02x ", _pBuffer[num^3]);
strcat(szTemp, szTemp2);
@@ -39,32 +40,58 @@ int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength)
{
LOG(SERIALINTERFACE, szTemp);
szTemp[0] = '\0';
}
}
}
LOG(SERIALINTERFACE, szTemp);
LOG(SERIALINTERFACE, szTemp);
#endif
return 0;
};
// =====================================================================================================
// --- dummy device ---
// =====================================================================================================
CSIDevice_Dummy::CSIDevice_Dummy(int _iDeviceNumber) :
ISIDevice(_iDeviceNumber)
{}
int CSIDevice_Dummy::RunBuffer(u8* _pBuffer, int _iLength)
//////////////////////////////////////////////////////////////////////////
// --- class CSIDummy ---
//////////////////////////////////////////////////////////////////////////
// Just a dummy that logs reads and writes
// to be used for SI devices we haven't emulated
class CSIDevice_Dummy : public ISIDevice
{
reinterpret_cast<u32*>(_pBuffer)[0] = 0x00000000; // no device
return 4;
}
public:
CSIDevice_Dummy(int _iDeviceNumber) :
ISIDevice(_iDeviceNumber)
{}
bool CSIDevice_Dummy::GetData(u32& _Hi, u32& _Low)
{
return false;
}
virtual ~CSIDevice_Dummy(){}
void CSIDevice_Dummy::SendCommand(u32 _Cmd)
int RunBuffer(u8* _pBuffer, int _iLength)
{
// (shuffle2) Logging of this function will be done above, in ISIDevice::RunBuffer
// No device. (shuffle2) Maybe this should be SI_ERROR_NO_RESPONSE?
reinterpret_cast<u32*>(_pBuffer)[0] = 0x00000000;
return 4;
}
bool GetData(u32& _Hi, u32& _Low) {LOG(SERIALINTERFACE, "SI DUMMY %i GetData", this->m_iDeviceNumber); return false;}
void SendCommand(u32 _Cmd) {LOG(SERIALINTERFACE, "SI DUMMY %i SendCommand: %08x", this->m_iDeviceNumber, _Cmd);}
};
//////////////////////////////////////////////////////////////////////////
// F A C T O R Y /////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
ISIDevice* SIDevice_Create(TSIDevices _SIDevice, int _iDeviceNumber)
{
switch(_SIDevice)
{
case SI_DUMMY:
return new CSIDevice_Dummy(_iDeviceNumber);
break;
case SI_GC_CONTROLLER:
return new CSIDevice_GCController(_iDeviceNumber);
break;
case SI_GBA:
return new CSIDevice_GBA(_iDeviceNumber);
break;
}
return NULL;
}
+30 -62
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -20,89 +20,57 @@
#include "Common.h"
#define SI_ERROR_NO_RESPONSE 0x0008 // nothing is attached
#define SI_ERROR_UNKNOWN 0x0040 // unknown device is attached
#define SI_ERROR_BUSY 0x0080 // still detecting
// Devices can reply with these, but idk if we'll ever use them...
#define SI_ERROR_NO_RESPONSE 0x0008 // Nothing is attached
#define SI_ERROR_UNKNOWN 0x0040 // Unknown device is attached
#define SI_ERROR_BUSY 0x0080 // Still detecting
// Device types
#define SI_TYPE_MASK 0x18000000u
#define SI_TYPE_N64 0x00000000u
#define SI_TYPE_MASK 0x18000000u // ???
#define SI_TYPE_GC 0x08000000u
// GameCube
#define SI_GC_WIRELESS 0x80000000u
#define SI_GC_NOMOTOR 0x20000000u // no rumble motor
// GC Controller types
#define SI_GC_NOMOTOR 0x20000000u // No rumble motor
#define SI_GC_STANDARD 0x01000000u
// WaveBird
#define SI_WIRELESS_RECEIVED 0x40000000u // 0: no wireless unit
#define SI_WIRELESS_IR 0x04000000u // 0: IR 1: RF
#define SI_WIRELESS_STATE 0x02000000u // 0: variable 1: fixed
#define SI_WIRELESS_ORIGIN 0x00200000u // 0: invalid 1: valid
#define SI_WIRELESS_FIX_ID 0x00100000u // 0: not fixed 1: fixed
#define SI_WIRELESS_TYPE 0x000f0000u
#define SI_WIRELESS_LITE_MASK 0x000c0000u // 0: normal 1: lite controller
#define SI_WIRELESS_LITE 0x00040000u // 0: normal 1: lite controller
#define SI_WIRELESS_CONT_MASK 0x00080000u // 0: non-controller 1: non-controller
#define SI_WIRELESS_CONT 0x00000000u
#define SI_WIRELESS_ID 0x00c0ff00u
#define SI_WIRELESS_TYPE_ID (SI_WIRELESS_TYPE | SI_WIRELESS_ID)
// "Complete" IDs
#define SI_N64_CONTROLLER (SI_TYPE_N64 | 0x05000000)
#define SI_N64_MIC (SI_TYPE_N64 | 0x00010000)
#define SI_N64_KEYBOARD (SI_TYPE_N64 | 0x00020000)
#define SI_N64_MOUSE (SI_TYPE_N64 | 0x02000000)
#define SI_GBA (SI_TYPE_N64 | 0x00040000)
#define SI_GC_CONTROLLER (SI_TYPE_GC | SI_GC_STANDARD)
#define SI_GC_RECEIVER (SI_TYPE_GC | SI_GC_WIRELESS)
#define SI_GC_WAVEBIRD (SI_TYPE_GC | SI_GC_WIRELESS | SI_GC_STANDARD | SI_WIRELESS_STATE | SI_WIRELESS_FIX_ID)
#define SI_GC_KEYBOARD (SI_TYPE_GC | 0x00200000)
#define SI_GC_STEERING (SI_TYPE_GC | 0x00000000)
class ISIDevice
{
protected:
int m_iDeviceNumber;
public:
// Constructor
ISIDevice(int _iDeviceNumber) :
m_iDeviceNumber(_iDeviceNumber)
{}
// constructor
ISIDevice(int _iDeviceNumber) :
m_iDeviceNumber(_iDeviceNumber)
{ }
virtual ~ISIDevice() { }
// Destructor
virtual ~ISIDevice() {}
// run the SI Buffer
// Run the SI Buffer
virtual int RunBuffer(u8* _pBuffer, int _iLength);
// return true on new data
// Return true on new data
virtual bool GetData(u32& _Hi, u32& _Low) = 0;
// send a command directly (no detour per buffer)
// Send a command directly (no detour per buffer)
virtual void SendCommand(u32 _Cmd) = 0;
};
// =====================================================================================================
// dummy - no device attached
// =====================================================================================================
class CSIDevice_Dummy : public ISIDevice
// SI Device IDs
enum TSIDevices
{
public:
// constructor
CSIDevice_Dummy(int _iDeviceNumber);
// run the SI Buffer
virtual int RunBuffer(u8* _pBuffer, int _iLength);
// return true on new data
virtual bool GetData(u32& _Hi, u32& _Low);
// send a command directly
virtual void SendCommand(u32 _Cmd);
SI_DUMMY = 0,
SI_N64_MIC = 0x00010000,
SI_N64_KEYBOARD = 0x00020000,
SI_N64_MOUSE = 0x02000000,
SI_N64_CONTROLLER = 0x05000000,
SI_GBA = 0x00040000,
SI_GC_CONTROLLER = (SI_TYPE_GC | SI_GC_STANDARD),
SI_GC_KEYBOARD = (SI_TYPE_GC | 0x00200000),
SI_GC_STEERING = SI_TYPE_GC, // (shuffle2)I think the "chainsaw" is the same (Or else it's just standard)
};
extern ISIDevice* SIDevice_Create(TSIDevices _SIDevice, int _iDeviceNumber);
#endif
+132
View File
@@ -0,0 +1,132 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "SI_Device.h"
#include "SI_DeviceGBA.h"
//////////////////////////////////////////////////////////////////////////
// --- GameBoy Advance ---
//////////////////////////////////////////////////////////////////////////
CSIDevice_GBA::CSIDevice_GBA(int _iDeviceNumber) :
ISIDevice(_iDeviceNumber)
{
}
int CSIDevice_GBA::RunBuffer(u8* _pBuffer, int _iLength)
{
// for debug logging only
ISIDevice::RunBuffer(_pBuffer, _iLength);
int iPosition = 0;
while(iPosition < _iLength)
{
// read the command
EBufferCommands command = static_cast<EBufferCommands>(_pBuffer[iPosition ^ 3]);
iPosition++;
// handle it
switch(command)
{
// NOTE: All "Send/Recieve" mentioned here is from dolphin's perspective,
// NOT the GBA's
// This means "Send"s are seen as CMDs to the GBA, and are therefor IMPORTANT :p
// Also this means that we can randomly fill recieve bits and try for a fake gba...
// for example, the ORd bits in RESET and STATUS are just some values to play with
case CMD_RESET:
{
//Device Reset
//Send 0xFF
//Recieve 0x00
//Recieve 0x04
//Recieve from lower 8bits of SIOSTAT register
*(u32*)&_pBuffer[0] = SI_GBA|2;
iPosition = _iLength; // break the while loop
LOG(SERIALINTERFACE, "GBA CMD_RESET");
}
break;
case CMD_STATUS:
{
//Type/Status Data Request
//Send 0x00
//Recieve 0x00
//Recieve 0x04
//Recieve from lower 8bits of SIOSTAT register
*(u32*)&_pBuffer[0] = SI_GBA|8;
iPosition = _iLength; // break the while loop
LOG(SERIALINTERFACE, "GBA CMD_STATUS");
}
break;
case CMD_WRITE:
{
//GBA Data Write (to GBA)
//Send 0x15
//Send to Lower 8bits of JOY_RECV_L
//Send to Upper 8bits of JOY_RECV_L
//Send to Lower 8bits of JOY_RECV_H
//Send to Upper 8bits of JOY_RECV_H
//Receive from lower 8bits of SIOSTAT register
LOG(SERIALINTERFACE, "GBA CMD_WRITE");
}
break;
case CMD_READ:
{
//GBA Data Read (from GBA)
//Send 0x14
//Receive from Lower 8bits of JOY_TRANS_L
//Receive from Upper 8bits of JOY_TRANS_L
//Receive from Lower 8bits of JOY_TRANS_H
//Receive from Upper 8bits of JOY_TRANS_H
//Receive from lower 8bits of SIOSTAT register
LOG(SERIALINTERFACE, "GBA CMD_READ");
}
break;
default:
{
LOG(SERIALINTERFACE, "unknown GBA command (0x%x)", command);
iPosition = _iLength;
}
break;
}
}
return iPosition;
}
//////////////////////////////////////////////////////////////////////////
// GetData
//////////////////////////////////////////////////////////////////////////
bool
CSIDevice_GBA::GetData(u32& _Hi, u32& _Low)
{
LOG(SERIALINTERFACE, "GBA GetData Hi: 0x%x Low: 0x%x", _Hi, _Low);
return true;
}
//////////////////////////////////////////////////////////////////////////
// SendCommand
//////////////////////////////////////////////////////////////////////////
void
CSIDevice_GBA::SendCommand(u32 _Cmd)
{
LOG(SERIALINTERFACE, "GBA SendCommand: (0x%x)", _Cmd);
}
@@ -1,62 +1,78 @@
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
// =====================================================================================================
// GameBoy Advance
// =====================================================================================================
class CSIDevice_GBA : public ISIDevice
{
private:
// commands
enum EBufferCommands
{
CMD_RESET = 0xFF,
CMD_STATUS = 0x00,
CMD_WRITE = 0x15,
CMD_READ = 0x14
};
//0x4000158 - JOYSTAT - Receive Status Register (R/W) (ON THE GBA)
//Bit Explanation
//0 Not used
//1 Receive Status Flag (0=Remote GBA is/was receiving) (Read Only?)
//2 Not used
//3 Send Status Flag (1=Remote GBA is/was sending) (Read Only?)
//4-5 General Purpose Flag (Not assigned, may be used for whatever purpose)
//6-15 Not used
//--------------------------------------
//Bit 1 is automatically set when writing to local JOY_TRANS.
//Bit 3 is automatically reset when reading from local JOY_RECV.
int DeviceNum;
public:
// constructor
CSIDevice_GBA(int _iDeviceNumber);
// run the SI Buffer
virtual int RunBuffer(u8* _pBuffer, int _iLength);
// return true on new data
virtual bool GetData(u32& _Hi, u32& _Low);
// send a command directly
virtual void SendCommand(u32 _Cmd);
};
// Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _SI_DEVICEGBA_H
#define _SI_DEVICEGBA_H
//////////////////////////////////////////////////////////////////////////
// GameBoy Advance
//////////////////////////////////////////////////////////////////////////
class CSIDevice_GBA : public ISIDevice
{
private:
// Commands
enum EBufferCommands
{
CMD_RESET = 0xFF,
CMD_STATUS = 0x00,
CMD_WRITE = 0x15,
CMD_READ = 0x14
};
struct FAKE_JOYSTAT
{
unsigned unused : 1;
unsigned stat_rec : 1;
unsigned unused2 : 1;
unsigned stat_send : 1;
unsigned genpurpose : 2;
unsigned unused3 :10;
};
//////////////////////////////////////////////////////////////////////////
//0x4000158 - JOYSTAT - Receive Status Register (R/W) (ON THE GBA)
//////////////////////////////////////////////////////////////////////////
// NOTE: I am guessing that JOYSTAT == SIOSTAT, may be wrong
//Bit Expl.
//0 Not used
//1 Receive Status Flag (0=Remote GBA is/was receiving) (Read Only?)
//2 Not used
//3 Send Status Flag (1=Remote GBA is/was sending) (Read Only?)
//4-5 General Purpose Flag (Not assigned, may be used for whatever purpose)
//6-15 Not used
//--------------------------------------
//0b0000000000 00 0 0 0 0
//______________________________________
//Bit 1 is automatically set when writing to local JOY_TRANS.
//Bit 3 is automatically reset when reading from local JOY_RECV.
public:
// Constructor
CSIDevice_GBA(int _iDeviceNumber);
// Run the SI Buffer
virtual int RunBuffer(u8* _pBuffer, int _iLength);
// Return true on new data
virtual bool GetData(u32& _Hi, u32& _Low);
// Send a command directly
virtual void SendCommand(u32 _Cmd);
};
#endif

Some files were not shown because too many files have changed in this diff Show More