diff --git a/output/dll/octoshock.dll b/output/dll/octoshock.dll index b4137624b0..282dfe4a7d 100644 Binary files a/output/dll/octoshock.dll and b/output/dll/octoshock.dll differ diff --git a/psx/octoshock/psx/cpu.cpp b/psx/octoshock/psx/cpu.cpp index 747b34141e..c7c20ec732 100644 --- a/psx/octoshock/psx/cpu.cpp +++ b/psx/octoshock/psx/cpu.cpp @@ -218,6 +218,22 @@ INLINE T PS_CPU::PeekMemory(uint32 address) return(ret); } +template +void PS_CPU::PokeMemory(uint32 address, T value) +{ + address &= addr_mask[address >> 29]; + + if(address >= 0x1F800000 && address <= 0x1F8003FF) + return ScratchRAM.Write(address & 0x3FF, value); + + if(sizeof(T) == 1) + PSX_MemPoke8(address, value); + else if(sizeof(T) == 2) + PSX_MemPoke16(address, value); + else + PSX_MemPoke32(address, value); +} + template INLINE T PS_CPU::ReadMemory(pscpu_timestamp_t ×tamp, uint32 address, bool DS24, bool LWC_timing) { @@ -2381,7 +2397,21 @@ uint32 PS_CPU::PeekMem32(uint32 A) { return PeekMemory(A); } - + +void PS_CPU::PokeMem8(uint32 A, uint8 V) +{ + PokeMemory(A, V); +} + +void PS_CPU::PokeMem16(uint32 A, uint16 V) +{ + PokeMemory(A, V); +} + +void PS_CPU::PokeMem32(uint32 A, uint32 V) +{ + PokeMemory(A, V); +} #undef BEGIN_OPF #undef END_OPF diff --git a/psx/octoshock/psx/cpu.h b/psx/octoshock/psx/cpu.h index 7de9ed3532..e6bfe3b5a1 100644 --- a/psx/octoshock/psx/cpu.h +++ b/psx/octoshock/psx/cpu.h @@ -214,6 +214,7 @@ class PS_CPU template pscpu_timestamp_t RunReal(pscpu_timestamp_t timestamp_in) NO_INLINE; template T PeekMemory(uint32 address) MDFN_COLD; + template void PokeMemory(uint32 address, T value) MDFN_COLD; template T ReadMemory(pscpu_timestamp_t ×tamp, uint32 address, bool DS24 = false, bool LWC_timing = false); template void WriteMemory(pscpu_timestamp_t ×tamp, uint32 address, uint32 value, bool DS24 = false); @@ -243,9 +244,15 @@ class PS_CPU uint32 GetRegister(unsigned int which, char *special, const uint32 special_len); void SetRegister(unsigned int which, uint32 value); bool PeekCheckICache(uint32 PC, uint32 *iw); + uint8 PeekMem8(uint32 A); uint16 PeekMem16(uint32 A); uint32 PeekMem32(uint32 A); + + void PokeMem8(uint32 A, uint8 V); + void PokeMem16(uint32 A, uint16 V); + void PokeMem32(uint32 A, uint32 V); + private: void (*CPUHook)(const pscpu_timestamp_t timestamp, uint32 pc); void (*ADDBT)(uint32 from, uint32 to, bool exception); diff --git a/psx/octoshock/psx/debug.cpp b/psx/octoshock/psx/debug.cpp index 9909855933..ecf4e1784f 100644 --- a/psx/octoshock/psx/debug.cpp +++ b/psx/octoshock/psx/debug.cpp @@ -1,674 +1,680 @@ -/* 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 RedoCPUHook(void); - -static void (*CPUHook)(uint32, bool) = NULL; -static bool CPUHookContinuous = false; - -struct PSX_BPOINT -{ - uint32 A[2]; - int type; -}; - -static std::vector BreakPointsPC, BreakPointsRead, BreakPointsWrite; -static bool FoundBPoint; - -static bool BTEnabled; -static int BTIndex; - -struct BTEntry -{ - uint32 from; - uint32 to; - uint32 branch_count; - bool exception; - bool valid; -}; - -#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->valid) - prevbt->branch_count++; - else - { - BTEntries[BTIndex].from = from; - BTEntries[BTIndex].to = to; - BTEntries[BTIndex].exception = exception; - BTEntries[BTIndex].branch_count = 1; - BTEntries[BTIndex].valid = true; - - BTIndex = (BTIndex + 1) % NUMBT; - } -} - -static void EnableBranchTrace(bool enable) -{ - BTEnabled = enable; - if(!enable) - { - BTIndex = 0; - memset(BTEntries, 0, sizeof(BTEntries)); - } - RedoCPUHook(); -} - -static std::vector GetBranchTrace(void) -{ - BranchTraceResult tmp; - std::vector 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::iterator bpit; - std::vector::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(const pscpu_timestamp_t timestamp, uint32 PC) -{ - std::vector::iterator bpit; - - 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)); - - CPUHookContinuous |= FoundBPoint; - - if(CPUHookContinuous && CPUHook) - { - ForceEventUpdates(timestamp); - CPUHook(PC, FoundBPoint); - } - - FoundBPoint = false; -} - - -static void RedoCPUHook(void) -{ - const bool HappyTest = CPUHook || BreakPointsPC.size() || BreakPointsRead.size() || BreakPointsWrite.size(); - - CPU->SetCPUHook(HappyTest ? CPUHandler : NULL, BTEnabled ? 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, bool bpoint), bool continuous) -{ - CPUHook = callb; - CPUHookContinuous = continuous; - RedoCPUHook(); -} - -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) -{ - 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) * GfxDecode_Buf->w)) & 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, - EnableBranchTrace, - GetBranchTrace, - SetGraphicsDecode, - NULL, //PCFXDBG_SetLogFunc, -}; - -static RegType Regs_Misc[] = -{ - { TIMER_GSREG_COUNTER0, "COUNT0", "Counter 0", 2 }, - { TIMER_GSREG_MODE0, "MODE0", "Mode 0", 2 }, - { TIMER_GSREG_TARGET0, "TARGET0", "Target 0", 2 }, - - { 0, "------", "", 0xFFFF }, - - - { TIMER_GSREG_COUNTER1, "COUNT1", "Counter 1", 2 }, - { TIMER_GSREG_MODE1, "MODE1", "Mode 1", 2 }, - { TIMER_GSREG_TARGET1, "TARGET1", "Target 1", 2 }, - - { 0, "------", "", 0xFFFF }, - - { TIMER_GSREG_COUNTER2, "COUNT2", "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, "ASSERTD", "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_RVBVOL_L, "RvbVolL", "Reverb Volume Left", 2 }, - { PS_SPU::GSREG_RVBVOL_R, "RvbVolR", "Reverb Volume Right", 2 }, - - { PS_SPU::GSREG_MAINVOL_CTRL_L, "MainVolCL", "Main Volume Control Left", 2 }, - { PS_SPU::GSREG_MAINVOL_CTRL_R, "MainVolCR", "Main Volume Control Right", 2 }, - - { PS_SPU::GSREG_MAINVOL_L, "MainVolL", "Dry Volume Left", 2 }, - { PS_SPU::GSREG_MAINVOL_R, "MainVolR", "Dry 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_DST_A0", "", 2 }, - { PS_SPU::GSREG_IIR_DEST_A1, "IIR_DST_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_DST_B0", "", 2 }, - { PS_SPU::GSREG_IIR_DEST_B1, "IIR_DST_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_DST_A0", "", 2 }, - { PS_SPU::GSREG_MIX_DEST_A1, "MIX_DST_A1", "", 2 }, - { PS_SPU::GSREG_MIX_DEST_B0, "MIX_DST_B0", "", 2 }, - { PS_SPU::GSREG_MIX_DEST_B1, "MIX_DST_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; - CPUHookContinuous = false; - FoundBPoint = false; - - BTEnabled = false; - BTIndex = false; - memset(BTEntries, 0, sizeof(BTEntries)); - - 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); -} - - - -} - +/* 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 RedoCPUHook(void); + +static void (*CPUHook)(uint32, bool) = NULL; +static bool CPUHookContinuous = false; + +struct PSX_BPOINT +{ + uint32 A[2]; + int type; +}; + +static std::vector BreakPointsPC, BreakPointsRead, BreakPointsWrite; +static bool FoundBPoint; + +static bool BTEnabled; +static int BTIndex; + +struct BTEntry +{ + uint32 from; + uint32 to; + uint32 branch_count; + bool exception; + bool valid; +}; + +#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->valid) + prevbt->branch_count++; + else + { + BTEntries[BTIndex].from = from; + BTEntries[BTIndex].to = to; + BTEntries[BTIndex].exception = exception; + BTEntries[BTIndex].branch_count = 1; + BTEntries[BTIndex].valid = true; + + BTIndex = (BTIndex + 1) % NUMBT; + } +} + +static void EnableBranchTrace(bool enable) +{ + BTEnabled = enable; + if(!enable) + { + BTIndex = 0; + memset(BTEntries, 0, sizeof(BTEntries)); + } + RedoCPUHook(); +} + +static std::vector GetBranchTrace(void) +{ + BranchTraceResult tmp; + std::vector 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::iterator bpit; + std::vector::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(const pscpu_timestamp_t timestamp, uint32 PC) +{ + std::vector::iterator bpit; + + 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)); + + CPUHookContinuous |= FoundBPoint; + + if(CPUHookContinuous && CPUHook) + { + ForceEventUpdates(timestamp); + CPUHook(PC, FoundBPoint); + } + + FoundBPoint = false; +} + + +static void RedoCPUHook(void) +{ + const bool HappyTest = CPUHook || BreakPointsPC.size() || BreakPointsRead.size() || BreakPointsWrite.size(); + + CPU->SetCPUHook(HappyTest ? CPUHandler : NULL, BTEnabled ? 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, bool bpoint), bool continuous) +{ + CPUHook = callb; + CPUHookContinuous = continuous; + RedoCPUHook(); +} + +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--) + { + Address &= 0xFFFFFFFF; + CPU->PokeMem8(Address, *Buffer); + Address++; + Buffer++; + } + } + else if(!strcmp(name, "ram")) + { + while(Length--) + { + Address &= 0x1FFFFF; + CPU->PokeMem8(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) +{ + 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) * GfxDecode_Buf->w)) & 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, + EnableBranchTrace, + GetBranchTrace, + SetGraphicsDecode, + NULL, //PCFXDBG_SetLogFunc, +}; + +static RegType Regs_Misc[] = +{ + { TIMER_GSREG_COUNTER0, "COUNT0", "Counter 0", 2 }, + { TIMER_GSREG_MODE0, "MODE0", "Mode 0", 2 }, + { TIMER_GSREG_TARGET0, "TARGET0", "Target 0", 2 }, + + { 0, "------", "", 0xFFFF }, + + + { TIMER_GSREG_COUNTER1, "COUNT1", "Counter 1", 2 }, + { TIMER_GSREG_MODE1, "MODE1", "Mode 1", 2 }, + { TIMER_GSREG_TARGET1, "TARGET1", "Target 1", 2 }, + + { 0, "------", "", 0xFFFF }, + + { TIMER_GSREG_COUNTER2, "COUNT2", "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, "ASSERTD", "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_RVBVOL_L, "RvbVolL", "Reverb Volume Left", 2 }, + { PS_SPU::GSREG_RVBVOL_R, "RvbVolR", "Reverb Volume Right", 2 }, + + { PS_SPU::GSREG_MAINVOL_CTRL_L, "MainVolCL", "Main Volume Control Left", 2 }, + { PS_SPU::GSREG_MAINVOL_CTRL_R, "MainVolCR", "Main Volume Control Right", 2 }, + + { PS_SPU::GSREG_MAINVOL_L, "MainVolL", "Dry Volume Left", 2 }, + { PS_SPU::GSREG_MAINVOL_R, "MainVolR", "Dry 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_DST_A0", "", 2 }, + { PS_SPU::GSREG_IIR_DEST_A1, "IIR_DST_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_DST_B0", "", 2 }, + { PS_SPU::GSREG_IIR_DEST_B1, "IIR_DST_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_DST_A0", "", 2 }, + { PS_SPU::GSREG_MIX_DEST_A1, "MIX_DST_A1", "", 2 }, + { PS_SPU::GSREG_MIX_DEST_B0, "MIX_DST_B0", "", 2 }, + { PS_SPU::GSREG_MIX_DEST_B1, "MIX_DST_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; + CPUHookContinuous = false; + FoundBPoint = false; + + BTEnabled = false; + BTIndex = false; + memset(BTEntries, 0, sizeof(BTEntries)); + + 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); +} + + + +} + diff --git a/psx/octoshock/psx/gpu.cpp b/psx/octoshock/psx/gpu.cpp index 3d738414f7..b8df37b820 100644 --- a/psx/octoshock/psx/gpu.cpp +++ b/psx/octoshock/psx/gpu.cpp @@ -169,7 +169,7 @@ void PS_GPU::FillVideoParams(MDFNGI* gi) // For Justifier and Guncon. // gi->mouse_scale_x = (float)gi->lcm_width / gi->nominal_width; - gi->mouse_offs_x = 0; + gi->mouse_offs_x = (float)(2800 - gi->lcm_width) / 2; gi->mouse_scale_y = 1.0; gi->mouse_offs_y = LineVisFirst; @@ -401,6 +401,7 @@ INLINE void PS_GPU::Command_FBCopy(const uint32 *cb) if(!height) height = 0x200; + InvalidateTexCache(); //printf("FB Copy: %d %d %d %d %d %d\n", sourceX, sourceY, destX, destY, width, height); DrawTimeAvail -= (width * height) * 2; @@ -453,6 +454,8 @@ INLINE void PS_GPU::Command_FBWrite(const uint32 *cb) FBRW_CurX = FBRW_X; FBRW_CurY = FBRW_Y; + InvalidateTexCache(); + if(FBRW_W != 0 && FBRW_H != 0) InCmd = INCMD_FBWRITE; } @@ -491,28 +494,50 @@ INLINE void PS_GPU::RecalcTexPageStuff(uint32 tpage) } */ + +INLINE void PS_GPU::SetTPage(const uint32 cmdw) +{ + const unsigned NewTexPageX = (cmdw & 0xF) * 64; + const unsigned NewTexPageY = (cmdw & 0x10) * 16; + const unsigned NewTexMode = (cmdw >> 7) & 0x3; + + abr = (cmdw >> 5) & 0x3; + + if(!NewTexMode != !TexMode || NewTexPageX != TexPageX || NewTexPageY != TexPageY) + { + InvalidateTexCache(); + } + + if(TexDisableAllowChange) + { + bool NewTexDisable = (cmdw >> 11) & 1; + + if(NewTexDisable != TexDisable) + InvalidateTexCache(); + + TexDisable = NewTexDisable; + //printf("TexDisable: %02x\n", TexDisable); + } + + TexPageX = NewTexPageX; + TexPageY = NewTexPageY; + TexMode = NewTexMode; + + // + // + RecalcTexWindowStuff(); +} + INLINE void PS_GPU::Command_DrawMode(const uint32 *cb) { const uint32 cmdw = *cb; - TexPageX = (cmdw & 0xF) * 64; - TexPageY = (cmdw & 0x10) * 16; + SetTPage(cmdw); SpriteFlip = cmdw & 0x3000; - - abr = (cmdw >> 5) & 0x3; - TexMode = (cmdw >> 7) & 0x3; - dtd = (cmdw >> 9) & 1; dfe = (cmdw >> 10) & 1; - if(TexDisableAllowChange) - { - TexDisable = (cmdw >> 11) & 1; - //printf("TexDisable: %02x\n", TexDisable); - } - - RecalcTexWindowStuff(); //printf("*******************DFE: %d -- scanline=%d\n", dfe, scanline); } @@ -557,12 +582,18 @@ INLINE void PS_GPU::Command_MaskSetting(const uint32 *cb) MaskEvalAND = (*cb & 2) ? 0x8000 : 0x0000; } +INLINE void PS_GPU::InvalidateTexCache(void) +{ + for(int i=0;i> 4) & 0x1)] >> 16; - - TexPageX = (tpage & 0xF) * 64; - TexPageY = (tpage & 0x10) * 16; - - abr = (tpage >> 5) & 0x3; - TexMode = (tpage >> 7) & 0x3; - RecalcTexWindowStuff(); + SetTPage(CB[4 + ((cc >> 4) & 0x1)] >> 16); } if(!command->func[abr][TexMode]) diff --git a/psx/octoshock/psx/gpu.h b/psx/octoshock/psx/gpu.h index c96e4dce2e..1f3d5bfad3 100644 --- a/psx/octoshock/psx/gpu.h +++ b/psx/octoshock/psx/gpu.h @@ -131,8 +131,11 @@ class PS_GPU uint32 Tag; } TexCache[256]; + void InvalidateTexCache(void); void InvalidateCache(void); + void SetTPage(uint32); + void ProcessFIFO(void); void WriteCB(uint32 data); uint32 ReadData(void); diff --git a/psx/octoshock/psx/input/multitap.cpp b/psx/octoshock/psx/input/multitap.cpp index bc11ccb569..156055876e 100644 --- a/psx/octoshock/psx/input/multitap.cpp +++ b/psx/octoshock/psx/input/multitap.cpp @@ -118,32 +118,32 @@ void InputDevice_Multitap::SetSubDevice(unsigned int sub_index, InputDevice *dev } -void InputDevice_Multitap::Power(void) -{ - selected_device = -1; - bit_counter = 0; - receive_buffer = 0; - byte_counter = 0; - - mc_mode = false; - full_mode = false; - full_mode_setting = false; - - prev_fm_success = false; - memset(sb, 0, sizeof(sb)); - - fm_dp = 0; - memset(fm_buffer, 0, sizeof(fm_buffer)); - fm_deferred_error_temp = false; - - for(int i = 0; i < 4; i++) - { - if(pad_devices[i]) - pad_devices[i]->Power(); - - if(mc_devices[i]) - mc_devices[i]->Power(); - } +void InputDevice_Multitap::Power(void) +{ + selected_device = -1; + bit_counter = 0; + receive_buffer = 0; + byte_counter = 0; + + mc_mode = false; + full_mode = false; + full_mode_setting = false; + + prev_fm_success = false; + memset(sb, 0, sizeof(sb)); + + fm_dp = 0; + memset(fm_buffer, 0, sizeof(fm_buffer)); + fm_command_error = false; + + for(int i = 0; i < 4; i++) + { + if(pad_devices[i]) + pad_devices[i]->Power(); + + if(mc_devices[i]) + mc_devices[i]->Power(); + } } //void InputDevice_Multitap::StateAction(StateMem* sm, const unsigned load, const bool data_only, const char* sname_prefix) diff --git a/psx/octoshock/psx/input/multitap.h b/psx/octoshock/psx/input/multitap.h index a17c2cc80c..f9467dfbac 100644 --- a/psx/octoshock/psx/input/multitap.h +++ b/psx/octoshock/psx/input/multitap.h @@ -46,8 +46,6 @@ class InputDevice_Multitap final : public InputDevice uint8 sb[4][8]; - bool fm_deferred_error_temp; - bool fm_deferred_error; bool fm_command_error; uint8 command; diff --git a/psx/octoshock/psx/psx.cpp b/psx/octoshock/psx/psx.cpp index e187e9171c..4f6e1c3d7c 100644 --- a/psx/octoshock/psx/psx.cpp +++ b/psx/octoshock/psx/psx.cpp @@ -403,7 +403,7 @@ void PSX_RequestMLExit(void) // -// Remember to update MemPeek<>() when we change address decoding in MemRW() +// Remember to update MemPeek<>() and MemPoke<>() when we change address decoding in MemRW() template static INLINE void MemRW(pscpu_timestamp_t ×tamp, uint32 A, uint32 &V) { #if 0 @@ -918,6 +918,60 @@ uint32 PSX_MemPeek32(uint32 A) return MemPeek(0, A); } +template static INLINE void MemPoke(pscpu_timestamp_t timestamp, uint32 A, T V) +{ + if(A < 0x00800000) + { + if(Access24) + MainRAM.WriteU24(A & 0x1FFFFF, V); + else + MainRAM.Write(A & 0x1FFFFF, V); + + return; + } + + if(A >= 0x1FC00000 && A <= 0x1FC7FFFF) + { + if(Access24) + BIOSROM->WriteU24(A & 0x7FFFF, V); + else + BIOSROM->Write(A & 0x7FFFF, V); + + return; + } + + if(A >= 0x1F801000 && A <= 0x1F802FFF) + { + if(A >= 0x1F801000 && A <= 0x1F801023) + { + unsigned index = (A & 0x1F) >> 2; + SysControl.Regs[index] = (V << ((A & 3) * 8)) & SysControl_Mask[index]; + return; + } + } + + if(A == 0xFFFE0130) + { + CPU->SetBIU(V); + return; + } +} + +void PSX_MemPoke8(uint32 A, uint8 V) +{ + MemPoke(0, A, V); +} + +void PSX_MemPoke16(uint32 A, uint16 V) +{ + MemPoke(0, A, V); +} + +void PSX_MemPoke32(uint32 A, uint32 V) +{ + MemPoke(0, A, V); +} + static void PSX_Power(bool powering_up) { PSX_PRNG.ResetState(); // Should occur first! diff --git a/psx/octoshock/psx/psx.h b/psx/octoshock/psx/psx.h index edcfcbef88..839bcb3a84 100644 --- a/psx/octoshock/psx/psx.h +++ b/psx/octoshock/psx/psx.h @@ -64,11 +64,9 @@ namespace MDFN_IEN_PSX uint32 PSX_MemPeek32(uint32 A); // Should write to WO-locations if possible - #if 0 void PSX_MemPoke8(uint32 A, uint8 V); void PSX_MemPoke16(uint32 A, uint16 V); void PSX_MemPoke32(uint32 A, uint32 V); - #endif void PSX_RequestMLExit(void); void ForceEventUpdates(const pscpu_timestamp_t timestamp);