OAM DMA hijacking: Difference between revisions

Jump to navigation Jump to search
Content added Content deleted
No edit summary
Line 17: Line 17:


1. Before doing anything, make sure to write C9 (ret) to FF80 first; unless the code writes to the region all at once (and without an interrupt back to FF80).
1. Before doing anything, make sure to write C9 (ret) to FF80 first; unless the code writes to the region all at once (and without an interrupt back to FF80).

2. (Option 1 - Simplest but breaks OAM sprites) The player can write bytes from FF81 onward, such as a simple RAM modification code (15 EA 59 D0 C9), before adding 3E back to FF80. Another option for longer codes is to make FF80 read jp (source address). The ld a,C3 ld (ff00+46),a if overwritten like this will break OAM sprites (i.e. the sprites like Red on the screen), although from now on the code will run every frame regardless of where the player is in game; something that other arbitrary code execution methods cannot do.
2. (Option 1 - Simplest but breaks OAM sprites) The player can write bytes from FF81 onward, such as a simple RAM modification code (15 EA 59 D0 C9), before adding 3E back to FF80. Another option for longer codes is to make FF80 read jp (source address). The ld a,C3 ld (ff00+46),a if overwritten like this will break OAM sprites (i.e. the sprites like Red on the screen), although from now on the code will run every frame regardless of where the player is in game; something that other arbitrary code execution methods cannot do.

2. (Option 2 - Keeps OAM sprites) A more elaborate code may be written to keep OAM sprite functionality. Note the ld a,C3 ld (ff00+46),a works with a delay to keep the program counter in HRAM until FF89 (jumping there if the z flag is unset, from the code ld a,28 dec a jr nz,ff86). If the program counter remains in HRAM for the wrong amount of time, the game will freeze after leaving it (for example, if the 28 was changed to a lower value). Hence, any new delay should address this before leaving HRAM, yet if properly accounted for it is possible to run code outside of HRAM in addition to OAM sprites still working.
2. (Option 2 - Keeps OAM sprites) A more elaborate code may be written to keep OAM sprite functionality. Note the ld a,C3 ld (ff00+46),a works with a delay to keep the program counter in HRAM until FF89 (jumping there if the z flag is unset, from the code ld a,28 dec a jr nz,ff86). If the program counter remains in HRAM for the wrong amount of time, the game will freeze after leaving it (for example, if the 28 was changed to a lower value). Hence, any new delay should address this before leaving HRAM, yet if properly accounted for it is possible to run code outside of HRAM in addition to OAM sprites still working.

2. (Option 3 - Keeps OAM sprites but at the cost of potentially freezing the game if the HRAM addresses the player chose to change are overwritten again); Another option is to overwrite other HRAM address that don't often change beginning from a relative jump at FF89 (such as the money coins amount at FF9F) to run additional code which can be ended with a ret, without having to ever leave HRAM as part of the routines the player writes.
2. (Option 3 - Keeps OAM sprites but at the cost of potentially freezing the game if the HRAM addresses the player chose to change are overwritten again); Another option is to overwrite other HRAM address that don't often change beginning from a relative jump at FF89 (such as the money coins amount at FF9F) to run additional code which can be ended with a ret, without having to ever leave HRAM as part of the routines the player writes.