PCSX2 Debugger?
#1
Somebody on this site a while ago made a thread about something that involves using the debugger to find memory addresses and instructions to nop them and achieve a desired effect (namely disabling interlacing). They left behind some explanation but I'm still kind of lost as to how to use the debugger. There doesn't seem to be any documentation anywhere, not even on Youtube. Does anyone know a site that teaches the basics? Maybe there's other debugging programs that are similar that I could look into to understand this better?

I could also just ask the specific questions I have in mind and link to that old thread if somebody here is willing to take the time to explain things to me.

Thanks in advance.
Reply

Sponsored links

#2
PCSX2 has its own debugger, but Cheat Engine is probably your best bet. Learn how to use Cheat Engine with the game you're running. There's also ArtMoney as well. I've used both Cheat Engine and ArtMoney and found that CE is more advanced.
PC Specs:
PC: HP Omen 15 dc-0051nr laptop
CPU: Intel i7-8750H (2.2 GHz up to 4.1 GHz)
RAM: 16 GB
GPU: Nvidia GeForce GTX 1060 Notebook (6 GB)
OS: Windows 10 Pro (64 bit)/Windows 8.1 Pro (64 bit)
Storage: 256 SSD PCi NV M.2+1 TB HDD
Need the latest GIT/development build? Click here!
Reply
#3
(09-23-2019, 07:24 PM)gtgamer468 Wrote: PCSX2 has its own debugger, but Cheat Engine is probably your best bet. Learn how to use Cheat Engine with the game you're running. There's also ArtMoney as well. I've used both Cheat Engine and ArtMoney and found that CE is more advanced.
The idea behind what I was trying to do is to read the code in the debugger and figure out what instruction is causing interlacing/screen shaking so you can disable it. I don't think that works in Cheat Engine?
Reply
#4
When game use standard code from Sony libraries, you can even disable it with hex editor only sometime. But ps2dis should be enough for many games to find that. Not really need for pcsx2 debugger to do that.
sceGsSetHalfOffset pattern is easy to find, when you grab it from any game with that symbol. Also simple hex search can give good result if game not use daddiu v0, v0, $0008 frequently.

All is well described here: https://forums.pcsx2.net/Thread-No-interlacing-codes
For games that use own versions of code finding this is much harder. There pcsx2 debugger can be handy.
Reply
#5
(09-24-2019, 10:41 AM)kozarovv Wrote: When game use standard code from Sony libraries, you can even disable it with hex editor only sometime. But ps2dis should be enough for many games to find that. Not really need for pcsx2 debugger to do that.
sceGsSetHalfOffset pattern is easy to find, when you grab it from any game with that symbol. Also simple hex search can give good result if game not use daddiu v0, v0, $0008 frequently.

All is well described here: https://forums.pcsx2.net/Thread-No-interlacing-codes
For games that use own versions of code finding this is much harder. There pcsx2 debugger can be handy.

Yeah, I've tried searching for "daddiu v0, v0, $0008" (64420008) and zeroing it out in a few games and it worked for Road Trip Adventure for example. But it didn't work for most other games so I wanted to learn how to figure it out with the breakpoint and searching for 0s, 1s or 8s. I have to look into it more with Cheat Engine I think but so far I'm not understanding a lot of it, probably because I have little to no understanding of Assembly and debuggers.

For example, I can find many different values that consisently change between 0 and 1 or 0 and 8 every frame. Is it enough to make a .pnach that sets the value to 0 permanently (or whichever is the upper frame) to disable the shaking? (I can try that once I have the time to test all the different addresses I found)

The person in that thread said:
Quote:3. You will find a few addresses, from trial and error we conclude that address 00641E40 is responsible for the shaking

4. The instrucion @0016A048 is writing this address during gameplay, and instr @0016A054 is writing the same address during loading screen

How do they determine which one is "responsible" for the shaking? By setting it to a fixed value in Cheat Engine? Making a .pnach? But then what is the instruction at 0016A048 for? How do they find 0016A048? Is that something you find in the PCSX2 debugger by clicking on something and just scrolling through it? Or do you do something specific in Cheat Engine?
Reply
#6
(09-24-2019, 11:23 AM)Maria Wrote: For example, I can find many different values that consisently change between 0 and 1 or 0 and 8 every frame. Is it enough to make a .pnach that sets the value to 0 permanently (or whichever is the upper frame) to disable the shaking? (I can try that once I have the time to test all the different addresses I found)

The person in that thread said:

"3. You will find a few addresses, from trial and error we conclude that address 00641E40 is responsible for the shaking

4. The instrucion @0016A048 is writing this address during gameplay, and instr @0016A054 is writing the same address during loading screen"

How do they determine which one is "responsible" for the shaking? By setting it to a fixed value in Cheat Engine? Making a .pnach?

Yes, by setting that value by pnach, or sometime by changing value directly in debugger (push G to edit instruction). Look out with using save states, never save state when you using pnach. If game is not reloading that part of memory, when you load state like that, your pnach will be active even if you remove it.


Quote:But then what is the instruction at 0016A048 for? How do they find 0016A048? Is that something you find in the PCSX2 debugger by clicking on something and just scrolling through it? Or do you do something specific in Cheat Engine?

From what i can read there, 0x16A048 is where instruction that set 8, or 1 was. I don't know which game it is, so i can't show exactly how it looked, but probably it was some ""sb register1, register2"" where register1 stored 1, or 8, and register 2 stored 0x641E40, so place where it write that 1, or 8. 

Generally is much better way to patch instruction that set 1, than just patch 0x641E40 to 0. 

Quote:For example, I can find many different values that consisently change between 0 and 1 or 0 and 8 every frame. Is it enough to make a .pnach that sets the value to 0 permanently (or whichever is the upper frame) to disable the shaking? (I can try that once I have the time to test all the different addresses I found)

Well that is actually that trial and error mentioned earlier. Find values that change between frames (0,1,8), and test what happen if you patch them to not change between frames. Remember to use 0x12000090 write break, because without that you can find much more values that change between 0,1,8. This will only make things harder.
Reply
#7
(09-24-2019, 07:05 PM)kozarovv Wrote: From what i can read there, 0x16A048 is where instruction that set 8, or 1 was. I don't know which game it is, so i can't show exactly how it looked, but probably it was some ""sb register1, register2"" where register1 stored 1, or 8, and register 2 stored 0x641E40, so place where it write that 1, or 8. 

Generally is much better way to patch instruction that set 1, than just patch 0x641E40 to 0. 

Does that mean when I've found a value that consistently changes between 0/1 or 0/8 in Cheat Engine, do I right-click it and then "Find out what writes to this address"? I'll have to try this properly later. I'm testing this with Legaia 2 NTSC right now and so far I've found a green address 016F07B4 that changes from 0 to 1 and is written by 008D9E40 and 008D9F09 and replacing them in CE with "nop" doesn't remove the shaking, neither does making cheats (008D9E40 00000000 and 008D9F09 00000000). I also tried using AF80E750 instead of 00000000 since asasega used that for crash which seems to mean "beql" in MIPS code (?) and that didn't work either. I assume I just found the wrong address, I'll try later with other addresses I can find. But I guess this is at least the right procedure? Or am I overlooking or misunderstanding something?

I'm also not sure what the memory range I should search in, to make sure I don't waste time searching useless addresses. The PS2 has 32MB memory so does that mean I search within 0 - 33554432?

Thank you very much for your help so far. I'm definitely learning a lot.
Reply
#8
I've experimented more and figured out a bunch of things with Legaia 2 (NTSC).

Most scenes in the game - opening credits and anything that's 3D like the world map, town/dungeon scenes, cutscenes, battles - use the Sony standard routine, i.e. 64420008. The code for this in a .pnach would be 202C0F04 00000000.

Load/save screen, status screen, anything 2D like text boxes, menus, HP display, etc. use a custom routine that I don't entirely understand. But I know for a fact that the address 2049E8B4 must be responsible for the shaking, 0 = up and 1 = down. I couldn't stop the shaking by putting 2049E8B4 00000000 into the .pnach. However, I can go to Cheat Engine, right click 2049E8B4 -> "Find out what writes to this address" and nop out any entries it finds there during gameplay (right click->"Replace with code that does nothing (NOP)") which removes it instantly.

This has to be done everytime you restart the game in PCSX2. When you first start PCSX2 and boot the game, the addresses for the instructions will be consistent (30147EB2 and 30147F07 usually) but when I tried 00000000'ing them out in the .pnach it did nothing.

For the time being this is really good but is there any way I can actually find these instructions in the PCSX2 debugger as well? And actually make them work in a .pnach? I'm guessing maybe 30147EB2 and 30147F07 are protected memory or something because the .pnach code doesn't affect them.

Also, I've noticed there is a discrepancy between memory addresses in the Cheat Engine memory viewer and the PCSX2 debugger/memory viewer. For instance, when I tested with Road Trip Adventure, the first instruction I could see in PCSX2 (30 00 00 00 10 1A 00 00) was at 00100000. However when I searched for the same instruction in Cheat Engine, it was at 20100000. Other times, like when I search for the daddiu v0 v0 8 code (08 00 42 64), I can find it at the same address 202724C4 in both Cheat Engine and PCSX2. When I search for instructions that are writing into the 0/1 or 0/8 address, Cheat Engine gives me addresses that do not exist in this game (3xxxxxxx) - those memory ranges in PCSX2 are completely empty. Is there a way to somehow trace the instructions Cheat Engine finds back to the PCSX2 debugger?

I also understand now that Cheat Engine disassembles the code differently from PCSX2 - Playstation 2 Code is MIPS based whereas Cheat Engine automatically interprets everything as regular PC (x86?) code so the disassembled code in Cheat Engine seems to be useless. I've tried looking into ps2dis and PCSX2dis and both indeed disassemble the game correctly (like PCSX2's internal debugger does) but unlike Cheat Engine, neither of them seem to provide a function to automatically search for instructions that write into an address. And that function seems really important from what I can tell. Are there other programs that can do this better? Or a Cheat Engine plugin that can disassemble MIPS? Are there maybe other ways around this?
Reply
#9
Set breakpoint to 0x49E8B4, set it to write memory access only. That way when write to that address will be performed, you will see place that write to it in debbuger (it will auto jump there). This gonna be something like:

sb aX, register
or
sw aX, register

That one is that you need to nop to stop it writing value there.
I doubt that gonna be case here, but if you land on branch when debugger break (b, bne, blez, etc.) then remember that mips is executing also next opcode after that branch. So if you land at b 0xsomething, check that next opcode is sw, or sb. Because that sw or sb is what you need to nop.

I don't think you will have that situation with your first game, but who knows.

Quote:This has to be done everytime you restart the game in PCSX2. When you first start PCSX2 and boot the game, the addresses for the instructions will be consistent (30147EB2 and 30147F07 usually) but when I tried 00000000'ing them out in the .pnach it did nothing.
EE memory is 0x0 to 0x1FFFFFF, when you create pnach with 3 at start, you will do nothing, or do something unexpected when extended code format is used. Read about it btw. First character in pnach is kind of command, 0,1,2 = byte, half, word. 3-F have totally different meaning, like conditional patch, etc. 

Just follow my advice for 0x49E8B4, and you should be good.
Reply
#10
Making a breakpoint at the address that changes between 0/1 (0x49E8B4) was REALLY helpful! It jumps to 00111184, at a beqz function which is followed by an sw instruction. Here's a screenshot just for reference.

I figured out that that sw instruction (at 0x111188) is ultimately the one responsible for interlacing and by noping that instruction I was able to get rid of it.

At first I got confused about how .pnach files work so I looked that up as well. The PCSX2 memory doesn't need 8 digit hexcodes (as you pointed out @kozarovv), the first digit is actually used to indicate how many bytes are going to be replaced. Since I want to replace/nop an entire instruction, that requires for 4 bytes to be replaced so I need a preceding 2:

Code:
patch=1,EE,20111188,extended,00000000

This is the line required to fully remove interlacing in Legaia 2 NTSC (alongside 202C0F04 00000000).

I think if I wanted to patch an address that just holds a simple value (like 0/1 or an HP counter etc) then it'd start with 0 (which means 1 byte will be replaced). For values that are bigger than FF (or 255 in decimal) I would need to start it with 1. Instructions (like in the picture though) are 4 bytes long so in .pnach it needs to start with 2.

Thanks @kozarovv, you were really helpful. I should be able to find interlacing codes for other games like this too. Is it always an sb or sw instruction that causes the interlacing? Is it possible that it's sometimes a different instruction? Is it always at the point the debugger jumps to or very closely after it?
Reply




Users browsing this thread: 1 Guest(s)