fix weirdo serialinterface (pad) errors. get rid of si_channel. i guess it was a bad idea :<

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2135 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2009-02-08 02:58:18 +00:00
parent adde9b778b
commit 553656966b
6 changed files with 320 additions and 424 deletions

View File

@ -618,14 +618,6 @@
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"
>

View File

@ -22,23 +22,96 @@
#include "PeripheralInterface.h"
#include "SI.h"
#include "SI_Channel.h"
namespace SerialInterface
{
void RunSIBuffer();
void UpdateInterrupts();
// SI Interrupt Types
enum SIInterruptType
{
INT_RDSTINT = 0,
INT_TCINT = 1,
};
static void GenerateSIInterrupt(SIInterruptType _SIInterrupt);
// SI number of channels
enum
{
NUMBER_OF_CHANNELS = 4
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
@ -136,26 +209,34 @@ union USIEXIClockCount
};
// STATE_TO_SAVE
CSIChannel *g_Channel; // Save the channel state here?
static USIPoll g_Poll;
static USIComCSR g_ComCSR;
static USIStatusReg g_StatusReg;
static USIEXIClockCount g_EXIClockCount;
static u8 g_SIBuffer[128];
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];
static void GenerateSIInterrupt(SIInterruptType _SIInterrupt);
void RunSIBuffer();
void UpdateInterrupts();
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);
}
void Init()
{
g_Channel = new CSIChannel[NUMBER_OF_CHANNELS];
// TODO: allow dynamic attaching/detaching of devices
for (int i = 0; i < NUMBER_OF_CHANNELS; i++)
{
g_Channel[i].m_ChannelId = i;
g_Channel[i].AddDevice(SConfig::GetInstance().m_SIDevice[i], i);
{
g_Channel[i].m_Out.Hex = 0;
g_Channel[i].m_InHi.Hex = 0;
g_Channel[i].m_InLo.Hex = 0;
AddDevice(SConfig::GetInstance().m_SIDevice[i], i);
}
g_Poll.Hex = 0;
@ -167,18 +248,11 @@ void Init()
void Shutdown()
{
delete [] g_Channel;
g_Channel = 0;
}
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);
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)
@ -193,19 +267,104 @@ void Read32(u32& _uReturnValue, const u32 _iAddress)
return;
}
// (shuffle2) these assignments are taken from EXI,
// the iAddr amounted to the same, so I'm guessing the rest are too :D
unsigned int iAddr = _iAddress & 0x3FF;
unsigned int iRegister = (iAddr >> 2) % 5;
unsigned int iChannel = (iAddr >> 2) / 5;
// registers
switch (_iAddress & 0x3FF)
{
//////////////////////////////////////////////////////////////////////////
// Channel 0
//////////////////////////////////////////////////////////////////////////
case SI_CHANNEL_0_OUT:
_uReturnValue = g_Channel[0].m_Out.Hex;
return;
if (iChannel < NUMBER_OF_CHANNELS)
g_Channel[iChannel].Read32(_uReturnValue, iAddr);
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);
LOGV(SERIALINTERFACE, 3, "(w32): 0x%08x 0x%08x", _iValue,_iAddress);
// SIBuffer
if ((_iAddress >= 0xCC006480 && _iAddress < 0xCC006500) ||
@ -215,12 +374,101 @@ void Write32(const u32 _iValue, const u32 _iAddress)
return;
}
int iAddr = _iAddress & 0x3FF;
int iRegister = (iAddr >> 2) % 5;
int iChannel = (iAddr >> 2) / 5;
// 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;
if (iChannel < NUMBER_OF_CHANNELS)
g_Channel[iChannel].Write32(_iValue, iAddr);
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()
@ -255,6 +503,27 @@ void GenerateSIInterrupt(SIInterruptType _SIInterrupt)
UpdateInterrupts();
}
void RemoveDevice(int _iDeviceNumber)
{
if (g_Channel[_iDeviceNumber].m_pDevice != NULL)
{
delete g_Channel[_iDeviceNumber].m_pDevice;
g_Channel[_iDeviceNumber].m_pDevice = NULL;
}
}
void AddDevice(const TSIDevices _device, int _iDeviceNumber)
{
//_dbg_assert_(SERIALINTERFACE, _iDeviceNumber < NUMBER_OF_CHANNELS);
// delete the old device
RemoveDevice(_iDeviceNumber);
// create the new one
g_Channel[_iDeviceNumber].m_pDevice = SIDevice_Create(_device, _iDeviceNumber);
_dbg_assert_(SERIALINTERFACE, g_Channel[_iDeviceNumber].m_pDevice != NULL);
}
void UpdateDevices()
{
// Update channels
@ -283,9 +552,9 @@ void RunSIBuffer()
else
outLength++;
#ifdef LOGGING
int numOutput =
#endif
#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);

View File

@ -18,6 +18,7 @@
#define _SERIALINTERFACE_H
#include "Common.h"
#include "SI_Device.h"
class PointerWrap;
namespace SerialInterface
@ -29,6 +30,9 @@ void DoState(PointerWrap &p);
void UpdateDevices();
void RemoveDevice(int _iDeviceNumber);
void AddDevice(const TSIDevices _device, int _iDeviceNumber);
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);

View File

@ -1,257 +0,0 @@
// 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;
}
}

View File

@ -1,111 +0,0 @@
// 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

View File

@ -118,8 +118,7 @@ CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
{
SPADStatus PadStatus;
memset(&PadStatus, 0 ,sizeof(PadStatus));
Common::PluginPAD* pad =
CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
pad->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
_Hi = (u32)((u8)PadStatus.stickY);
@ -146,7 +145,7 @@ CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
void
CSIDevice_GCController::SendCommand(u32 _Cmd)
{
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(0);
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
UCommand command(_Cmd);
switch(command.Command)