Jump to content

OAM DMA hijacking: Difference between revisions

m
Line 18:
1. Before doing anything, make sure to write C9 (ret) to FF80 first; unless the code writes to the region all at once as the game could freeze.
 
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 normally do (though hypothetically something may be possible without it by manipulating the stack).
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's ret (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 to the money coins amount at FF9F) to run additional code (and with a potential series of other relative jumps across HRAM) which can be ended with a ret, without having to ever leave HRAM as part of the routines the player writes.
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's ret (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 to the money coins amount at FF9F) to run additional code (and with a potential series of other relative jumps across HRAM) which can be ended with a ret, without having to ever leave HRAM as part of the routines the player writes.
 
OAM DMA hijacking is useful as a form of 'real-time' arbitrary code execution, allowing the player to perform exploits such as walk through walls in Generation II or writing a [[0x50 sub-tile]] permanently to the beginning of the screen data for Generation I.
Cookies help us deliver our services. By using our services, you agree to our use of cookies.