Norbert wrote: ↑February 1st, 2021, 10:20 pm
In the file after numpad 6 I see the same two bytes, but changing those in the same manner crashes the game.
For the record, here is that hack:
David wrote: ↑September 2nd, 2018, 9:09 pm
Norbert wrote: ↑August 29th, 2018, 9:02 am
- A way to force the prince to auto-run right, with left/right arrows having no impact.
This is the easier of the two.
search: 80 3E D7 28 00 75 07
change: 75 07 to EB 1C
This changes the keyboard handler, so it won't work in joystick mode.
And here is what it changes:
Code: Select all
seg000:152F loc_152F:
seg000:152F
seg000:152F 80 3E D7 28 00 cmp key_states_4B_left, 0
seg000:1534 75 07 jnz loc_153D ; <-- change to jmp loc_1552
seg000:1536 80 3E D3 28 00 cmp key_states_47_home, 0
seg000:153B 74 07 jz loc_1544
seg000:153D
seg000:153D loc_153D:
seg000:153D C6 06 12 46 FF mov control_x, 0FFh
seg000:1542 EB 13 jmp short loc_1557
seg000:1544
seg000:1544 loc_1544:
seg000:1544 80 3E D9 28 00 cmp key_states_4D_right, 0
seg000:1549 75 07 jnz loc_1552
seg000:154B 80 3E D5 28 00 cmp key_states_49_pageup, 0
seg000:1550 74 05 jz loc_1557
seg000:1552
seg000:1552 loc_1552:
seg000:1552 C6 06 12 46 01 mov control_x, 1
seg000:1557
seg000:1557 loc_1557:
So why does EB 1C mean jmp loc_1552?
0x1C is a relative jump offset, counted from the byte after the jump instruction: 0x1536 + 0x1C = 0x1552.
If you write the same bytes at 0x1549, then it will jump to 0x154B + 0x1C = 0x1567.
That address is the second byte of this instruction:
Jumping into the middle of instructions is generally a bad thing.
The CPU will see these instructions:
Code: Select all
.00001567: 03 28 add bp,[bx+si]
.00001569: 06 push es
.0000156A: C6 4C CB 55 mov [si-35],55
.0000156E: 8B EC mov bp,sp
So the CPU will skip the return instruction (retf = CB, the mov "ate" it), and starts to execute the following procedure, which is copy_screen_rect().
At the end of copy_screen_rect() there is a "pop bp" instruction, because it has a stack frame (for local variables).
Code: Select all
seg000:15E3 8B E5 mov sp, bp
seg000:15E5 5D pop bp
seg000:15E6 CA 04 00 retf 4
However, we have also skipped the "push bp" (55, also eaten by the mov) at the start of this procedure, so "pop bp" will pop not a pushed bp but the return address meant for the "retf" in read_keyb_control()!
Then the following "retf" will return to a "random" address read from whatever is on the top of the stack is at this point.
That's why it crashes.