Add ability to use Reset (reset button interrupt, still figuring out the other reset modes)

Add support for button combos that are built-in to controllers:
y+x+start for three seconds updates the origin
b+x+start for three seconds resets
Changed CPeripheralInterface to a namespace and renamed to ProcessorInterface

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4366 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman
2009-10-06 15:49:20 +00:00
parent 19b8e6bc08
commit 4c22bea4d4
33 changed files with 342 additions and 295 deletions
+1 -1
View File
@@ -229,7 +229,7 @@ void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool
int BytesWritten = 0;
DWORD cAttrWritten = 0;
for (int i = 0; i < Attr.size(); i++)
for (size_t i = 0; i < Attr.size(); i++)
{
if (!WriteConsoleOutputCharacter(hConsole, Str[i], ReadBufferSize, coordScreen, &cCharsWritten))
SLog += StringFromFormat("WriteConsoleOutputCharacter error");
+1 -1
View File
@@ -52,7 +52,7 @@ enum LOG_TYPE {
MEMCARD_MANAGER,
OSREPORT,
PAD,
PERIPHERALINTERFACE,
PROCESSORINTERFACE,
PIXELENGINE,
SERIALINTERFACE,
SP1,
+1 -1
View File
@@ -40,7 +40,7 @@ LogManager::LogManager() : logMutex(1) {
m_Log[LogTypes::COMMANDPROCESSOR] = new LogContainer("CP", "CommandProc");
m_Log[LogTypes::VIDEOINTERFACE] = new LogContainer("VI", "VideoInt");
m_Log[LogTypes::SERIALINTERFACE] = new LogContainer("SI", "SerialInt");
m_Log[LogTypes::PERIPHERALINTERFACE]= new LogContainer("PI", "PeripheralInt");
m_Log[LogTypes::PROCESSORINTERFACE] = new LogContainer("PI", "ProcessorInt");
m_Log[LogTypes::MEMMAP] = new LogContainer("MI", "MI & memmap");
m_Log[LogTypes::SP1] = new LogContainer("SP1", "Serial Port 1");
m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream", "StreamingInt");
+4 -4
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Version="9.00"
Name="Core"
ProjectGUID="{F0B874CB-4476-4199-9315-8343D05AE684}"
RootNamespace="Core"
@@ -904,14 +904,14 @@
</File>
</Filter>
<Filter
Name="PI - Peripheral Interface"
Name="PI - Processor Interface"
>
<File
RelativePath=".\Src\Hw\PeripheralInterface.cpp"
RelativePath=".\Src\HW\ProcessorInterface.cpp"
>
</File>
<File
RelativePath=".\Src\Hw\PeripheralInterface.h"
RelativePath=".\Src\HW\ProcessorInterface.h"
>
</File>
</Filter>
+1 -1
View File
@@ -27,7 +27,7 @@
#include "../HW/HW.h"
#include "../HW/EXI_DeviceIPL.h"
#include "../HW/Memmap.h"
#include "../HW/PeripheralInterface.h"
#include "../HW/ProcessorInterface.h"
#include "../HW/DVDInterface.h"
#include "../HW/VideoInterface.h"
#include "../HW/CPU.h"
+1 -1
View File
@@ -35,7 +35,7 @@
#include "Boot/Boot.h"
#include "HW/Memmap.h"
#include "HW/PeripheralInterface.h"
#include "HW/ProcessorInterface.h"
#include "HW/GPFifo.h"
#include "HW/CPU.h"
#include "HW/HW.h"
+1 -1
View File
@@ -40,7 +40,7 @@
#include "PatchEngine.h"
#include "HW/Memmap.h"
#include "HW/PeripheralInterface.h"
#include "HW/ProcessorInterface.h"
#include "HW/GPFifo.h"
#include "HW/CPU.h"
#include "HW/HW.h"
+3 -3
View File
@@ -28,7 +28,7 @@
#include "AudioInterface.h"
#include "CPU.h"
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "DVDInterface.h"
#include "../PowerPC/PowerPC.h"
#include "../CoreTiming.h"
@@ -251,11 +251,11 @@ void UpdateInterrupts()
{
if (g_AudioRegister.m_Control.AIINT & g_AudioRegister.m_Control.AIINTMSK)
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_AUDIO, true);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_AUDIO, true);
}
else
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_AUDIO, false);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_AUDIO, false);
}
}
+9 -9
View File
@@ -77,7 +77,7 @@
#include "Atomic.h"
#include "Memmap.h"
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "GPFifo.h"
#include "CPU.h"
#include "../Core.h"
@@ -616,9 +616,9 @@ void STACKALIGN GatherPipeBursted()
s_fifoIdleEvent.MsgWait();
}
// check if we are in sync
_assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == CPeripheralInterface::Fifo_CPUWritePointer, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPBase == CPeripheralInterface::Fifo_CPUBase, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == CPeripheralInterface::Fifo_CPUEnd, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == ProcessorInterface::Fifo_CPUWritePointer, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPBase == ProcessorInterface::Fifo_CPUBase, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == ProcessorInterface::Fifo_CPUEnd, "FIFOs linked but out of sync");
}
else
{
@@ -626,9 +626,9 @@ void STACKALIGN GatherPipeBursted()
if (fifo.CPWritePointer >= fifo.CPEnd)
fifo.CPWritePointer = fifo.CPBase;
// check if we are in sync
_assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == CPeripheralInterface::Fifo_CPUWritePointer, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPBase == CPeripheralInterface::Fifo_CPUBase, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == CPeripheralInterface::Fifo_CPUEnd, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == ProcessorInterface::Fifo_CPUWritePointer, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPBase == ProcessorInterface::Fifo_CPUBase, "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == ProcessorInterface::Fifo_CPUEnd, "FIFOs linked but out of sync");
UpdateFifoRegister();
}
@@ -723,11 +723,11 @@ void UpdateInterrupts()
if (m_CPCtrlReg.CPIntEnable &&
(fifo.bFF_BPEnable && fifo.bFF_Breakpoint))
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_CP, true);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_CP, true);
}
else
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_CP, false);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_CP, false);
}
}
+3 -3
View File
@@ -42,7 +42,7 @@
#include "CPU.h"
#include "MemoryUtil.h"
#include "Memmap.h"
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "AudioInterface.h"
#include "../PowerPC/PowerPC.h"
#include "../PluginManager.h"
@@ -525,11 +525,11 @@ void UpdateInterrupts()
(g_dspState.DSPControl.ARAM & g_dspState.DSPControl.ARAM_mask) ||
(g_dspState.DSPControl.DSP & g_dspState.DSPControl.DSP_mask))
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_DSP, true);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DSP, true);
}
else
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_DSP, false);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DSP, false);
}
}
+3 -3
View File
@@ -23,7 +23,7 @@
#include "StreamADPCM.H" // Core
#include "DVDInterface.h"
#include "../PowerPC/PowerPC.h"
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "Memmap.h"
#include "Thread.h"
#include "../VolumeHandler.h"
@@ -507,11 +507,11 @@ void UpdateInterrupts()
(dvdMem.StatusReg.BRKINT & dvdMem.StatusReg.BRKINTMASK) ||
(dvdMem.CoverReg.CVRINT & dvdMem.CoverReg.CVRINTMASK))
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_DI, true);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DI, true);
}
else
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_DI, false);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DI, false);
}
}
+3 -3
View File
@@ -20,7 +20,7 @@
#include "../ConfigManager.h"
#include "../CoreTiming.h"
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "../PowerPC/PowerPC.h"
#include "EXI.h"
@@ -132,12 +132,12 @@ void UpdateInterrupts()
{
if(g_Channels[i].IsCausingInterrupt())
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_EXI, true);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_EXI, true);
return;
}
}
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_EXI, false);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_EXI, false);
}
} // end of namespace ExpansionInterface
+1 -1
View File
@@ -24,7 +24,7 @@
#define EXI_READWRITE 2
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "../PowerPC/PowerPC.h"
CEXIChannel::CEXIChannel() :
+10 -10
View File
@@ -17,7 +17,7 @@
#include "Common.h"
#include "ChunkFile.h"
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "CommandProcessor.h"
#include "Memmap.h"
#include "../PowerPC/PowerPC.h"
@@ -71,7 +71,7 @@ void STACKALIGN CheckGatherPipe()
while (m_gatherPipeCount >= GATHER_PIPE_SIZE)
{
// copy the GatherPipe
memcpy(Memory::GetPointer(CPeripheralInterface::Fifo_CPUWritePointer), m_gatherPipe, GATHER_PIPE_SIZE);
memcpy(Memory::GetPointer(ProcessorInterface::Fifo_CPUWritePointer), m_gatherPipe, GATHER_PIPE_SIZE);
// move back the spill bytes
m_gatherPipeCount -= GATHER_PIPE_SIZE;
@@ -80,21 +80,21 @@ void STACKALIGN CheckGatherPipe()
memcpy(m_gatherPipe, m_gatherPipe + GATHER_PIPE_SIZE, m_gatherPipeCount);
// increase the CPUWritePointer
CPeripheralInterface::Fifo_CPUWritePointer += GATHER_PIPE_SIZE;
ProcessorInterface::Fifo_CPUWritePointer += GATHER_PIPE_SIZE;
if (CPeripheralInterface::Fifo_CPUWritePointer > CPeripheralInterface::Fifo_CPUEnd)
if (ProcessorInterface::Fifo_CPUWritePointer > ProcessorInterface::Fifo_CPUEnd)
_assert_msg_(DYNA_REC, 0, "Fifo_CPUWritePointer out of bounds: %08x (end = %08x)",
CPeripheralInterface::Fifo_CPUWritePointer, CPeripheralInterface::Fifo_CPUEnd);
ProcessorInterface::Fifo_CPUWritePointer, ProcessorInterface::Fifo_CPUEnd);
if (CPeripheralInterface::Fifo_CPUWritePointer >= CPeripheralInterface::Fifo_CPUEnd)
CPeripheralInterface::Fifo_CPUWritePointer = CPeripheralInterface::Fifo_CPUBase;
if (ProcessorInterface::Fifo_CPUWritePointer >= ProcessorInterface::Fifo_CPUEnd)
ProcessorInterface::Fifo_CPUWritePointer = ProcessorInterface::Fifo_CPUBase;
CommandProcessor::GatherPipeBursted();
}
}
void Write8(const u8 _iValue, const u32 _iAddress)
{
// LOG(GPFIFO, "GPFIFO #%x: 0x%02x",CPeripheralInterface::Fifo_CPUWritePointer+m_gatherPipeCount, _iValue);
// LOG(GPFIFO, "GPFIFO #%x: 0x%02x",ProcessorInterface::Fifo_CPUWritePointer+m_gatherPipeCount, _iValue);
m_gatherPipe[m_gatherPipeCount] = _iValue;
m_gatherPipeCount++;
CheckGatherPipe();
@@ -102,7 +102,7 @@ void Write8(const u8 _iValue, const u32 _iAddress)
void Write16(const u16 _iValue, const u32 _iAddress)
{
// LOG(GPFIFO, "GPFIFO #%x: 0x%04x",CPeripheralInterface::Fifo_CPUWritePointer+m_gatherPipeCount, _iValue);
// LOG(GPFIFO, "GPFIFO #%x: 0x%04x",ProcessorInterface::Fifo_CPUWritePointer+m_gatherPipeCount, _iValue);
*(u16*)(&m_gatherPipe[m_gatherPipeCount]) = Common::swap16(_iValue);
m_gatherPipeCount += 2;
CheckGatherPipe();
@@ -112,7 +112,7 @@ void Write32(const u32 _iValue, const u32 _iAddress)
{
#ifdef _DEBUG
float floatvalue = *(float*)&_iValue;
// LOG(GPFIFO, "GPFIFO #%x: 0x%08x / %f",CPeripheralInterface::Fifo_CPUWritePointer+m_gatherPipeCount, _iValue, floatvalue);
// LOG(GPFIFO, "GPFIFO #%x: 0x%08x / %f",ProcessorInterface::Fifo_CPUWritePointer+m_gatherPipeCount, _iValue, floatvalue);
#endif
*(u32*)(&m_gatherPipe[m_gatherPipeCount]) = Common::swap32(_iValue);
m_gatherPipeCount += 4;
+3 -3
View File
@@ -27,7 +27,7 @@
#include "EXI.h"
#include "GPFifo.h"
#include "Memmap.h"
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "PixelEngine.h"
#include "SI.h"
#include "AudioInterface.h"
@@ -56,7 +56,7 @@ namespace HW
CommandProcessor::Init();
VideoInterface::Init();
SerialInterface::Init();
CPeripheralInterface::Init();
ProcessorInterface::Init();
Memory::Init();
DSP::Init();
DVDInterface::Init();
@@ -100,7 +100,7 @@ namespace HW
CommandProcessor::DoState(p);
VideoInterface::DoState(p);
SerialInterface::DoState(p);
CPeripheralInterface::DoState(p);
ProcessorInterface::DoState(p);
DSP::DoState(p);
DVDInterface::DoState(p);
GPFifo::DoState(p);
+5 -5
View File
@@ -32,7 +32,7 @@ may be redirected here (for example to Read_U32()).
#include "../PowerPC/Jit64/Jit.h"
#include "../HLE/HLE.h"
#include "CPU.h"
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "DSP.h"
#include "DVDInterface.h"
#include "GPFifo.h"
@@ -204,8 +204,8 @@ void InitHWMemFuncs()
hwWrite16[VI_START+i] = VideoInterface::Write16;
hwWrite32[VI_START+i] = VideoInterface::Write32;
hwRead32 [PI_START+i] = CPeripheralInterface::Read32;
hwWrite32[PI_START+i] = CPeripheralInterface::Write32;
hwRead32 [PI_START+i] = ProcessorInterface::Read32;
hwWrite32[PI_START+i] = ProcessorInterface::Write32;
hwRead16 [MI_START+i] = MemoryInterface::Read16;
hwRead32 [MI_START+i] = MemoryInterface::Read32;
@@ -270,8 +270,8 @@ void InitHWMemFuncsWii()
hwWrite16[PE_START+i] = PixelEngine::Write16;
hwWrite32[PE_START+i] = PixelEngine::Write32;
hwRead32 [PI_START+i] = CPeripheralInterface::Read32;
hwWrite32[PI_START+i] = CPeripheralInterface::Write32;
hwRead32 [PI_START+i] = ProcessorInterface::Read32;
hwWrite32[PI_START+i] = ProcessorInterface::Write32;
hwRead8 [VI_START+i] = VideoInterface::Read8;
hwRead16 [VI_START+i] = VideoInterface::Read16;
@@ -1,120 +0,0 @@
// Copyright (C) 2003 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 _PERIPHERALINTERFACE_H
#define _PERIPHERALINTERFACE_H
#include "Common.h"
class PointerWrap;
//
// PERIPHERALINTERFACE
// Handles communication with cpu services like the write gatherer used for fifos, and interrupts
//
class CPeripheralInterface
{
friend class CRegisters;
public:
enum InterruptCause
{
INT_CAUSE_ERROR = 0x1, // ?
INT_CAUSE_RSW = 0x2, // Reset Switch
INT_CAUSE_DI = 0x4, // DVD interrupt
INT_CAUSE_SI = 0x8, // Serial interface
INT_CAUSE_EXI = 0x10, // Expansion interface
INT_CAUSE_AUDIO = 0x20, // Audio Interface Streaming
INT_CAUSE_DSP = 0x40, // DSP interface
INT_CAUSE_MEMORY = 0x80, // Memory interface
INT_CAUSE_VI = 0x100, // Video interface
INT_CAUSE_PE_TOKEN = 0x200, // GP Token
INT_CAUSE_PE_FINISH = 0x400, // GP Finished
INT_CAUSE_CP = 0x800, // Command Fifo
INT_CAUSE_DEBUG = 0x1000, // ?
INT_CAUSE_HSP = 0x2000, // High Speed Port
INT_CAUSE_WII_IPC = 0x4000, // Wii IPC
INT_CAUSE_RST_BUTTON = 0x10000 // ResetButtonState (1 = unpressed, 0 = pressed)
};
private:
// internal hardware addresses
enum
{
PI_INTERRUPT_CAUSE = 0x000,
PI_INTERRUPT_MASK = 0x004,
PI_FIFO_BASE = 0x00C,
PI_FIFO_END = 0x010,
PI_FIFO_WPTR = 0x014,
PI_FIFO_RESET = 0x018, // ??? - GXAbortFrameWrites to it
PI_RESET_CODE = 0x024,
PI_MB_REV = 0x02C,
};
//This must always be byteswapped :( (UNUSED ATM)
struct PIRegMem
{
u32 rInterruptCause; //00
u32 rInterruptMask; //04
u32 unused0; //08
u32 FifoBase; //0C
u32 FifoEnd; //10
u32 FifoWptr; //14
u32 FifoReset; //18
u32 unused1; //1C
u32 unused2; //20
u32 ResetCode; //24
u32 unused3; //28
u32 MBRev; //2C
};
static volatile u32 m_InterruptMask;
static volatile u32 m_InterruptCause;
static void UpdateException();
// Debug_GetInterruptName
static const char* Debug_GetInterruptName(InterruptCause _causemask);
public:
static u32 Fifo_CPUBase;
static u32 Fifo_CPUEnd;
static u32 Fifo_CPUWritePointer;
static void Init();
static void DoState(PointerWrap &p);
static u32 GetMask() { return m_InterruptMask; }
static u32 GetCause() { return m_InterruptCause; }
static void SetInterrupt(InterruptCause _causemask, bool _bSet=true);
// Read32
static void Read32(u32& _uReturnValue, const u32 _iAddress);
// Write32
static void Write32(const u32 _iValue, const u32 _iAddress);
// SetResetButton (you have to release the button again to make a reset)
static void SetResetButton(bool _bSet);
};
#endif
+5 -5
View File
@@ -28,7 +28,7 @@
#include "../CoreTiming.h"
#include "../PowerPC/PowerPC.h"
#include "PeripheralInterface.h"
#include "ProcessorInterface.h"
#include "CommandProcessor.h"
#include "CPU.h"
#include "../Core.h"
@@ -309,15 +309,15 @@ void UpdateInterrupts()
{
// check if there is a token-interrupt
if (g_bSignalTokenInterrupt & m_Control.PETokenEnable)
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_PE_TOKEN, true);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_PE_TOKEN, true);
else
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_PE_TOKEN, false);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_PE_TOKEN, false);
// check if there is a finish-interrupt
if (g_bSignalFinishInterrupt & m_Control.PEFinishEnable)
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_PE_FINISH, true);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_PE_FINISH, true);
else
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_PE_FINISH, false);
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_PE_FINISH, false);
}
// TODO(mb2): Refactor SetTokenINT_OnMainThread(u64 userdata, int cyclesLate).
@@ -20,29 +20,62 @@
#include "ChunkFile.h"
#include "../PowerPC/PowerPC.h"
#include "../HW/CPU.h"
#include "PeripheralInterface.h"
#include "CPU.h"
#include "../CoreTiming.h"
#include "ProcessorInterface.h"
#include "GPFifo.h"
namespace ProcessorInterface
{
// Internal hardware addresses
enum
{
PI_INTERRUPT_CAUSE = 0x00,
PI_INTERRUPT_MASK = 0x04,
PI_FIFO_BASE = 0x0C,
PI_FIFO_END = 0x10,
PI_FIFO_WPTR = 0x14,
PI_FIFO_RESET = 0x18, // ??? - GXAbortFrameWrites to it
PI_RESET_CODE = 0x24,
PI_MB_REV = 0x2C,
};
// STATE_TO_SAVE
u32 volatile CPeripheralInterface::m_InterruptMask;
u32 volatile CPeripheralInterface::m_InterruptCause;
volatile u32 m_InterruptCause;
volatile u32 m_InterruptMask;
// addresses for CPU fifo accesses
u32 CPeripheralInterface::Fifo_CPUBase;
u32 CPeripheralInterface::Fifo_CPUEnd;
u32 CPeripheralInterface::Fifo_CPUWritePointer;
u32 Fifo_CPUBase;
u32 Fifo_CPUEnd;
u32 Fifo_CPUWritePointer;
u32 m_Fifo_Reset;
u32 m_ResetCode;
u32 m_MBRev;
void CPeripheralInterface::DoState(PointerWrap &p)
// ID and callback for scheduling reset button presses/releases
static int toggleResetButton;
void ToggleResetButtonCallback(u64 userdata, int cyclesLate);
// Let the PPC know that an external exception is set/cleared
void UpdateException();
void DoState(PointerWrap &p)
{
p.Do(m_InterruptMask);
p.Do(m_InterruptCause);
p.Do(Fifo_CPUBase);
p.Do(Fifo_CPUEnd);
p.Do(Fifo_CPUWritePointer);
// (shuffle2) Enable sometime ;p
// p.Do(m_Fifo_Reset);
// p.Do(m_ResetCode);
// p.Do(m_MBRev);
}
void CPeripheralInterface::Init()
void Init()
{
m_InterruptMask = 0;
m_InterruptCause = 0;
@@ -51,12 +84,18 @@ void CPeripheralInterface::Init()
Fifo_CPUEnd = 0;
Fifo_CPUWritePointer = 0;
m_InterruptCause |= INT_CAUSE_RST_BUTTON; // Reset button state
m_MBRev = 2 << 28; // HW2 production board
// Bleh, why?
//m_ResetCode |= 0x80000000;
//m_InterruptCause |= INT_CAUSE_RST_BUTTON;
toggleResetButton = CoreTiming::RegisterEvent("ToggleResetButton", &ToggleResetButtonCallback);
}
void CPeripheralInterface::Read32(u32& _uReturnValue, const u32 _iAddress)
void Read32(u32& _uReturnValue, const u32 _iAddress)
{
//LOG(PERIPHERALINTERFACE, "(r32) 0x%08x", _iAddress);
//INFO_LOG(PROCESSORINTERFACE, "(r32) 0x%08x", _iAddress);
switch(_iAddress & 0xFFF)
{
@@ -69,100 +108,89 @@ void CPeripheralInterface::Read32(u32& _uReturnValue, const u32 _iAddress)
return;
case PI_FIFO_BASE:
INFO_LOG(PERIPHERALINTERFACE,"read cpu fifo base, value = %08x",Fifo_CPUBase);
DEBUG_LOG(PROCESSORINTERFACE, "read cpu fifo base, value = %08x", Fifo_CPUBase);
_uReturnValue = Fifo_CPUBase;
return;
case PI_FIFO_END:
INFO_LOG(PERIPHERALINTERFACE,"read cpu fifo end, value = %08x",Fifo_CPUEnd);
DEBUG_LOG(PROCESSORINTERFACE, "read cpu fifo end, value = %08x", Fifo_CPUEnd);
_uReturnValue = Fifo_CPUEnd;
return;
case PI_FIFO_WPTR:
DEBUG_LOG(PERIPHERALINTERFACE, "read writepointer, value = %08x",Fifo_CPUWritePointer);
DEBUG_LOG(PROCESSORINTERFACE, "read writepointer, value = %08x", Fifo_CPUWritePointer);
_uReturnValue = Fifo_CPUWritePointer; //really writes in 32-byte chunks
// Monk's gcube does some crazy align trickery here.
return;
case PI_RESET_CODE:
_uReturnValue = 0x80000000;
INFO_LOG(PROCESSORINTERFACE, "read reset code, 0x%08x", m_ResetCode);
_uReturnValue = m_ResetCode;
return;
case PI_MB_REV:
_uReturnValue = 0x20000000; // HW2 production board
INFO_LOG(PROCESSORINTERFACE, "read board rev, 0x%08x", m_MBRev);
_uReturnValue = m_MBRev;
return;
default:
ERROR_LOG(PERIPHERALINTERFACE,"!!!!Unknown write!!!! 0x%08x", _iAddress);
ERROR_LOG(PROCESSORINTERFACE, "!!!!Unknown write!!!! 0x%08x", _iAddress);
break;
}
_uReturnValue = 0xAFFE0000;
}
void CPeripheralInterface::Write32(const u32 _uValue, const u32 _iAddress)
void Write32(const u32 _uValue, const u32 _iAddress)
{
INFO_LOG(PERIPHERALINTERFACE, "(w32) 0x%08x @ 0x%08x", _uValue, _iAddress);
//INFO_LOG(PROCESSORINTERFACE, "(w32) 0x%08x @ 0x%08x", _uValue, _iAddress);
switch(_iAddress & 0xFFF)
{
case PI_INTERRUPT_CAUSE:
m_InterruptCause &= ~_uValue; //writes turns them off
m_InterruptCause &= ~_uValue; // writes turn them off
UpdateException();
return;
case PI_INTERRUPT_MASK:
m_InterruptMask = _uValue;
DEBUG_LOG(PERIPHERALINTERFACE,"New Interrupt mask: %08x",m_InterruptMask);
DEBUG_LOG(PROCESSORINTERFACE,"New Interrupt mask: %08x", m_InterruptMask);
UpdateException();
return;
case PI_FIFO_BASE:
Fifo_CPUBase = _uValue & 0xFFFFFFE0;
DEBUG_LOG(PERIPHERALINTERFACE,"Fifo base = %08x", _uValue);
DEBUG_LOG(PROCESSORINTERFACE,"Fifo base = %08x", _uValue);
break;
case PI_FIFO_END:
Fifo_CPUEnd = _uValue & 0xFFFFFFE0;
DEBUG_LOG(PERIPHERALINTERFACE,"Fifo end = %08x", _uValue);
DEBUG_LOG(PROCESSORINTERFACE,"Fifo end = %08x", _uValue);
break;
case PI_FIFO_WPTR:
Fifo_CPUWritePointer = _uValue & 0xFFFFFFE0;
DEBUG_LOG(PERIPHERALINTERFACE,"Fifo writeptr = %08x", _uValue);
DEBUG_LOG(PROCESSORINTERFACE,"Fifo writeptr = %08x", _uValue);
break;
case PI_FIFO_RESET:
// Fifo_CPUWritePointer = Fifo_CPUBase; ??
// PanicAlert("Unknown write to PI_FIFO_RESET (%08x)", _uValue);
//Fifo_CPUWritePointer = Fifo_CPUBase; ??
//PanicAlert("Unknown write to PI_FIFO_RESET (%08x)", _uValue);
WARN_LOG(PROCESSORINTERFACE, "Fifo reset (%08x)", _uValue);
break;
case PI_RESET_CODE:
{
INFO_LOG(PERIPHERALINTERFACE,"PI Reset = %08x ???", _uValue);
if ((_uValue != 0x80000001) && (_uValue != 0x80000005)) // DVDLowReset
{
switch (_uValue) {
case 3:
PanicAlert("The game wants to go to memory card manager. BIOS is being HLE:d - so we can't do that.\n");
break;
default:
_dbg_assert_msg_(PERIPHERALINTERFACE,0,"The game wants to reset the machine. PI_RESET_CODE: (%08x)", _uValue);
break;
}
}
}
NOTICE_LOG(PROCESSORINTERFACE, "Write %08x to PI_RESET_CODE", _uValue);
// (shuffle2) TODO :)
break;
default:
ERROR_LOG(PERIPHERALINTERFACE,"!!!!Unknown PI write!!!! 0x%08x", _iAddress);
ERROR_LOG(PROCESSORINTERFACE,"!!!!Unknown PI write!!!! 0x%08x", _iAddress);
PanicAlert("Unknown write to PI: %08x", _iAddress);
break;
}
}
void CPeripheralInterface::UpdateException()
void UpdateException()
{
if ((m_InterruptCause & m_InterruptMask) != 0)
PowerPC::ppcState.Exceptions |= EXCEPTION_EXTERNAL_INT;
@@ -170,7 +198,7 @@ void CPeripheralInterface::UpdateException()
PowerPC::ppcState.Exceptions &= ~EXCEPTION_EXTERNAL_INT;
}
const char *CPeripheralInterface::Debug_GetInterruptName(InterruptCause _causemask)
static const char *Debug_GetInterruptName(InterruptCause _causemask)
{
switch (_causemask)
{
@@ -190,23 +218,22 @@ const char *CPeripheralInterface::Debug_GetInterruptName(InterruptCause _causema
case INT_CAUSE_WII_IPC: return "INT_CAUSE_WII_IPC";
case INT_CAUSE_HSP: return "INT_CAUSE_HSP";
case INT_CAUSE_RST_BUTTON: return "INT_CAUSE_RST_BUTTON";
default: return "!!! ERROR-unknown Interrupt !!!";
}
return "!!! ERROR-unknown Interrupt !!!";
}
void CPeripheralInterface::SetInterrupt(InterruptCause _causemask, bool _bSet)
void SetInterrupt(InterruptCause _causemask, bool _bSet)
{
//TODO(ector): add sanity check that current thread id is cpu thread
// TODO(ector): add sanity check that current thread id is cpu thread
if (_bSet && !(m_InterruptCause & (u32)_causemask))
{
INFO_LOG(PERIPHERALINTERFACE, "Setting Interrupt %s (%s)",Debug_GetInterruptName(_causemask), "set");
DEBUG_LOG(PROCESSORINTERFACE, "Setting Interrupt %s (%s)",Debug_GetInterruptName(_causemask), "set");
}
if (!_bSet && (m_InterruptCause & (u32)_causemask))
{
INFO_LOG(PERIPHERALINTERFACE, "Setting Interrupt %s (%s)",Debug_GetInterruptName(_causemask), "clear");
DEBUG_LOG(PROCESSORINTERFACE, "Setting Interrupt %s (%s)",Debug_GetInterruptName(_causemask), "clear");
}
if (_bSet)
@@ -218,7 +245,7 @@ void CPeripheralInterface::SetInterrupt(InterruptCause _causemask, bool _bSet)
UpdateException();
}
void CPeripheralInterface::SetResetButton(bool _bSet)
void SetResetButton(bool _bSet)
{
if (_bSet)
m_InterruptCause &= ~INT_CAUSE_RST_BUTTON;
@@ -226,3 +253,15 @@ void CPeripheralInterface::SetResetButton(bool _bSet)
m_InterruptCause |= INT_CAUSE_RST_BUTTON;
}
void ToggleResetButtonCallback(u64 userdata, int cyclesLate)
{
SetResetButton(!!userdata);
}
void ResetButton_Tap()
{
CoreTiming::ScheduleEvent_Threadsafe(0, toggleResetButton, true);
CoreTiming::ScheduleEvent_Threadsafe(243000000, toggleResetButton, false);
}
} // namespace ProcessorInterface
@@ -0,0 +1,73 @@
// Copyright (C) 2003 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 _PROCESSORINTERFACE_H
#define _PROCESSORINTERFACE_H
#include "Common.h"
class PointerWrap;
// Holds statuses of things like the write gatherer used for fifos, and interrupts from various sources
namespace ProcessorInterface
{
enum InterruptCause
{
INT_CAUSE_ERROR = 0x1, // YAGCD says: GP runtime error
INT_CAUSE_RSW = 0x2, // Reset Switch
INT_CAUSE_DI = 0x4, // DVD interrupt
INT_CAUSE_SI = 0x8, // Serial interface
INT_CAUSE_EXI = 0x10, // Expansion interface
INT_CAUSE_AUDIO = 0x20, // Audio Interface Streaming
INT_CAUSE_DSP = 0x40, // DSP interface
INT_CAUSE_MEMORY = 0x80, // Memory interface
INT_CAUSE_VI = 0x100, // Video interface
INT_CAUSE_PE_TOKEN = 0x200, // GP Token
INT_CAUSE_PE_FINISH = 0x400, // GP Finished
INT_CAUSE_CP = 0x800, // Command Fifo
INT_CAUSE_DEBUG = 0x1000, // Debugger (from devkit)
INT_CAUSE_HSP = 0x2000, // High Speed Port
INT_CAUSE_WII_IPC = 0x4000, // Wii IPC
INT_CAUSE_RST_BUTTON = 0x10000 // ResetButtonState (1 = unpressed, 0 = pressed) (shuffle2) beh, YAGCD says the inverse...
};
extern volatile u32 m_InterruptCause;
extern volatile u32 m_InterruptMask;
extern u32 Fifo_CPUBase;
extern u32 Fifo_CPUEnd;
extern u32 Fifo_CPUWritePointer;
void Init();
void DoState(PointerWrap &p);
void Read32(u32& _uReturnValue, const u32 _iAddress);
void Write32(const u32 _iValue, const u32 _iAddress);
inline u32 GetMask() { return m_InterruptMask; }
inline u32 GetCause() { return m_InterruptCause; }
void SetInterrupt(InterruptCause _causemask, bool _bSet=true);
// Thread-safe func which sets and clears reset button state automagically
void ResetButton_Tap();
} // namespace ProcessorInterface
#endif

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