From b2e96e1ca5b2a2e3b56e8d2a9eae665040ec05fb Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Sun, 4 Jan 2009 22:55:55 +0000 Subject: [PATCH] separate SI to be more like EXI, this will be helpful to keep each device in it's own file(s), and fix some menu text. SI devices which are interesting (to me) are GC keyboard, GBA, and N64 devices. Possibly SI.cpp can have the channel part separated out like EXI? Just committing like this to see if this is ok. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1776 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Core.vcproj | 24 +- Source/Core/Core/Src/HW/HW.cpp | 2 +- Source/Core/Core/Src/HW/Memmap.cpp | 2 +- .../Src/HW/{SerialInterface.cpp => SI.cpp} | 1110 ++++++++--------- .../Core/Src/HW/{SerialInterface.h => SI.h} | 75 +- Source/Core/Core/Src/HW/SI_Device.cpp | 70 ++ Source/Core/Core/Src/HW/SI_Device.h | 108 ++ ..._Devices.cpp => SI_DeviceGCController.cpp} | 409 +++--- ...face_Devices.h => SI_DeviceGCController.h} | 229 ++-- Source/Core/Core/Src/HW/SystemTimers.cpp | 2 +- Source/Core/Core/Src/SConscript | 5 +- Source/Core/DolphinWX/Src/FrameTools.cpp | 7 +- 12 files changed, 1059 insertions(+), 984 deletions(-) rename Source/Core/Core/Src/HW/{SerialInterface.cpp => SI.cpp} (96%) rename Source/Core/Core/Src/HW/{SerialInterface.h => SI.h} (96%) create mode 100644 Source/Core/Core/Src/HW/SI_Device.cpp create mode 100644 Source/Core/Core/Src/HW/SI_Device.h rename Source/Core/Core/Src/HW/{SerialInterface_Devices.cpp => SI_DeviceGCController.cpp} (70%) rename Source/Core/Core/Src/HW/{SerialInterface_Devices.h => SI_DeviceGCController.h} (64%) diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj index d1075b7a21..552b8d27cc 100644 --- a/Source/Core/Core/Core.vcproj +++ b/Source/Core/Core/Core.vcproj @@ -607,19 +607,35 @@ Name="SI - Serial Interface" > + + + + + + + + diff --git a/Source/Core/Core/Src/HW/HW.cpp b/Source/Core/Core/Src/HW/HW.cpp index 1321e6786f..a59452476b 100644 --- a/Source/Core/Core/Src/HW/HW.cpp +++ b/Source/Core/Core/Src/HW/HW.cpp @@ -29,7 +29,7 @@ #include "Memmap.h" #include "PeripheralInterface.h" #include "PixelEngine.h" -#include "SerialInterface.h" +#include "SI.h" #include "AudioInterface.h" #include "VideoInterface.h" #include "WII_IPC.h" diff --git a/Source/Core/Core/Src/HW/Memmap.cpp b/Source/Core/Core/Src/HW/Memmap.cpp index a59fa816e1..5e630e6152 100644 --- a/Source/Core/Core/Src/HW/Memmap.cpp +++ b/Source/Core/Core/Src/HW/Memmap.cpp @@ -31,7 +31,7 @@ #include "DVDInterface.h" #include "GPFifo.h" #include "VideoInterface.h" -#include "SerialInterface.h" +#include "SI.h" #include "EXI.h" #include "PixelEngine.h" #include "CommandProcessor.h" diff --git a/Source/Core/Core/Src/HW/SerialInterface.cpp b/Source/Core/Core/Src/HW/SI.cpp similarity index 96% rename from Source/Core/Core/Src/HW/SerialInterface.cpp rename to Source/Core/Core/Src/HW/SI.cpp index 5757f4e0a7..fb1fe3741b 100644 --- a/Source/Core/Core/Src/HW/SerialInterface.cpp +++ b/Source/Core/Core/Src/HW/SI.cpp @@ -1,557 +1,553 @@ -// Copyright (C) 2003-2008 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 - -#include "Common.h" -#include "ChunkFile.h" - -#include "SerialInterface.h" -#include "SerialInterface_Devices.h" - -#include "PeripheralInterface.h" -#include "CPU.h" - -#include "../PowerPC/PowerPC.h" -#include "../Plugins/Plugin_PAD.h" - -namespace SerialInterface -{ - -// SI Interrupt Types -enum SIInterruptType -{ - INT_RDSTINT = 0, - INT_TCINT = 1, -}; - -// SI number of channels -enum -{ - NUMBER_OF_CHANNELS = 0x04 -}; - -// 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; - }; -}; - -// SI Channel -struct SSIChannel -{ - USIChannelOut m_Out; - USIChannelIn_Hi m_InHi; - USIChannelIn_Lo m_InLo; - ISIDevice* m_pDevice; -}; - -// SI Poll: Controls how often a device is polled -union USIPoll -{ - u32 Hex; - struct - { - unsigned VBCPY3 : 1; - unsigned VBCPY2 : 1; - unsigned VBCPY1 : 1; - unsigned VBCPY0 : 1; - unsigned EN3 : 1; - unsigned EN2 : 1; - unsigned EN1 : 1; - unsigned EN0 : 1; - unsigned Y : 10; - unsigned X : 10; - unsigned : 6; - }; -}; - -// SI Communication Control Status Register -union USIComCSR -{ - u32 Hex; - struct - { - unsigned TSTART : 1; - unsigned CHANNEL : 2; // determines which SI channel will be used the communication interface. - unsigned : 5; - unsigned INLNGTH : 7; - unsigned : 1; - unsigned OUTLNGTH : 7; // Communication Channel Output Length in bytes - unsigned : 4; - unsigned RDSTINTMSK : 1; // Read Status Interrupt Status Mask - unsigned RDSTINT : 1; // Read Status Interrupt Status - unsigned COMERR : 1; // Communication Error (set 0) - unsigned TCINTMSK : 1; // Transfer Complete Interrupt Mask - unsigned TCINT : 1; // Transfer Complete Interrupt - }; - USIComCSR() {Hex = 0;} - USIComCSR(u32 _hex) {Hex = _hex;} -}; - -// SI Status Register -union USIStatusReg -{ - u32 Hex; - struct - { - unsigned UNRUN3 : 1; // (RWC) write 1: bit cleared read 1 main proc underrun error - unsigned OVRUN3 : 1; // (RWC) write 1: bit cleared read 1 overrun error - unsigned COLL3 : 1; // (RWC) write 1: bit cleared read 1 collision error - unsigned NOREP3 : 1; // (RWC) write 1: bit cleared read 1 response error - unsigned WRST3 : 1; // (R) 1: buffer channel0 not copied - unsigned RDST3 : 1; // (R) 1: new Data available - unsigned : 2; // 7:6 - unsigned UNRUN2 : 1; // (RWC) write 1: bit cleared read 1 main proc underrun error - unsigned OVRUN2 : 1; // (RWC) write 1: bit cleared read 1 overrun error - unsigned COLL2 : 1; // (RWC) write 1: bit cleared read 1 collision error - unsigned NOREP2 : 1; // (RWC) write 1: bit cleared read 1 response error - unsigned WRST2 : 1; // (R) 1: buffer channel0 not copied - unsigned RDST2 : 1; // (R) 1: new Data available - unsigned : 2; // 15:14 - unsigned UNRUN1 : 1; // (RWC) write 1: bit cleared read 1 main proc underrun error - unsigned OVRUN1 : 1; // (RWC) write 1: bit cleared read 1 overrun error - unsigned COLL1 : 1; // (RWC) write 1: bit cleared read 1 collision error - unsigned NOREP1 : 1; // (RWC) write 1: bit cleared read 1 response error - unsigned WRST1 : 1; // (R) 1: buffer channel0 not copied - unsigned RDST1 : 1; // (R) 1: new Data available - unsigned : 2; // 23:22 - unsigned UNRUN0 : 1; // (RWC) write 1: bit cleared read 1 main proc underrun error - unsigned OVRUN0 : 1; // (RWC) write 1: bit cleared read 1 overrun error - unsigned COLL0 : 1; // (RWC) write 1: bit cleared read 1 collision error - unsigned NOREP0 : 1; // (RWC) write 1: bit cleared read 1 response error - unsigned WRST0 : 1; // (R) 1: buffer channel0 not copied - unsigned RDST0 : 1; // (R) 1: new Data available - unsigned : 1; - unsigned WR : 1; // (RW) write 1 start copy, read 0 copy done - }; - USIStatusReg() {Hex = 0;} - USIStatusReg(u32 _hex) {Hex = _hex;} -}; - -// SI EXI Clock Count -union USIEXIClockCount -{ - u32 Hex; - struct - { - unsigned LOCK : 1; - unsigned : 30; - }; -}; - -// STATE_TO_SAVE -static SSIChannel g_Channel[NUMBER_OF_CHANNELS]; -static USIPoll g_Poll; -static USIComCSR g_ComCSR; -static USIStatusReg g_StatusReg; -static USIEXIClockCount g_EXIClockCount; -static u8 g_SIBuffer[128]; - -void DoState(PointerWrap &p) -{ - // p.DoArray(g_Channel); - p.Do(g_Poll); - p.Do(g_ComCSR); - p.Do(g_StatusReg); - p.Do(g_EXIClockCount); - p.Do(g_SIBuffer); -} - -static void GenerateSIInterrupt(SIInterruptType _SIInterrupt); -void RunSIBuffer(); -void UpdateInterrupts(); - -void Init() -{ - for (int i = 0; i < NUMBER_OF_CHANNELS; i++) - { - g_Channel[i].m_Out.Hex = 0; - g_Channel[i].m_InHi.Hex = 0; - g_Channel[i].m_InLo.Hex = 0; - } - - unsigned int AttachedPadMask = PluginPAD::PAD_GetAttachedPads ? PluginPAD::PAD_GetAttachedPads() : 1; - for (int i = 0; i < 4; i++) - { - if (AttachedPadMask & (1 << i)) - g_Channel[i].m_pDevice = new CSIDevice_GCController(i); - else - g_Channel[i].m_pDevice = new CSIDevice_Dummy(i); - } - - g_Poll.Hex = 0; - g_ComCSR.Hex = 0; - g_StatusReg.Hex = 0; - g_EXIClockCount.Hex = 0; - memset(g_SIBuffer, 0xce, 128); -} - -void Shutdown() -{ - for (int i = 0; i < NUMBER_OF_CHANNELS; i++) - { - delete g_Channel[i].m_pDevice; - g_Channel[i].m_pDevice = NULL; - } -} - -void Read32(u32& _uReturnValue, const u32 _iAddress) -{ - LOGV(SERIALINTERFACE, 3, "(r32): 0x%08x", _iAddress); - - // SIBuffer - if ((_iAddress >= 0xCC006480 && _iAddress < 0xCC006500) || - (_iAddress >= 0xCD006480 && _iAddress < 0xCD006500)) - { - _uReturnValue = *(u32*)&g_SIBuffer[_iAddress & 0x7F]; - return; - } - - // registers - switch (_iAddress & 0x3FF) - { - //=================================================================================================== - // Channel 0 - //=================================================================================================== - case SI_CHANNEL_0_OUT: - _uReturnValue = g_Channel[0].m_Out.Hex; - return; - - case SI_CHANNEL_0_IN_HI: - g_StatusReg.RDST0 = 0; - UpdateInterrupts(); - _uReturnValue = g_Channel[0].m_InHi.Hex; - return; - - case SI_CHANNEL_0_IN_LO: - g_StatusReg.RDST0 = 0; - UpdateInterrupts(); - _uReturnValue = g_Channel[0].m_InLo.Hex; - return; - - //=================================================================================================== - // Channel 1 - //=================================================================================================== - case SI_CHANNEL_1_OUT: - _uReturnValue = g_Channel[1].m_Out.Hex; - return; - - case SI_CHANNEL_1_IN_HI: - g_StatusReg.RDST1 = 0; - UpdateInterrupts(); - _uReturnValue = g_Channel[1].m_InHi.Hex; - return; - - case SI_CHANNEL_1_IN_LO: - g_StatusReg.RDST1 = 0; - UpdateInterrupts(); - _uReturnValue = g_Channel[1].m_InLo.Hex; - return; - - //=================================================================================================== - // Channel 2 - //=================================================================================================== - case SI_CHANNEL_2_OUT: - _uReturnValue = g_Channel[2].m_Out.Hex; - return; - - case SI_CHANNEL_2_IN_HI: - g_StatusReg.RDST2 = 0; - UpdateInterrupts(); - _uReturnValue = g_Channel[2].m_InHi.Hex; - return; - - case SI_CHANNEL_2_IN_LO: - g_StatusReg.RDST2 = 0; - UpdateInterrupts(); - _uReturnValue = g_Channel[2].m_InLo.Hex; - return; - - //=================================================================================================== - // Channel 3 - //=================================================================================================== - case SI_CHANNEL_3_OUT: - _uReturnValue = g_Channel[3].m_Out.Hex; - return; - - case SI_CHANNEL_3_IN_HI: - g_StatusReg.RDST3 = 0; - UpdateInterrupts(); - _uReturnValue = g_Channel[3].m_InHi.Hex; - return; - - case SI_CHANNEL_3_IN_LO: - g_StatusReg.RDST3 = 0; - UpdateInterrupts(); - _uReturnValue = g_Channel[3].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: - LOG(SERIALINTERFACE, "(r32-unk): 0x%08x", _iAddress); - _dbg_assert_(SERIALINTERFACE,0); - break; - } - - // error - _uReturnValue = 0xdeadbeef; -} - -void Write32(const u32 _iValue, const u32 _iAddress) -{ - LOGV(SERIALINTERFACE, 3, "(w32): 0x%08x 0x%08x", _iValue,_iAddress); - - // SIBuffer - if ((_iAddress >= 0xCC006480 && _iAddress < 0xCC006500) || - (_iAddress >= 0xCD006480 && _iAddress < 0xCD006500)) - { - *(u32*)&g_SIBuffer[_iAddress & 0x7F] = _iValue; - return; - } - - // registers - switch (_iAddress & 0x3FF) - { - case SI_CHANNEL_0_OUT: g_Channel[0].m_Out.Hex = _iValue; break; - case SI_CHANNEL_0_IN_HI: g_Channel[0].m_InHi.Hex = _iValue; break; - case SI_CHANNEL_0_IN_LO: g_Channel[0].m_InLo.Hex = _iValue; break; - case SI_CHANNEL_1_OUT: g_Channel[1].m_Out.Hex = _iValue; break; - case SI_CHANNEL_1_IN_HI: g_Channel[1].m_InHi.Hex = _iValue; break; - case SI_CHANNEL_1_IN_LO: g_Channel[1].m_InLo.Hex = _iValue; break; - case SI_CHANNEL_2_OUT: g_Channel[2].m_Out.Hex = _iValue; break; - case SI_CHANNEL_2_IN_HI: g_Channel[2].m_InHi.Hex = _iValue; break; - case SI_CHANNEL_2_IN_LO: g_Channel[2].m_InLo.Hex = _iValue; break; - case SI_CHANNEL_3_OUT: g_Channel[3].m_Out.Hex = _iValue; break; - case SI_CHANNEL_3_IN_HI: g_Channel[3].m_InHi.Hex = _iValue; break; - case SI_CHANNEL_3_IN_LO: g_Channel[3].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: runsi-buffer 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; - g_Channel[0].m_pDevice->SendCommand(g_Channel[0].m_Out.Hex); - g_Channel[1].m_pDevice->SendCommand(g_Channel[1].m_Out.Hex); - g_Channel[2].m_pDevice->SendCommand(g_Channel[2].m_Out.Hex); - g_Channel[3].m_pDevice->SendCommand(g_Channel[3].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; - } -} - -void UpdateInterrupts() -{ - // check if we have to update the RDSTINT flag - if (g_StatusReg.RDST0 || g_StatusReg.RDST1 || - g_StatusReg.RDST2 || g_StatusReg.RDST3) - g_ComCSR.RDSTINT = 1; - else - g_ComCSR.RDSTINT = 0; - - // check if we have to generate an interrupt - if ((g_ComCSR.RDSTINT & g_ComCSR.RDSTINTMSK) || - (g_ComCSR.TCINT & g_ComCSR.TCINTMSK)) - { - CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_SI, true); - } - else - { - CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_SI, false); - } -} - -void GenerateSIInterrupt(SIInterruptType _SIInterrupt) -{ - switch(_SIInterrupt) - { - case INT_RDSTINT: g_ComCSR.RDSTINT = 1; break; - case INT_TCINT: g_ComCSR.TCINT = 1; break; - } - - UpdateInterrupts(); -} - -void UpdateDevices() -{ - // update channels - g_StatusReg.RDST0 = g_Channel[0].m_pDevice->GetData(g_Channel[0].m_InHi.Hex, g_Channel[0].m_InLo.Hex) ? 1 : 0; - g_StatusReg.RDST1 = g_Channel[1].m_pDevice->GetData(g_Channel[1].m_InHi.Hex, g_Channel[1].m_InLo.Hex) ? 1 : 0; - g_StatusReg.RDST2 = g_Channel[2].m_pDevice->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex) ? 1 : 0; - g_StatusReg.RDST3 = g_Channel[3].m_pDevice->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex) ? 1 : 0; - - // update interrupts - UpdateInterrupts(); -} - -void RunSIBuffer() -{ - // math inLength - int inLength = g_ComCSR.INLNGTH; - if (inLength == 0) - inLength = 128; - else - inLength++; - - // math outLength - int outLength = g_ComCSR.OUTLNGTH; - if (outLength == 0) - outLength = 128; - else - outLength++; - -#ifdef LOGGING - int numOutput = -#endif - g_Channel[g_ComCSR.CHANNEL].m_pDevice->RunBuffer(g_SIBuffer, inLength); - LOGV(SERIALINTERFACE, 2, "RunSIBuffer (intLen: %i outLen: %i) (processed: %i)", inLength, outLength, numOutput); - - // Transfer completed - GenerateSIInterrupt(INT_TCINT); - g_ComCSR.TSTART = 0; -} - -} // end of namespace SerialInterface - +// Copyright (C) 2003-2008 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 "Common.h" +#include "ChunkFile.h" + +#include "PeripheralInterface.h" + +#include "../Plugins/Plugin_PAD.h" + +#include "SI.h" +#include "SI_Device.h" +#include "SI_DeviceGCController.h" + +namespace SerialInterface +{ + +// SI Interrupt Types +enum SIInterruptType +{ + INT_RDSTINT = 0, + INT_TCINT = 1, +}; + +// SI number of channels +enum +{ + NUMBER_OF_CHANNELS = 0x04 +}; + +// 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; + }; +}; + +// SI Channel +struct SSIChannel +{ + USIChannelOut m_Out; + USIChannelIn_Hi m_InHi; + USIChannelIn_Lo m_InLo; + ISIDevice* m_pDevice; +}; + +// SI Poll: Controls how often a device is polled +union USIPoll +{ + u32 Hex; + struct + { + unsigned VBCPY3 : 1; + unsigned VBCPY2 : 1; + unsigned VBCPY1 : 1; + unsigned VBCPY0 : 1; + unsigned EN3 : 1; + unsigned EN2 : 1; + unsigned EN1 : 1; + unsigned EN0 : 1; + unsigned Y : 10; + unsigned X : 10; + unsigned : 6; + }; +}; + +// SI Communication Control Status Register +union USIComCSR +{ + u32 Hex; + struct + { + unsigned TSTART : 1; + unsigned CHANNEL : 2; // determines which SI channel will be used the communication interface. + unsigned : 5; + unsigned INLNGTH : 7; + unsigned : 1; + unsigned OUTLNGTH : 7; // Communication Channel Output Length in bytes + unsigned : 4; + unsigned RDSTINTMSK : 1; // Read Status Interrupt Status Mask + unsigned RDSTINT : 1; // Read Status Interrupt Status + unsigned COMERR : 1; // Communication Error (set 0) + unsigned TCINTMSK : 1; // Transfer Complete Interrupt Mask + unsigned TCINT : 1; // Transfer Complete Interrupt + }; + USIComCSR() {Hex = 0;} + USIComCSR(u32 _hex) {Hex = _hex;} +}; + +// SI Status Register +union USIStatusReg +{ + u32 Hex; + struct + { + unsigned UNRUN3 : 1; // (RWC) write 1: bit cleared read 1 main proc underrun error + unsigned OVRUN3 : 1; // (RWC) write 1: bit cleared read 1 overrun error + unsigned COLL3 : 1; // (RWC) write 1: bit cleared read 1 collision error + unsigned NOREP3 : 1; // (RWC) write 1: bit cleared read 1 response error + unsigned WRST3 : 1; // (R) 1: buffer channel0 not copied + unsigned RDST3 : 1; // (R) 1: new Data available + unsigned : 2; // 7:6 + unsigned UNRUN2 : 1; // (RWC) write 1: bit cleared read 1 main proc underrun error + unsigned OVRUN2 : 1; // (RWC) write 1: bit cleared read 1 overrun error + unsigned COLL2 : 1; // (RWC) write 1: bit cleared read 1 collision error + unsigned NOREP2 : 1; // (RWC) write 1: bit cleared read 1 response error + unsigned WRST2 : 1; // (R) 1: buffer channel0 not copied + unsigned RDST2 : 1; // (R) 1: new Data available + unsigned : 2; // 15:14 + unsigned UNRUN1 : 1; // (RWC) write 1: bit cleared read 1 main proc underrun error + unsigned OVRUN1 : 1; // (RWC) write 1: bit cleared read 1 overrun error + unsigned COLL1 : 1; // (RWC) write 1: bit cleared read 1 collision error + unsigned NOREP1 : 1; // (RWC) write 1: bit cleared read 1 response error + unsigned WRST1 : 1; // (R) 1: buffer channel0 not copied + unsigned RDST1 : 1; // (R) 1: new Data available + unsigned : 2; // 23:22 + unsigned UNRUN0 : 1; // (RWC) write 1: bit cleared read 1 main proc underrun error + unsigned OVRUN0 : 1; // (RWC) write 1: bit cleared read 1 overrun error + unsigned COLL0 : 1; // (RWC) write 1: bit cleared read 1 collision error + unsigned NOREP0 : 1; // (RWC) write 1: bit cleared read 1 response error + unsigned WRST0 : 1; // (R) 1: buffer channel0 not copied + unsigned RDST0 : 1; // (R) 1: new Data available + unsigned : 1; + unsigned WR : 1; // (RW) write 1 start copy, read 0 copy done + }; + USIStatusReg() {Hex = 0;} + USIStatusReg(u32 _hex) {Hex = _hex;} +}; + +// SI EXI Clock Count +union USIEXIClockCount +{ + u32 Hex; + struct + { + unsigned LOCK : 1; + unsigned : 30; + }; +}; + +// STATE_TO_SAVE +static SSIChannel g_Channel[NUMBER_OF_CHANNELS]; +static USIPoll g_Poll; +static USIComCSR g_ComCSR; +static USIStatusReg g_StatusReg; +static USIEXIClockCount g_EXIClockCount; +static u8 g_SIBuffer[128]; + +void DoState(PointerWrap &p) +{ + // p.DoArray(g_Channel); + p.Do(g_Poll); + p.Do(g_ComCSR); + p.Do(g_StatusReg); + p.Do(g_EXIClockCount); + p.Do(g_SIBuffer); +} + +static void GenerateSIInterrupt(SIInterruptType _SIInterrupt); +void RunSIBuffer(); +void UpdateInterrupts(); + +void Init() +{ + for (int i = 0; i < NUMBER_OF_CHANNELS; i++) + { + g_Channel[i].m_Out.Hex = 0; + g_Channel[i].m_InHi.Hex = 0; + g_Channel[i].m_InLo.Hex = 0; + } + + unsigned int AttachedPadMask = PluginPAD::PAD_GetAttachedPads ? PluginPAD::PAD_GetAttachedPads() : 1; + for (int i = 0; i < 4; i++) + { + if (AttachedPadMask & (1 << i)) + g_Channel[i].m_pDevice = new CSIDevice_GCController(i); + else + g_Channel[i].m_pDevice = new CSIDevice_Dummy(i); + } + + g_Poll.Hex = 0; + g_ComCSR.Hex = 0; + g_StatusReg.Hex = 0; + g_EXIClockCount.Hex = 0; + memset(g_SIBuffer, 0xce, 128); +} + +void Shutdown() +{ + for (int i = 0; i < NUMBER_OF_CHANNELS; i++) + { + delete g_Channel[i].m_pDevice; + g_Channel[i].m_pDevice = NULL; + } +} + +void Read32(u32& _uReturnValue, const u32 _iAddress) +{ + LOGV(SERIALINTERFACE, 3, "(r32): 0x%08x", _iAddress); + + // SIBuffer + if ((_iAddress >= 0xCC006480 && _iAddress < 0xCC006500) || + (_iAddress >= 0xCD006480 && _iAddress < 0xCD006500)) + { + _uReturnValue = *(u32*)&g_SIBuffer[_iAddress & 0x7F]; + return; + } + + // registers + switch (_iAddress & 0x3FF) + { + //=================================================================================================== + // Channel 0 + //=================================================================================================== + case SI_CHANNEL_0_OUT: + _uReturnValue = g_Channel[0].m_Out.Hex; + return; + + case SI_CHANNEL_0_IN_HI: + g_StatusReg.RDST0 = 0; + UpdateInterrupts(); + _uReturnValue = g_Channel[0].m_InHi.Hex; + return; + + case SI_CHANNEL_0_IN_LO: + g_StatusReg.RDST0 = 0; + UpdateInterrupts(); + _uReturnValue = g_Channel[0].m_InLo.Hex; + return; + + //=================================================================================================== + // Channel 1 + //=================================================================================================== + case SI_CHANNEL_1_OUT: + _uReturnValue = g_Channel[1].m_Out.Hex; + return; + + case SI_CHANNEL_1_IN_HI: + g_StatusReg.RDST1 = 0; + UpdateInterrupts(); + _uReturnValue = g_Channel[1].m_InHi.Hex; + return; + + case SI_CHANNEL_1_IN_LO: + g_StatusReg.RDST1 = 0; + UpdateInterrupts(); + _uReturnValue = g_Channel[1].m_InLo.Hex; + return; + + //=================================================================================================== + // Channel 2 + //=================================================================================================== + case SI_CHANNEL_2_OUT: + _uReturnValue = g_Channel[2].m_Out.Hex; + return; + + case SI_CHANNEL_2_IN_HI: + g_StatusReg.RDST2 = 0; + UpdateInterrupts(); + _uReturnValue = g_Channel[2].m_InHi.Hex; + return; + + case SI_CHANNEL_2_IN_LO: + g_StatusReg.RDST2 = 0; + UpdateInterrupts(); + _uReturnValue = g_Channel[2].m_InLo.Hex; + return; + + //=================================================================================================== + // Channel 3 + //=================================================================================================== + case SI_CHANNEL_3_OUT: + _uReturnValue = g_Channel[3].m_Out.Hex; + return; + + case SI_CHANNEL_3_IN_HI: + g_StatusReg.RDST3 = 0; + UpdateInterrupts(); + _uReturnValue = g_Channel[3].m_InHi.Hex; + return; + + case SI_CHANNEL_3_IN_LO: + g_StatusReg.RDST3 = 0; + UpdateInterrupts(); + _uReturnValue = g_Channel[3].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: + LOG(SERIALINTERFACE, "(r32-unk): 0x%08x", _iAddress); + _dbg_assert_(SERIALINTERFACE,0); + break; + } + + // error + _uReturnValue = 0xdeadbeef; +} + +void Write32(const u32 _iValue, const u32 _iAddress) +{ + LOGV(SERIALINTERFACE, 3, "(w32): 0x%08x 0x%08x", _iValue,_iAddress); + + // SIBuffer + if ((_iAddress >= 0xCC006480 && _iAddress < 0xCC006500) || + (_iAddress >= 0xCD006480 && _iAddress < 0xCD006500)) + { + *(u32*)&g_SIBuffer[_iAddress & 0x7F] = _iValue; + return; + } + + // registers + switch (_iAddress & 0x3FF) + { + case SI_CHANNEL_0_OUT: g_Channel[0].m_Out.Hex = _iValue; break; + case SI_CHANNEL_0_IN_HI: g_Channel[0].m_InHi.Hex = _iValue; break; + case SI_CHANNEL_0_IN_LO: g_Channel[0].m_InLo.Hex = _iValue; break; + case SI_CHANNEL_1_OUT: g_Channel[1].m_Out.Hex = _iValue; break; + case SI_CHANNEL_1_IN_HI: g_Channel[1].m_InHi.Hex = _iValue; break; + case SI_CHANNEL_1_IN_LO: g_Channel[1].m_InLo.Hex = _iValue; break; + case SI_CHANNEL_2_OUT: g_Channel[2].m_Out.Hex = _iValue; break; + case SI_CHANNEL_2_IN_HI: g_Channel[2].m_InHi.Hex = _iValue; break; + case SI_CHANNEL_2_IN_LO: g_Channel[2].m_InLo.Hex = _iValue; break; + case SI_CHANNEL_3_OUT: g_Channel[3].m_Out.Hex = _iValue; break; + case SI_CHANNEL_3_IN_HI: g_Channel[3].m_InHi.Hex = _iValue; break; + case SI_CHANNEL_3_IN_LO: g_Channel[3].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: runsi-buffer 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; + g_Channel[0].m_pDevice->SendCommand(g_Channel[0].m_Out.Hex); + g_Channel[1].m_pDevice->SendCommand(g_Channel[1].m_Out.Hex); + g_Channel[2].m_pDevice->SendCommand(g_Channel[2].m_Out.Hex); + g_Channel[3].m_pDevice->SendCommand(g_Channel[3].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; + } +} + +void UpdateInterrupts() +{ + // check if we have to update the RDSTINT flag + if (g_StatusReg.RDST0 || g_StatusReg.RDST1 || + g_StatusReg.RDST2 || g_StatusReg.RDST3) + g_ComCSR.RDSTINT = 1; + else + g_ComCSR.RDSTINT = 0; + + // check if we have to generate an interrupt + if ((g_ComCSR.RDSTINT & g_ComCSR.RDSTINTMSK) || + (g_ComCSR.TCINT & g_ComCSR.TCINTMSK)) + { + CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_SI, true); + } + else + { + CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_SI, false); + } +} + +void GenerateSIInterrupt(SIInterruptType _SIInterrupt) +{ + switch(_SIInterrupt) + { + case INT_RDSTINT: g_ComCSR.RDSTINT = 1; break; + case INT_TCINT: g_ComCSR.TCINT = 1; break; + } + + UpdateInterrupts(); +} + +void UpdateDevices() +{ + // update channels + g_StatusReg.RDST0 = g_Channel[0].m_pDevice->GetData(g_Channel[0].m_InHi.Hex, g_Channel[0].m_InLo.Hex) ? 1 : 0; + g_StatusReg.RDST1 = g_Channel[1].m_pDevice->GetData(g_Channel[1].m_InHi.Hex, g_Channel[1].m_InLo.Hex) ? 1 : 0; + g_StatusReg.RDST2 = g_Channel[2].m_pDevice->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex) ? 1 : 0; + g_StatusReg.RDST3 = g_Channel[3].m_pDevice->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex) ? 1 : 0; + + // update interrupts + UpdateInterrupts(); +} + +void RunSIBuffer() +{ + // math inLength + int inLength = g_ComCSR.INLNGTH; + if (inLength == 0) + inLength = 128; + else + inLength++; + + // math outLength + int outLength = g_ComCSR.OUTLNGTH; + if (outLength == 0) + outLength = 128; + else + outLength++; + +#ifdef LOGGING + int numOutput = +#endif + g_Channel[g_ComCSR.CHANNEL].m_pDevice->RunBuffer(g_SIBuffer, inLength); + LOGV(SERIALINTERFACE, 2, "RunSIBuffer (intLen: %i outLen: %i) (processed: %i)", inLength, outLength, numOutput); + + // Transfer completed + GenerateSIInterrupt(INT_TCINT); + g_ComCSR.TSTART = 0; +} + +} // end of namespace SerialInterface diff --git a/Source/Core/Core/Src/HW/SerialInterface.h b/Source/Core/Core/Src/HW/SI.h similarity index 96% rename from Source/Core/Core/Src/HW/SerialInterface.h rename to Source/Core/Core/Src/HW/SI.h index 4bfb59c2ff..36a1967344 100644 --- a/Source/Core/Core/Src/HW/SerialInterface.h +++ b/Source/Core/Core/Src/HW/SI.h @@ -1,39 +1,36 @@ -// Copyright (C) 2003-2008 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 _SERIALINTERFACE_H -#define _SERIALINTERFACE_H - -#include "Common.h" -class PointerWrap; - -namespace SerialInterface -{ - -void Init(); -void Shutdown(); -void DoState(PointerWrap &p); - -void UpdateDevices(); - -void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress); -void HWCALL Write32(const u32 _iValue, const u32 _iAddress); - -}; // end of namespace SerialInterface - -#endif - +// Copyright (C) 2003-2008 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 _SERIALINTERFACE_H +#define _SERIALINTERFACE_H + +#include "Common.h" +class PointerWrap; + +namespace SerialInterface +{ + +void Init(); +void Shutdown(); +void DoState(PointerWrap &p); + +void UpdateDevices(); + +void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress); +void HWCALL Write32(const u32 _iValue, const u32 _iAddress); + +}; // end of namespace SerialInterface +#endif diff --git a/Source/Core/Core/Src/HW/SI_Device.cpp b/Source/Core/Core/Src/HW/SI_Device.cpp new file mode 100644 index 0000000000..2f05c2729c --- /dev/null +++ b/Source/Core/Core/Src/HW/SI_Device.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2003-2008 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" + +// ===================================================================================================== +// --- base class --- +// ===================================================================================================== + +int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength) +{ +#ifdef _DEBUG + LOG(SERIALINTERFACE, "Send Data Device(%i) - Length(%i) ", ISIDevice::m_iDeviceNumber,_iLength); + + char szTemp[256] = ""; + int num = 0; + while(num < _iLength) + { + char szTemp2[128] = ""; + sprintf(szTemp2, "0x%02x ", _pBuffer[num^3]); + strcat(szTemp, szTemp2); + num++; + + if ((num % 8) == 0) + { + LOG(SERIALINTERFACE, szTemp); + szTemp[0] = '\0'; + } + } + LOG(SERIALINTERFACE, szTemp); +#endif + return 0; +}; + +// ===================================================================================================== +// --- dummy device --- +// ===================================================================================================== + +CSIDevice_Dummy::CSIDevice_Dummy(int _iDeviceNumber) : + ISIDevice(_iDeviceNumber) +{} + +int CSIDevice_Dummy::RunBuffer(u8* _pBuffer, int _iLength) +{ + reinterpret_cast(_pBuffer)[0] = 0x00000000; // no device + return 4; +} + +bool CSIDevice_Dummy::GetData(u32& _Hi, u32& _Low) +{ + return false; +} + +void CSIDevice_Dummy::SendCommand(u32 _Cmd) +{ +} diff --git a/Source/Core/Core/Src/HW/SI_Device.h b/Source/Core/Core/Src/HW/SI_Device.h new file mode 100644 index 0000000000..b38e9df2b4 --- /dev/null +++ b/Source/Core/Core/Src/HW/SI_Device.h @@ -0,0 +1,108 @@ +// Copyright (C) 2003-2008 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 _SIDEVICE_H +#define _SIDEVICE_H + +#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 + +// Device types +#define SI_TYPE_MASK 0x18000000u +#define SI_TYPE_N64 0x00000000u +#define SI_TYPE_GC 0x08000000u + +// GameCube +#define SI_GC_WIRELESS 0x80000000u +#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) + { } + virtual ~ISIDevice() { } + + // run the SI Buffer + virtual int RunBuffer(u8* _pBuffer, int _iLength); + + // return true on new data + virtual bool GetData(u32& _Hi, u32& _Low) = 0; + + // send a command directly (no detour per buffer) + virtual void SendCommand(u32 _Cmd) = 0; +}; + +// ===================================================================================================== +// dummy - no device attached +// ===================================================================================================== + +class CSIDevice_Dummy : public ISIDevice +{ +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); +}; + +#endif diff --git a/Source/Core/Core/Src/HW/SerialInterface_Devices.cpp b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp similarity index 70% rename from Source/Core/Core/Src/HW/SerialInterface_Devices.cpp rename to Source/Core/Core/Src/HW/SI_DeviceGCController.cpp index 1719fb83fc..e767fa0c2f 100644 --- a/Source/Core/Core/Src/HW/SerialInterface_Devices.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp @@ -1,238 +1,171 @@ -// Copyright (C) 2003-2008 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 -#include - -#include "SerialInterface_Devices.h" - -#include "EXI_Device.h" -#include "EXI_DeviceMic.h" - -#include "../Plugins/Plugin_PAD.h" - -#include "../PowerPC/PowerPC.h" -#include "CPU.h" - -#define SI_TYPE_GC 0x08000000u - -#define SI_GC_STANDARD 0x01000000u // dolphin standard controller -#define SI_GC_NOMOTOR 0x20000000u // no rumble motor - -#define SI_GC_KEYBOARD (SI_TYPE_GC | 0x00200000) -#define SI_GC_CONTROLLER (SI_TYPE_GC | SI_GC_STANDARD) - -#define SI_MAX_COMCSR_INLNGTH 128 -#define SI_MAX_COMCSR_OUTLNGTH 128 - -// ===================================================================================================== -// --- base class --- -// ===================================================================================================== - -int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength) -{ -#ifdef _DEBUG - LOG(SERIALINTERFACE, "Send Data Device(%i) - Length(%i) ", ISIDevice::m_iDeviceNumber,_iLength); - - char szTemp[256] = ""; - int num = 0; - while(num < _iLength) - { - char szTemp2[128] = ""; - sprintf(szTemp2, "0x%02x ", _pBuffer[num^3]); - strcat(szTemp, szTemp2); - num++; - - if ((num % 8) == 0) - { - LOG(SERIALINTERFACE, szTemp); - szTemp[0] = '\0'; - } - } - LOG(SERIALINTERFACE, szTemp); -#endif - return 0; -}; - -// ===================================================================================================== -// --- standard gamecube controller --- -// ===================================================================================================== - -CSIDevice_GCController::CSIDevice_GCController(int _iDeviceNumber) : - ISIDevice(_iDeviceNumber) -{ - memset(&m_origin, 0, sizeof(SOrigin)); - - m_origin.uCommand = 0x41; - m_origin.uOriginStickX = 0x80; - m_origin.uOriginStickY = 0x80; - m_origin.uSubStickStickX = 0x80; - m_origin.uSubStickStickY = 0x80; - m_origin.uTrigger_L = 0x1F; - m_origin.uTrigger_R = 0x1F; -} - -int CSIDevice_GCController::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(_pBuffer[iPosition ^ 3]); - iPosition++; - - // handle it - switch(command) - { - case CMD_RESET: - { - *(u32*)&_pBuffer[0] = SI_GC_CONTROLLER; // | SI_GC_NOMOTOR; - iPosition = _iLength; // break the while loop - } - break; - - case CMD_ORIGIN: - { - LOG(SERIALINTERFACE, "SI - Get Origin"); - u8* pCalibration = reinterpret_cast(&m_origin); - for (int i = 0; i < (int)sizeof(SOrigin); i++) - { - _pBuffer[i ^ 3] = *pCalibration++; - } - } - iPosition = _iLength; - break; - - // Recalibrate (FiRES: i am not 100 percent sure about this) - case CMD_RECALIBRATE: - { - LOG(SERIALINTERFACE, "SI - Recalibrate"); - u8* pCalibration = reinterpret_cast(&m_origin); - for (int i = 0; i < (int)sizeof(SOrigin); i++) - { - _pBuffer[i ^ 3] = *pCalibration++; - } - } - iPosition = _iLength; - break; - - // WII Something - case 0xCE: - LOG(SERIALINTERFACE, "Unknown Wii SI Command"); - break; - - // DEFAULT - default: - { - LOG(SERIALINTERFACE, "unknown SI command (0x%x)", command); - PanicAlert("SI: Unknown command"); - iPosition = _iLength; - } - break; - } - } - - return iPosition; -} - -// __________________________________________________________________________________________________ -// GetData -// -// return true on new data (max 7 Bytes and 6 bits ;) -// -bool -CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) -{ - SPADStatus PadStatus; - memset(&PadStatus, 0 ,sizeof(PadStatus)); - PluginPAD::PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); - - _Hi = (u32)((u8)PadStatus.stickY); - _Hi |= (u32)((u8)PadStatus.stickX << 8); - _Hi |= (u32)((u16)PadStatus.button << 16); - - _Low = (u8)PadStatus.triggerRight; - _Low |= (u32)((u8)PadStatus.triggerLeft << 8); - _Low |= (u32)((u8)PadStatus.substickY << 16); - _Low |= (u32)((u8)PadStatus.substickX << 24); - SetMic(PadStatus.MicButton); - - // F|RES: - // i dunno if i should force it here - // means that the pad must be "combined" with the origin to math the "final" OSPad-Struct - _Hi |= 0x00800000; - - return true; -} - -// __________________________________________________________________________________________________ -// SendCommand -// -void -CSIDevice_GCController::SendCommand(u32 _Cmd) -{ - UCommand command(_Cmd); - switch(command.Command) - { - // Costis sent it in some demos :) - case 0x00: - break; - - case CMD_RUMBLE: - { - unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard - unsigned int uStrength = command.Parameter2; - if (PluginPAD::PAD_Rumble) - PluginPAD::PAD_Rumble(ISIDevice::m_iDeviceNumber, uType, uStrength); - } - break; - - default: - { - LOG(SERIALINTERFACE, "unknown direct command (0x%x)", _Cmd); - PanicAlert("SI: Unknown direct command"); - } - break; - } -} - -// ===================================================================================================== -// --- dummy device --- -// ===================================================================================================== - -CSIDevice_Dummy::CSIDevice_Dummy(int _iDeviceNumber) : - ISIDevice(_iDeviceNumber) -{} - -int CSIDevice_Dummy::RunBuffer(u8* _pBuffer, int _iLength) -{ - reinterpret_cast(_pBuffer)[0] = 0x00000000; // no device - return 4; -} - -bool CSIDevice_Dummy::GetData(u32& _Hi, u32& _Low) -{ - return false; -} - -void CSIDevice_Dummy::SendCommand(u32 _Cmd) -{ -} - +// Copyright (C) 2003-2008 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 +#include + +#include "SI_Device.h" +#include "SI_DeviceGCController.h" +#include "../Plugins/Plugin_PAD.h" + +#include "EXI_Device.h" +#include "EXI_DeviceMic.h" + +// ===================================================================================================== +// --- standard gamecube controller --- +// ===================================================================================================== + +CSIDevice_GCController::CSIDevice_GCController(int _iDeviceNumber) : + ISIDevice(_iDeviceNumber) +{ + memset(&m_origin, 0, sizeof(SOrigin)); + + m_origin.uCommand = 0x41; + m_origin.uOriginStickX = 0x80; + m_origin.uOriginStickY = 0x80; + m_origin.uSubStickStickX = 0x80; + m_origin.uSubStickStickY = 0x80; + m_origin.uTrigger_L = 0x1F; + m_origin.uTrigger_R = 0x1F; +} + +int CSIDevice_GCController::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(_pBuffer[iPosition ^ 3]); + iPosition++; + + // handle it + switch(command) + { + case CMD_RESET: + { + *(u32*)&_pBuffer[0] = SI_GC_CONTROLLER; // | SI_GC_NOMOTOR; + iPosition = _iLength; // break the while loop + } + break; + + case CMD_ORIGIN: + { + LOG(SERIALINTERFACE, "PAD - Get Origin"); + u8* pCalibration = reinterpret_cast(&m_origin); + for (int i = 0; i < (int)sizeof(SOrigin); i++) + { + _pBuffer[i ^ 3] = *pCalibration++; + } + } + iPosition = _iLength; + break; + + // Recalibrate (FiRES: i am not 100 percent sure about this) + case CMD_RECALIBRATE: + { + LOG(SERIALINTERFACE, "PAD - Recalibrate"); + u8* pCalibration = reinterpret_cast(&m_origin); + for (int i = 0; i < (int)sizeof(SOrigin); i++) + { + _pBuffer[i ^ 3] = *pCalibration++; + } + } + iPosition = _iLength; + break; + + // WII Something + case 0xCE: + LOG(SERIALINTERFACE, "Unknown Wii SI Command"); + break; + + // DEFAULT + default: + { + LOG(SERIALINTERFACE, "unknown SI command (0x%x)", command); + PanicAlert("SI: Unknown command"); + iPosition = _iLength; + } + break; + } + } + + return iPosition; +} + +// __________________________________________________________________________________________________ +// GetData +// +// return true on new data (max 7 Bytes and 6 bits ;) +// +bool +CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) +{ + SPADStatus PadStatus; + memset(&PadStatus, 0 ,sizeof(PadStatus)); + PluginPAD::PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); + + _Hi = (u32)((u8)PadStatus.stickY); + _Hi |= (u32)((u8)PadStatus.stickX << 8); + _Hi |= (u32)((u16)PadStatus.button << 16); + + _Low = (u8)PadStatus.triggerRight; + _Low |= (u32)((u8)PadStatus.triggerLeft << 8); + _Low |= (u32)((u8)PadStatus.substickY << 16); + _Low |= (u32)((u8)PadStatus.substickX << 24); + SetMic(PadStatus.MicButton); + + // F|RES: + // i dunno if i should force it here + // means that the pad must be "combined" with the origin to math the "final" OSPad-Struct + _Hi |= 0x00800000; + + return true; +} + +// __________________________________________________________________________________________________ +// SendCommand +// +void +CSIDevice_GCController::SendCommand(u32 _Cmd) +{ + UCommand command(_Cmd); + switch(command.Command) + { + // Costis sent it in some demos :) + case 0x00: + break; + + case CMD_RUMBLE: + { + unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard + unsigned int uStrength = command.Parameter2; + if (PluginPAD::PAD_Rumble) + PluginPAD::PAD_Rumble(ISIDevice::m_iDeviceNumber, uType, uStrength); + } + break; + + default: + { + LOG(SERIALINTERFACE, "unknown direct command (0x%x)", _Cmd); + PanicAlert("SI: Unknown direct command"); + } + break; + } +} diff --git a/Source/Core/Core/Src/HW/SerialInterface_Devices.h b/Source/Core/Core/Src/HW/SI_DeviceGCController.h similarity index 64% rename from Source/Core/Core/Src/HW/SerialInterface_Devices.h rename to Source/Core/Core/Src/HW/SI_DeviceGCController.h index cae353d456..b7d9029fc5 100644 --- a/Source/Core/Core/Src/HW/SerialInterface_Devices.h +++ b/Source/Core/Core/Src/HW/SI_DeviceGCController.h @@ -1,139 +1,90 @@ -// Copyright (C) 2003-2008 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 _SERIALINTERFACE_DEVICES_H -#define _SERIALINTERFACE_DEVICES_H - -#include "Common.h" -class PointerWrap; - -class ISIDevice -{ -protected: - int m_iDeviceNumber; - -public: - - // constructor - ISIDevice(int _iDeviceNumber) : - m_iDeviceNumber(_iDeviceNumber) - { } - virtual ~ISIDevice() { } - - // run the SI Buffer - virtual int RunBuffer(u8* _pBuffer, int _iLength); - - // return true on new data - virtual bool GetData(u32& _Hi, u32& _Low) = 0; - - // send a command directly (no detour per buffer) - virtual void SendCommand(u32 _Cmd) = 0; -}; - -// ===================================================================================================== -// standard gamecube controller -// ===================================================================================================== - -class CSIDevice_GCController : public ISIDevice -{ -private: - - // commands - enum EBufferCommands - { - CMD_INVALID = 0xFFFFFFFF, - CMD_RESET = 0x00, - CMD_ORIGIN = 0x41, - CMD_RECALIBRATE = 0x42, - }; - - struct SOrigin - { - u8 uCommand; - u8 unk_1; - u8 uOriginStickX; - u8 uOriginStickY; - u8 uSubStickStickX; // ??? - u8 uSubStickStickY; // ??? - u8 uTrigger_L; // ??? - u8 uTrigger_R; // ??? - u8 unk_4; - u8 unk_5; - u8 unk_6; - u8 unk_7; - }; - - enum EDirectCommands - { - CMD_RUMBLE = 0x40 - }; - - union UCommand - { - u32 Hex; - struct - { - unsigned Parameter1 : 8; - unsigned Parameter2 : 8; - unsigned Command : 8; - unsigned : 8; - }; - UCommand() {Hex = 0;} - UCommand(u32 _iValue) {Hex = _iValue;} - }; - - SOrigin m_origin; - int DeviceNum; - -public: - - // constructor - CSIDevice_GCController(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); -}; - -// ===================================================================================================== -// dummy - no device attached -// ===================================================================================================== - -class CSIDevice_Dummy : public ISIDevice -{ -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); -}; - -#endif - +// Copyright (C) 2003-2008 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_DEVICEGCCONTROLLER_H +#define _SI_DEVICEGCCONTROLLER_H + +// ===================================================================================================== +// standard gamecube controller +// ===================================================================================================== + +class CSIDevice_GCController : public ISIDevice +{ +private: + + // commands + enum EBufferCommands + { + CMD_INVALID = 0xFFFFFFFF, + CMD_RESET = 0x00, + CMD_ORIGIN = 0x41, + CMD_RECALIBRATE = 0x42, + }; + + struct SOrigin + { + u8 uCommand; + u8 unk_1; + u8 uOriginStickX; + u8 uOriginStickY; + u8 uSubStickStickX; // ??? + u8 uSubStickStickY; // ??? + u8 uTrigger_L; // ??? + u8 uTrigger_R; // ??? + u8 unk_4; + u8 unk_5; + u8 unk_6; + u8 unk_7; + }; + + enum EDirectCommands + { + CMD_RUMBLE = 0x40 + }; + + union UCommand + { + u32 Hex; + struct + { + unsigned Parameter1 : 8; + unsigned Parameter2 : 8; + unsigned Command : 8; + unsigned : 8; + }; + UCommand() {Hex = 0;} + UCommand(u32 _iValue) {Hex = _iValue;} + }; + + SOrigin m_origin; + int DeviceNum; + +public: + + // constructor + CSIDevice_GCController(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 diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index 79f1dc60ce..d9ec74be3e 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -23,7 +23,7 @@ #include "../HW/DSP.h" #include "../HW/AudioInterface.h" #include "../HW/VideoInterface.h" -#include "../HW/SerialInterface.h" +#include "../HW/SI.h" #include "../HW/CommandProcessor.h" // for DC watchdog hack #include "../HW/EXI_DeviceIPL.h" #include "../PowerPC/PowerPC.h" diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript index caeabf4ae9..e042d11bd8 100644 --- a/Source/Core/Core/Src/SConscript +++ b/Source/Core/Core/Src/SConscript @@ -46,7 +46,10 @@ files = ["Console.cpp", "HW/PeripheralInterface.cpp", "HW/PixelEngine.cpp", "HW/SerialInterface.cpp", - "HW/SerialInterface_Devices.cpp", + "HW/SI.cpp", + "HW/SI_Device.cpp", + "HW/SI_DeviceGBA.cpp", + "HW/SI_DeviceGCController.cpp", "HW/StreamADPCM.cpp", "HW/SystemTimers.cpp", "HW/VideoInterface.cpp", diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index f9968ed5e4..6c81d96cd6 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -134,9 +134,10 @@ void CFrame::CreateMenu() wxMenu* pOptionsMenu = new wxMenu; m_pPluginOptions = pOptionsMenu->Append(IDM_CONFIG_MAIN, _T("Co&nfigure...")); pOptionsMenu->AppendSeparator(); - pOptionsMenu->Append(IDM_CONFIG_GFX_PLUGIN, _T("&Toolbar_PluginGFX settings")); - pOptionsMenu->Append(IDM_CONFIG_DSP_PLUGIN, _T("&Toolbar_PluginDSP settings")); - pOptionsMenu->Append(IDM_CONFIG_PAD_PLUGIN, _T("&Toolbar_PluginPAD settings")); + pOptionsMenu->Append(IDM_CONFIG_GFX_PLUGIN, _T("&GFX settings")); + pOptionsMenu->Append(IDM_CONFIG_DSP_PLUGIN, _T("&DSP settings")); + pOptionsMenu->Append(IDM_CONFIG_PAD_PLUGIN, _T("&PAD settings")); + pOptionsMenu->Append(IDM_CONFIG_WIIMOTE_PLUGIN, _T("&Wiimote settings")); #ifdef _WIN32 pOptionsMenu->AppendSeparator(); pOptionsMenu->Append(IDM_TOGGLE_FULLSCREEN, _T("&Fullscreen\tAlt+Enter"));