mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-06 23:11:18 +12:00
Add all the files
This commit is contained in:
parent
e3db07a16a
commit
d60742f52b
1445 changed files with 430238 additions and 0 deletions
162
src/Cafe/HW/SI/SI.cpp
Normal file
162
src/Cafe/HW/SI/SI.cpp
Normal file
|
@ -0,0 +1,162 @@
|
|||
#include "Cafe/HW/MMU/MMU.h"
|
||||
#include "Cafe/HW/Common/HwReg.h"
|
||||
#include "si.h"
|
||||
|
||||
namespace HW_SI
|
||||
{
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
HWREG::SICOMCSR sicomcsr{};
|
||||
HWREG::SIPOLL sipoll{};
|
||||
HWREG::SICOUTBUF outBuf[4]{};
|
||||
}registerState;
|
||||
struct
|
||||
{
|
||||
uint8 cmd{};
|
||||
uint8 buf[2]{};
|
||||
}outputBufferState[4];
|
||||
struct
|
||||
{
|
||||
bool hasErrorNoResponse{};
|
||||
}channelStatus[4];
|
||||
}g_si;
|
||||
|
||||
// normally we should call this periodically according to the parameters set in SIPOLL
|
||||
// but for now we just call it whenever status registers are read
|
||||
void handlePollUpdate()
|
||||
{
|
||||
for (uint32 i = 0; i < 4; i++)
|
||||
{
|
||||
// note: Order of EN and VBCPY is from MSB to LSB
|
||||
bool isEnabled = ((g_si.registerState.sipoll.get_EN() >> (3 - i))&1) != 0;
|
||||
if (isEnabled)
|
||||
{
|
||||
g_si.channelStatus[i].hasErrorNoResponse = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handleQueuedTransfers()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void flushAllOutputBuffers()
|
||||
{
|
||||
for (uint32 i = 0; i < 4; i++)
|
||||
{
|
||||
g_si.outputBufferState[i].cmd = g_si.registerState.outBuf[i].get_CMD();
|
||||
g_si.outputBufferState[i].buf[0] = g_si.registerState.outBuf[i].get_OUTPUT0();
|
||||
g_si.outputBufferState[i].buf[1] = g_si.registerState.outBuf[i].get_OUTPUT1();
|
||||
}
|
||||
}
|
||||
|
||||
/* +0x6400/0x640C/0x6418/0x6424 | SI0COUTBUF - SI3COUTBUF */
|
||||
|
||||
HWREG::SICOUTBUF SI_COUTBUF_R32(PAddr addr)
|
||||
{
|
||||
uint32 joyChannelIndex = (addr & 0xFF) / 0xC;
|
||||
|
||||
cemu_assert_debug(false);
|
||||
return HWREG::SICOUTBUF();
|
||||
}
|
||||
|
||||
void SI_COUTBUF_W32(PAddr addr, HWREG::SICOUTBUF newValue)
|
||||
{
|
||||
uint32 joyChannelIndex = (addr & 0xFF) / 0xC;
|
||||
g_si.registerState.outBuf[joyChannelIndex] = newValue;
|
||||
}
|
||||
|
||||
/* +0x6430 | SIPOLL */
|
||||
|
||||
HWREG::SIPOLL SI_POLL_R32(PAddr addr)
|
||||
{
|
||||
cemu_assert_debug(false);
|
||||
return g_si.registerState.sipoll;
|
||||
}
|
||||
|
||||
void SI_POLL_W32(PAddr addr, HWREG::SIPOLL newValue)
|
||||
{
|
||||
g_si.registerState.sipoll = newValue;
|
||||
}
|
||||
|
||||
/* +0x6434 | SICOMCSR */
|
||||
|
||||
HWREG::SICOMCSR SI_COMCSR_R32(PAddr addr)
|
||||
{
|
||||
//forceLogDebug_printf("Read SICOMCSR");
|
||||
return g_si.registerState.sicomcsr;
|
||||
}
|
||||
|
||||
void SI_COMCSR_W32(PAddr addr, HWREG::SICOMCSR newValue)
|
||||
{
|
||||
uint32 unhandledBits = g_si.registerState.sicomcsr.getRawValue() & ~(0x80000000);
|
||||
cemu_assert_debug(unhandledBits == 0);
|
||||
// clear transfer complete interrupt
|
||||
if (newValue.get_TCINT())
|
||||
{
|
||||
g_si.registerState.sicomcsr.set_TCINT(0);
|
||||
}
|
||||
|
||||
if (newValue.get_TRANSFER_START())
|
||||
{
|
||||
cemu_assert_debug(false);
|
||||
handleQueuedTransfers();
|
||||
}
|
||||
}
|
||||
|
||||
/* +0x6438 | SISR */
|
||||
|
||||
HWREG::SISR SI_SR_R32(PAddr addr)
|
||||
{
|
||||
handlePollUpdate();
|
||||
HWREG::SISR reg;
|
||||
// no response error
|
||||
if (g_si.channelStatus[0].hasErrorNoResponse)
|
||||
reg.set_NOREP0(1);
|
||||
if (g_si.channelStatus[1].hasErrorNoResponse)
|
||||
reg.set_NOREP1(1);
|
||||
if (g_si.channelStatus[2].hasErrorNoResponse)
|
||||
reg.set_NOREP2(1);
|
||||
if (g_si.channelStatus[3].hasErrorNoResponse)
|
||||
reg.set_NOREP3(1);
|
||||
|
||||
// todo - other status fields
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
void SI_SR_W32(PAddr addr, HWREG::SISR newValue)
|
||||
{
|
||||
if (newValue.get_NOREP0())
|
||||
g_si.channelStatus[0].hasErrorNoResponse = false;
|
||||
if (newValue.get_NOREP1())
|
||||
g_si.channelStatus[1].hasErrorNoResponse = false;
|
||||
if (newValue.get_NOREP2())
|
||||
g_si.channelStatus[2].hasErrorNoResponse = false;
|
||||
if (newValue.get_NOREP3())
|
||||
g_si.channelStatus[3].hasErrorNoResponse = false;
|
||||
|
||||
|
||||
if (newValue.get_WR())
|
||||
{
|
||||
// copies contents of SICOUTBUF to the internal shadow buffers
|
||||
flushAllOutputBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
MMU::RegisterMMIO_32<HWREG::SICOUTBUF, SI_COUTBUF_R32, SI_COUTBUF_W32>(MMU::MMIOInterface::INTERFACE_0D000000, 0x6400);
|
||||
MMU::RegisterMMIO_32<HWREG::SICOUTBUF, SI_COUTBUF_R32, SI_COUTBUF_W32>(MMU::MMIOInterface::INTERFACE_0D000000, 0x640C);
|
||||
MMU::RegisterMMIO_32<HWREG::SICOUTBUF, SI_COUTBUF_R32, SI_COUTBUF_W32>(MMU::MMIOInterface::INTERFACE_0D000000, 0x6418);
|
||||
MMU::RegisterMMIO_32<HWREG::SICOUTBUF, SI_COUTBUF_R32, SI_COUTBUF_W32>(MMU::MMIOInterface::INTERFACE_0D000000, 0x6424);
|
||||
|
||||
MMU::RegisterMMIO_32<HWREG::SIPOLL, SI_POLL_R32, SI_POLL_W32>(MMU::MMIOInterface::INTERFACE_0D000000, 0x6430);
|
||||
MMU::RegisterMMIO_32<HWREG::SICOMCSR, SI_COMCSR_R32, SI_COMCSR_W32>(MMU::MMIOInterface::INTERFACE_0D000000, 0x6434);
|
||||
MMU::RegisterMMIO_32<HWREG::SISR, SI_SR_R32, SI_SR_W32>(MMU::MMIOInterface::INTERFACE_0D000000, 0x6438);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue