Baekalfen / PyBoy

Game Boy emulator written in Python
Other
4.57k stars 472 forks source link

Registering a hook to change PC to the previous instruction doesn't properly advance 'tick' #332

Open VariantXYZ opened 2 months ago

VariantXYZ commented 2 months ago

While trying to see if I could emulate breakpoint behavior in PyBoy using hooks, I found that setting the hook to one instruction ahead and changing PC to the instruction I actually wanted to hook was causing tick to never return.

Specifically, in my disassembly of Medarot 3:

from pyboy import PyBoy
def breakpoint(p):
     p.register_file.PC = p.symbol_lookup("Main.mainGameLoop")[1]

pyboy = PyBoy('medarot3_kabuto.gbc', symbols='medarot3_kabuto.sym')
pyboy.hook_register(0, pyboy.symbol_lookup("Main.mainGameLoop")[1] + 1, breakpoint, pyboy)
pyboy.tick(100)

where Main.mainGameLoop is defined as:

xor a
ld [$c4d9], a
call Function
...

If I instead opt to have my breakpoint at +4 (at the call instead), tick seems to properly return.

This Tick behavior seems to be unintended or undefined, but if it is intended, then I think it would be useful to have it documented.