beetle-pce-fast-libretro/mednafen/psx/debug.cpp
2013-09-08 13:41:01 +02:00

677 lines
17 KiB
C++

/* Mednafen - Multi-system Emulator
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "psx.h"
#include "timer.h"
#include "cdc.h"
#include "spu.h"
namespace MDFN_IEN_PSX
{
extern PS_GPU *GPU;
extern PS_SPU *SPU;
static void (*CPUHook)(uint32) = NULL;
static void (*BPCallB)(uint32 PC) = NULL;
struct PSX_BPOINT
{
uint32 A[2];
int type;
};
static std::vector<PSX_BPOINT> BreakPointsPC, BreakPointsRead, BreakPointsWrite;
static bool FoundBPoint;
static int BTIndex = 0;
struct BTEntry
{
uint32 from;
uint32 to;
uint32 branch_count;
bool exception;
};
#define NUMBT 24
static BTEntry BTEntries[NUMBT];
void DBG_Break(void)
{
FoundBPoint = true;
}
static void AddBranchTrace(uint32 from, uint32 to, bool exception)
{
BTEntry *prevbt = &BTEntries[(BTIndex + NUMBT - 1) % NUMBT];
//if(BTEntries[(BTIndex - 1) & 0xF] == PC) return;
if(prevbt->from == from && prevbt->to == to && prevbt->exception == exception && prevbt->branch_count < 0xFFFFFFFF)
prevbt->branch_count++;
else
{
BTEntries[BTIndex].from = from;
BTEntries[BTIndex].to = to;
BTEntries[BTIndex].exception = exception;
BTEntries[BTIndex].branch_count = 1;
BTIndex = (BTIndex + 1) % NUMBT;
}
}
static std::vector<BranchTraceResult> GetBranchTrace(void)
{
BranchTraceResult tmp;
std::vector<BranchTraceResult> ret;
for(int x = 0; x < NUMBT; x++)
{
const BTEntry *bt = &BTEntries[(x + BTIndex) % NUMBT];
tmp.count = bt->branch_count;
trio_snprintf(tmp.from, sizeof(tmp.from), "%08x", bt->from);
trio_snprintf(tmp.to, sizeof(tmp.to), "%08x", bt->to);
trio_snprintf(tmp.code, sizeof(tmp.code), "%s", bt->exception ? "e" : "");
ret.push_back(tmp);
}
return(ret);
}
void CheckCPUBPCallB(bool write, uint32 address, unsigned int len)
{
std::vector<PSX_BPOINT>::iterator bpit;
std::vector<PSX_BPOINT>::iterator bpit_end;
if(write)
{
bpit = BreakPointsWrite.begin();
bpit_end = BreakPointsWrite.end();
}
else
{
bpit = BreakPointsRead.begin();
bpit_end = BreakPointsRead.end();
}
while(bpit != bpit_end)
{
if(address >= bpit->A[0] && address <= bpit->A[1])
{
FoundBPoint = true;
break;
}
bpit++;
}
}
static void CPUHandler(uint32 PC)
{
std::vector<PSX_BPOINT>::iterator bpit;
if(PC == 0xB0 && CPU->GetRegister(PS_CPU::GSREG_GPR + 9, NULL, 0) == 0x3D)
{
putchar(CPU->GetRegister(PS_CPU::GSREG_GPR + 4, NULL, 0));
//exit(1);
//puts((const char *)&MainRAM[CPU->GetRegister(PS_CPU::GSREG_GPR + 4, NULL, 0) & 0x1FFFFF]);
}
// FIXME/TODO: Call ForceEventUpdates() somewhere
for(bpit = BreakPointsPC.begin(); bpit != BreakPointsPC.end(); bpit++)
{
if(PC >= bpit->A[0] && PC <= bpit->A[1])
{
FoundBPoint = true;
break;
}
}
CPU->CheckBreakpoints(CheckCPUBPCallB, CPU->PeekMem32(PC));
if(FoundBPoint)
{
BPCallB(PC);
FoundBPoint = 0;
}
if(CPUHook)
CPUHook(PC);
}
static void RedoCPUHook(void)
{
const bool HappyTest = BreakPointsPC.size() || BreakPointsRead.size() || BreakPointsWrite.size();
void (*cpuh)(uint32);
cpuh = HappyTest ? CPUHandler : CPUHook;
CPU->SetCPUHook(cpuh, cpuh ? AddBranchTrace : NULL);
}
static void FlushBreakPoints(int type)
{
if(type == BPOINT_READ)
BreakPointsRead.clear();
else if(type == BPOINT_WRITE)
BreakPointsWrite.clear();
else if(type == BPOINT_PC)
BreakPointsPC.clear();
RedoCPUHook();
}
static void AddBreakPoint(int type, unsigned int A1, unsigned int A2, bool logical)
{
PSX_BPOINT tmp;
tmp.A[0] = A1;
tmp.A[1] = A2;
tmp.type = type;
if(type == BPOINT_READ)
BreakPointsRead.push_back(tmp);
else if(type == BPOINT_WRITE)
BreakPointsWrite.push_back(tmp);
else if(type == BPOINT_PC)
BreakPointsPC.push_back(tmp);
RedoCPUHook();
}
static void SetCPUCallback(void (*callb)(uint32 PC))
{
CPUHook = callb;
RedoCPUHook();
}
static void SetBPCallback(void (*callb)(uint32 PC))
{
BPCallB = callb;
}
static void GetAddressSpaceBytes(const char *name, uint32 Address, uint32 Length, uint8 *Buffer)
{
if(!strcmp(name, "cpu"))
{
while(Length--)
{
Address &= 0xFFFFFFFF;
*Buffer = CPU->PeekMem8(Address);
Address++;
Buffer++;
}
}
else if(!strcmp(name, "ram"))
{
while(Length--)
{
Address &= 0x1FFFFF;
*Buffer = CPU->PeekMem8(Address);
Address++;
Buffer++;
}
}
else if(!strcmp(name, "spu"))
{
while(Length--)
{
Address &= 0x7FFFF;
*Buffer = SPU->PeekSPURAM(Address >> 1) >> ((Address & 1) * 8);
Address++;
Buffer++;
}
}
else if(!strcmp(name, "gpu"))
{
while(Length--)
{
Address &= 0xFFFFF;
*Buffer = GPU->PeekRAM(Address >> 1) >> ((Address & 1) * 8);
Address++;
Buffer++;
}
}
}
static void PutAddressSpaceBytes(const char *name, uint32 Address, uint32 Length, uint32 Granularity, bool hl, const uint8 *Buffer)
{
if(!strcmp(name, "cpu"))
{
while(Length--)
{
pscpu_timestamp_t dummy = 0;
Address &= 0xFFFFFFFF;
// TODO
PSX_MemWrite8(dummy, Address, *Buffer);
Address++;
Buffer++;
}
}
else if(!strcmp(name, "gpu"))
{
while(Length--)
{
Address &= 0xFFFFF;
uint16 peeko = GPU->PeekRAM(Address >> 1);
GPU->PokeRAM(Address >> 1, (*Buffer << ((Address & 1) * 8)) | (peeko & (0xFF00 >> ((Address & 1) * 8))) );
Address++;
Buffer++;
}
}
else if(!strcmp(name, "spu"))
{
while(Length--)
{
Address &= 0x7FFFF;
uint16 peeko = SPU->PeekSPURAM(Address >> 1);
SPU->PokeSPURAM(Address >> 1, (*Buffer << ((Address & 1) * 8)) | (peeko & (0xFF00 >> ((Address & 1) * 8))) );
Address++;
Buffer++;
}
}
}
static uint32 MemPeek(uint32 A, unsigned int bsize, bool hl, bool logical)
{
uint32 ret = 0;
for(unsigned int i = 0; i < bsize; i++)
ret |= CPU->PeekMem8(A + i) << (i * 8);
return(ret);
}
static void Disassemble(uint32 &A, uint32 SpecialA, char *TextBuf)
{
assert(!(A & 0x3));
uint32 instr = CPU->PeekMem32(A);
CPU->PeekCheckICache(A, &instr);
strncpy(TextBuf, DisassembleMIPS(A, instr).c_str(), 256);
TextBuf[255] = 0;
// trio_snprintf(TextBuf, 256, "0x%08x", instr);
A += 4;
}
static MDFN_Surface *GfxDecode_Buf = NULL;
static int GfxDecode_Line = -1;
static int GfxDecode_Layer = 0;
static int GfxDecode_Scroll = 0;
static int GfxDecode_PBN = 0;
static void DoGfxDecode(void)
{
unsigned tp_w, tp_h;
tp_w = 256;
tp_h = 256;
if(GfxDecode_Buf)
{
for(int sy = 0; sy < GfxDecode_Buf->h; sy++)
{
for(int sx = 0; sx < GfxDecode_Buf->w; sx++)
{
unsigned fb_x = ((sx % GfxDecode_Buf->w) + ((sy + GfxDecode_Scroll) / GfxDecode_Buf->w * GfxDecode_Buf->w)) & 1023;
unsigned fb_y = (((sy + GfxDecode_Scroll) % GfxDecode_Buf->w) + ((((sx % GfxDecode_Buf->w) + ((sy + GfxDecode_Scroll) / GfxDecode_Buf->w * GfxDecode_Buf->w)) / 1024) * 256)) & 511;
uint16 pixel = GPU->PeekRAM(fb_y * 1024 + fb_x);
GfxDecode_Buf->pixels[(sy * GfxDecode_Buf->w * 3) + sx] = GfxDecode_Buf->MakeColor(((pixel >> 0) & 0x1F) * 255 / 31,
((pixel >> 5) & 0x1F) * 255 / 31,
((pixel >> 10) & 0x1F) * 255 / 31, 0xFF);
}
}
}
}
void DBG_GPUScanlineHook(unsigned scanline)
{
if((int)scanline == GfxDecode_Line)
{
DoGfxDecode();
}
}
static void SetGraphicsDecode(MDFN_Surface *surface, int line, int which, int xscroll, int yscroll, int pbn)
{
GfxDecode_Buf = surface;
GfxDecode_Line = line;
GfxDecode_Layer = which;
GfxDecode_Scroll = yscroll;
GfxDecode_PBN = pbn;
if(GfxDecode_Buf && GfxDecode_Line == -1)
DoGfxDecode();
}
DebuggerInfoStruct PSX_DBGInfo =
{
"shift_jis",
4, // Max instruction byte size
4, // Instruction alignment(bytes)
32, // Logical address bits
32, // Physical address bits
0x00000000, // Default watch addr
~0U, // ZP addr
MemPeek,
Disassemble,
NULL,
NULL, //ForceIRQ,
NULL, //NESDBG_GetVector,
FlushBreakPoints,
AddBreakPoint,
SetCPUCallback,
SetBPCallback,
GetBranchTrace,
SetGraphicsDecode,
NULL, //PCFXDBG_SetLogFunc,
};
static RegType Regs_Misc[] =
{
{ TIMER_GSREG_COUNTER0, "COUNTER0", "Counter 0", 2 },
{ TIMER_GSREG_MODE0, "MODE0", "Mode 0", 2 },
{ TIMER_GSREG_TARGET0, "TARGET0", "Target 0", 2 },
{ 0, "------", "", 0xFFFF },
{ TIMER_GSREG_COUNTER1, "COUNTER1", "Counter 1", 2 },
{ TIMER_GSREG_MODE1, "MODE1", "Mode 1", 2 },
{ TIMER_GSREG_TARGET1, "TARGET1", "Target 1", 2 },
{ 0, "------", "", 0xFFFF },
{ TIMER_GSREG_COUNTER2, "COUNTER2", "Counter 2", 2 },
{ TIMER_GSREG_MODE2, "MODE2", "Mode 2", 2 },
{ TIMER_GSREG_TARGET2, "TARGET2", "Target 2", 2 },
{ 0, "------", "", 0xFFFF },
{ 0, "------", "", 0xFFFF },
{ 0x10000 | IRQ_GSREG_ASSERTED, "ASSERTED", "IRQ Asserted", 2 },
{ 0x10000 | IRQ_GSREG_STATUS, "STATUS", "IRQ Status", 2 },
{ 0x10000 | IRQ_GSREG_MASK, "MASK", "IRQ Mask", 2 },
{ 0, "", "", 0 }
};
static uint32 GetRegister_Misc(const unsigned int id, char *special, const uint32 special_len)
{
if(id & 0x10000)
return(IRQ_GetRegister(id & 0xFFFF, special, special_len));
else
return(TIMER_GetRegister(id & 0xFFFF, special, special_len));
}
static void SetRegister_Misc(const unsigned int id, uint32 value)
{
if(id & 0x10000)
IRQ_SetRegister(id & 0xFFFF, value);
else
TIMER_SetRegister(id & 0xFFFF, value);
}
static RegGroupType MiscRegsGroup =
{
NULL,
Regs_Misc,
GetRegister_Misc,
SetRegister_Misc
};
static RegType Regs_SPU[] =
{
{ PS_SPU::GSREG_SPUCONTROL, "SPUCTRL", "SPU Control", 2 },
{ PS_SPU::GSREG_FM_ON, "FMOn", "FM Enable", 3 },
{ PS_SPU::GSREG_NOISE_ON, "NoiseOn", "Noise Enable", 3 },
{ PS_SPU::GSREG_REVERB_ON, "ReverbOn", "Reverb Enable", 3 },
{ PS_SPU::GSREG_CDVOL_L, "CDVolL", "CD Volume Left", 2 },
{ PS_SPU::GSREG_CDVOL_R, "CDVolR", "CD Volume Right", 2 },
{ PS_SPU::GSREG_DRYVOL_CTRL_L, "DryVolCL", "Dry Volume Control Left", 2 },
{ PS_SPU::GSREG_DRYVOL_CTRL_R, "DryVolCR", "Dry Volume Control Right", 2 },
{ PS_SPU::GSREG_DRYVOL_L, "DryVolL", "Dry Volume Left", 2 },
{ PS_SPU::GSREG_DRYVOL_R, "DryVolR", "Dry Volume Right", 2 },
{ PS_SPU::GSREG_WETVOL_L, "WetVolL", "Wet Volume Left", 2 },
{ PS_SPU::GSREG_WETVOL_R, "WetVolR", "Wet Volume Right", 2 },
{ PS_SPU::GSREG_RWADDR, "RWAddr", "SPURAM Read/Write Address", 3 },
{ PS_SPU::GSREG_IRQADDR, "IRQAddr", "IRQ Compare Address", 3 },
{ PS_SPU::GSREG_REVERBWA, "ReverbWA", "Reverb Work Area(Raw)", 2 },
{ PS_SPU::GSREG_VOICEON, "VoiceOn", "Voice On", 3 },
{ PS_SPU::GSREG_VOICEOFF, "VoiceOff", "Voice Off", 3 },
{ PS_SPU::GSREG_BLOCKEND, "BlockEnd", "Block End", 3 },
{ 0, "------", "", 0xFFFF },
{ PS_SPU::GSREG_FB_SRC_A, "FB_SRC_A", "", 2 },
{ PS_SPU::GSREG_FB_SRC_B, "FB_SRC_B", "", 2 },
{ PS_SPU::GSREG_IIR_ALPHA, "IIR_ALPHA", "", 2 },
{ PS_SPU::GSREG_ACC_COEF_A, "ACC_COEF_A", "", 2 },
{ PS_SPU::GSREG_ACC_COEF_B, "ACC_COEF_B", "", 2 },
{ PS_SPU::GSREG_ACC_COEF_C, "ACC_COEF_C", "", 2 },
{ PS_SPU::GSREG_ACC_COEF_D, "ACC_COEF_D", "", 2 },
{ PS_SPU::GSREG_IIR_COEF, "IIR_COEF", "", 2 },
{ PS_SPU::GSREG_FB_ALPHA, "FB_ALPHA", "", 2 },
{ PS_SPU::GSREG_FB_X, "FB_X", "", 2 },
{ PS_SPU::GSREG_IIR_DEST_A0, "IIR_DEST_A0", "", 2 },
{ PS_SPU::GSREG_IIR_DEST_A1, "IIR_DEST_A1", "", 2 },
{ PS_SPU::GSREG_ACC_SRC_A0, "ACC_SRC_A0", "", 2 },
{ PS_SPU::GSREG_ACC_SRC_A1, "ACC_SRC_A1", "", 2 },
{ PS_SPU::GSREG_ACC_SRC_B0, "ACC_SRC_B0", "", 2 },
{ PS_SPU::GSREG_ACC_SRC_B1, "ACC_SRC_B1", "", 2 },
{ PS_SPU::GSREG_IIR_SRC_A0, "IIR_SRC_A0", "", 2 },
{ PS_SPU::GSREG_IIR_SRC_A1, "IIR_SRC_A1", "", 2 },
{ PS_SPU::GSREG_IIR_DEST_B0, "IIR_DEST_B0", "", 2 },
{ PS_SPU::GSREG_IIR_DEST_B1, "IIR_DEST_B1", "", 2 },
{ PS_SPU::GSREG_ACC_SRC_C0, "ACC_SRC_C0", "", 2 },
{ PS_SPU::GSREG_ACC_SRC_C1, "ACC_SRC_C1", "", 2 },
{ PS_SPU::GSREG_ACC_SRC_D0, "ACC_SRC_D0", "", 2 },
{ PS_SPU::GSREG_ACC_SRC_D1, "ACC_SRC_D1", "", 2 },
{ PS_SPU::GSREG_IIR_SRC_B1, "IIR_SRC_B1", "", 2 },
{ PS_SPU::GSREG_IIR_SRC_B0, "IIR_SRC_B0", "", 2 },
{ PS_SPU::GSREG_MIX_DEST_A0, "MIX_DEST_A0", "", 2 },
{ PS_SPU::GSREG_MIX_DEST_A1, "MIX_DEST_A1", "", 2 },
{ PS_SPU::GSREG_MIX_DEST_B0, "MIX_DEST_B0", "", 2 },
{ PS_SPU::GSREG_MIX_DEST_B1, "MIX_DEST_B1", "", 2 },
{ PS_SPU::GSREG_IN_COEF_L, "IN_COEF_L", "", 2 },
{ PS_SPU::GSREG_IN_COEF_R, "IN_COEF_R", "", 2 },
{ 0, "", "", 0 },
};
#define VOICE_HELPER(v) \
{ 0, "--V"#v"--", "", 0xFFFF }, \
{ PS_SPU:: GSREG_V0_VOL_CTRL_L + v * 256, "VolCL", "Volume Control Left", 2 }, \
{ PS_SPU:: GSREG_V0_VOL_CTRL_R + v * 256, "VolCR", "Volume Control Right", 2 }, \
{ PS_SPU:: GSREG_V0_VOL_L + v * 256, "VolL", "Volume Left", 2 }, \
{ PS_SPU:: GSREG_V0_VOL_R + v * 256, "VolR", "Volume Right", 2 }, \
{ PS_SPU:: GSREG_V0_PITCH + v * 256, "Pitch", "Pitch", 2 }, \
{ PS_SPU:: GSREG_V0_STARTADDR + v * 256, "SAddr", "Start Address", 3 }, \
{ PS_SPU:: GSREG_V0_ADSR_CTRL + v * 256, "ADSRCTRL", "ADSR Control", 4 }, \
{ PS_SPU:: GSREG_V0_ADSR_LEVEL + v * 256, "ADSRLev", "ADSR Level", 2 }, \
{ PS_SPU:: GSREG_V0_LOOP_ADDR + v * 256, "LAddr", "Loop Address", 3 }, \
{ PS_SPU:: GSREG_V0_READ_ADDR + v * 256, "RAddr", "Read Address", 3 }
static RegType Regs_SPU_Voices[] =
{
#if 1
VOICE_HELPER(0),
VOICE_HELPER(1),
VOICE_HELPER(2),
VOICE_HELPER(3),
#else
VOICE_HELPER(9),
VOICE_HELPER(12),
VOICE_HELPER(17),
VOICE_HELPER(22),
//VOICE_HELPER(20),
//VOICE_HELPER(21),
//VOICE_HELPER(22),
//VOICE_HELPER(23),
#endif
{ 0, "", "", 0 },
};
static uint32 GetRegister_SPU(const unsigned int id, char *special, const uint32 special_len)
{
return(SPU->GetRegister(id, special, special_len));
}
static void SetRegister_SPU(const unsigned int id, uint32 value)
{
SPU->SetRegister(id, value);
}
static RegGroupType SPURegsGroup =
{
NULL,
Regs_SPU,
GetRegister_SPU,
SetRegister_SPU
};
static RegGroupType SPUVoicesRegsGroup =
{
NULL,
Regs_SPU_Voices,
GetRegister_SPU,
SetRegister_SPU
};
static RegType Regs_CPU[] =
{
{ PS_CPU::GSREG_PC, "PC", "PC", 4 },
{ PS_CPU::GSREG_PC_NEXT, "NPC", "Next PC", 4 },
{ PS_CPU::GSREG_IN_BD_SLOT, "INBD", "In Branch Delay Slot", 1 },
{ 0, "------", "", 0xFFFF },
{ PS_CPU::GSREG_GPR + 1, "at", "Assembler Temporary", 4 },
{ PS_CPU::GSREG_GPR + 2, "v0", "Return Value 0", 4 },
{ PS_CPU::GSREG_GPR + 3, "v1", "Return Value 1", 4 },
{ PS_CPU::GSREG_GPR + 4, "a0", "Argument 0", 4 },
{ PS_CPU::GSREG_GPR + 5, "a1", "Argument 1", 4 },
{ PS_CPU::GSREG_GPR + 6, "a2", "Argument 2", 4 },
{ PS_CPU::GSREG_GPR + 7, "a3", "Argument 3", 4 },
{ PS_CPU::GSREG_GPR + 8, "t0", "Temporary 0", 4 },
{ PS_CPU::GSREG_GPR + 9, "t1", "Temporary 1", 4 },
{ PS_CPU::GSREG_GPR + 10, "t2", "Temporary 2", 4 },
{ PS_CPU::GSREG_GPR + 11, "t3", "Temporary 3", 4 },
{ PS_CPU::GSREG_GPR + 12, "t4", "Temporary 4", 4 },
{ PS_CPU::GSREG_GPR + 13, "t5", "Temporary 5", 4 },
{ PS_CPU::GSREG_GPR + 14, "t6", "Temporary 6", 4 },
{ PS_CPU::GSREG_GPR + 15, "t7", "Temporary 7", 4 },
{ PS_CPU::GSREG_GPR + 16, "s0", "Subroutine Reg Var 0", 4 },
{ PS_CPU::GSREG_GPR + 17, "s1", "Subroutine Reg Var 1", 4 },
{ PS_CPU::GSREG_GPR + 18, "s2", "Subroutine Reg Var 2", 4 },
{ PS_CPU::GSREG_GPR + 19, "s3", "Subroutine Reg Var 3", 4 },
{ PS_CPU::GSREG_GPR + 20, "s4", "Subroutine Reg Var 4", 4 },
{ PS_CPU::GSREG_GPR + 21, "s5", "Subroutine Reg Var 5", 4 },
{ PS_CPU::GSREG_GPR + 22, "s6", "Subroutine Reg Var 6", 4 },
{ PS_CPU::GSREG_GPR + 23, "s7", "Subroutine Reg Var 7", 4 },
{ PS_CPU::GSREG_GPR + 24, "t8", "Temporary 8", 4 },
{ PS_CPU::GSREG_GPR + 25, "t9", "Temporary 9", 4 },
{ PS_CPU::GSREG_GPR + 26, "k0", "Interrupt/Trap Handler Reg 0", 4 },
{ PS_CPU::GSREG_GPR + 27, "k1", "Interrupt/Trap Handler Reg 1", 4 },
{ PS_CPU::GSREG_GPR + 28, "gp", "Global Pointer", 4 },
{ PS_CPU::GSREG_GPR + 29, "sp", "Stack Pointer", 4 },
{ PS_CPU::GSREG_GPR + 30, "s8", "Subroutine Reg Var 8/Frame Pointer", 4 },
{ PS_CPU::GSREG_GPR + 31, "ra", "Return Address", 4 },
{ 0, "------", "", 0xFFFF },
{ PS_CPU::GSREG_SR, "SR", "Status Register", 4 },
{ PS_CPU::GSREG_CAUSE, "CAU","Cause Register", 4 },
{ PS_CPU::GSREG_EPC, "EPC", "EPC Register", 4 },
{ 0, "", "", 0 }
};
static uint32 GetRegister_CPU(const unsigned int id, char *special, const uint32 special_len)
{
return(CPU->GetRegister(id, special, special_len));
}
static void SetRegister_CPU(const unsigned int id, uint32 value)
{
CPU->SetRegister(id, value);
}
static RegGroupType CPURegsGroup =
{
NULL,
Regs_CPU,
GetRegister_CPU,
SetRegister_CPU
};
bool DBG_Init(void)
{
CPUHook = NULL;
BPCallB = NULL;
FoundBPoint = false;
MDFNDBG_AddRegGroup(&CPURegsGroup);
MDFNDBG_AddRegGroup(&MiscRegsGroup);
MDFNDBG_AddRegGroup(&SPURegsGroup);
MDFNDBG_AddRegGroup(&SPUVoicesRegsGroup);
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "cpu", "CPU Physical", 32);
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "ram", "CPU Main Ram", 21);
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "spu", "SPU RAM", 19);
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "gpu", "GPU RAM", 20);
return(true);
}
}