Skip to content

Instantly share code, notes, and snippets.

@ZumiKua
Last active November 6, 2025 16:28
Show Gist options
  • Select an option

  • Save ZumiKua/c00b4bdfae5acbd86790f50f7e7273ae to your computer and use it in GitHub Desktop.

Select an option

Save ZumiKua/c00b4bdfae5acbd86790f50f7e7273ae to your computer and use it in GitHub Desktop.
local bit = require("bit")
function findFunctionStart(start_address)
start_address = bit.band(start_address, 0x7FFFFFFF)
local mem_ptr = PCSX.getMemPtr()
local INSTRUCTION_SIZE = 4
local JR_RA_OPCODE = 0x0800E003
if start_address % INSTRUCTION_SIZE ~= 0 then
start_address = start_address - (start_address % INSTRUCTION_SIZE)
end
local current_address = start_address
local MIN_SEARCH_ADDRESS = 0x00000000 -- 假设一个合理的最小搜索地址
while current_address >= MIN_SEARCH_ADDRESS do
local byte1 = mem_ptr[current_address]
local byte2 = mem_ptr[current_address + 1]
local byte3 = mem_ptr[current_address + 2]
local byte4 = mem_ptr[current_address + 3]
local instruction = bit.lshift(byte1, 24) + bit.lshift(byte2, 16) + bit.lshift(byte3, 8) + byte4
if instruction == JR_RA_OPCODE then
return current_address + 2 * INSTRUCTION_SIZE + 0x80000000
end
current_address = current_address - INSTRUCTION_SIZE
end
end
function showCurrentCallstacks()
local calls = PCSX.getCurrentCalls();
for call in calls do
local cra = call.ra
local craStart = 0--findFunctionStart(cra)
print(string.format("%X(%X)", craStart, cra))
end
--local ra = PCSX.getRegisters().GPR.n.ra
--local raStart = 0--findFunctionStart(ra)
--print(string.format("%X(%X)", raStart, ra))
end
function onCDRead()
local success, result = pcall(function()
local regs = PCSX.getRegisters().GPR.n;
local len = regs.a0
local dest = regs.a1
print(string.format("CDRead %d Sectors From %d Into %X", len, lastSetLoc, dest))
showCurrentCallstacks()
end)
if not success then
print("Error ", result)
end
return true
end
function btoi(c)
return bit.rshift(c, 4) * 10 + bit.band(c, 0xF)
end
lastSetLoc = 0
function onCDControl()
local regs = PCSX.getRegisters().GPR.n;
local command = regs.a0
local commandArg = regs.a1
if command ~= 2 then
return true
end
commandArg = bit.band(commandArg, 0x7FFFFFFF)
if commandArg >= 0x800000 then
print(string.format("CDControl with SetLoc at %X Invalid Addr", commandArg))
return
end
local mem = PCSX.getMemPtr()
local minutes = btoi(mem[commandArg])
local seconds = btoi(mem[commandArg + 1])
local sectors = btoi(mem[commandArg + 2])
local sec = minutes * 75 * 60 + seconds * 75 + sectors - 150
lastSetLoc = sec
print(string.format("CDControl with SetLoc at %d", sec))
showCurrentCallstacks()
return true
end
readCDBP = nil
cdControlBP = nil
function start()
--readCDBP = PCSX.addBreakpoint(0x800731e4, 'Exec', 4, "CDRead", onCDRead)
cdControlBP = PCSX.addBreakpoint(0x800702e0, 'Exec', 4, "CDControl", onCDControl)
PCSX.getCurrentCalls()
end
-- local calls = PCSX.getCurrentCalls();
-- for call in calls do
-- end
-- local ra = PCSX.getRegisters().GPR.n.ra
dofile("lua/callstacks.lua")
start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment