Tutorial:Hacking a Routine

From SMWiki

(Redirected from Tutorial:hacking a routine)
Jump to: navigation, search

Contents

[edit] Requirement

For this tutorial, you will need:

Geiger's SNES9x debugger

Xkas

SMW central's RAM map

Any text editor

[edit] Introduction

In this tutorial, we will replicate the powerdown patch found in the patch section (which require one to hack a game routine), it is also assumed that you understand most of the basic opcodes(LDA, STA, CMP, etc.)

[edit] Finding where to insert the code

Wrote breakpoint have been inserted
Wrote breakpoint have been inserted

Open your SMW ROM in the SNES9x debugger(make sure to make a back-up, as it WILL delete the copier header). To find the instruction we will substitute to insert our code, we need to add a breakpoint, A breakpoint is a feature that cause emulation to stop if a specific address is executed, read or written. To make a powerdown patch, we need to have it so when Fire Mario and Cape Mario get hurt, they revert back to Super Mario insted of normal. For this, we must locate the instruction used to make super/fire/cape Mario into normal. To locate it, first play the game until you get super/fire/cape and are close to getting hurt, then click on the breakpoint button, and add a breakpoint caused by write in 7E0019 (Mario's power-up). Once the breakpoint have been inserted, just get hurt to trigger the hurt subroutine. the emulation will stop, and the debug will have a new row of text in it, the new row will look like this:

$00/F600 64 19 STZ $19 [$00:0019] A:7901 X:0005 Y:0004 D:0000 DB:03 S:01EC P:envMXdizc

$00/F600 is the SNES address the opcode is located at, STZ $19 is the instruction that caused the breakpoint, 64 19 is the hex version of the opcode and P:envMXdizc is the state of the processor flags(capital mean set).
The instructions in the debug console
The instructions in the debug console
Because to insert our code, we need to add a JSL, which is 4 byte long, we need to know the next instruction so we can restore it to avoid bugs.

[edit] Inserting the code

Create a new .asm file and open it with your text editor, then add the following text:

header
lorom
org $F600

The first row, 'header', is used to make the assembler know that the ROM to be patched has a header, 'lorom' is used to make the assembler know that the ROM uses lorom mapping which SMW uses, 'org $F600' tells that the following code will have to be assembled at SNES adress $F600. now add the following text:

JSL Main

This JSL will lead to our routine which will store $00 to the power-up if you're in super Mario and store $01 if you're fire or cape mario. Also please take into consideration that the total number of bytes of the old instuctions must be equal to the number of bytes of the new instruction, since in our case the old instructions (STZ $19 and lda #$29) are 4 bytes in total, we don't need to worry about that, but if the total were 5, we would've needed to add a NOP. Now for the next part, lets add our custom code:

org $1fb000 ;the SNES adress the code will be inserted to this can be changed to anywhere in the ROM area

db "STAR"        ;\
dw $0080, $FF7F  ;/ A RATS tag used to protect 80 byte
Main:
          lda $19       ;\
          cmp #$02      ; |If Mario is Super
          BCS to_super  ; |then {
          STZ $19       ; |set Mario to normal ($00)
          lda #$29      ; |this is the instruction we removed to put the JSL
          rtl           ;/ return }
to_super:               ;\ 
          lda #$01      ; |else {
          sta $19       ; |set Mario to super ($01)
          lda #$29      ; |this is the instruction we removed to put the JSL
          rtl           ;/ return }

Please note that everything after the ; are comments and are ignored by the assembler. If you did all these steps, the final code should be:

header
lorom
org $F600
JSL Main
org $1fb000 ;the SNES adress the code will be inserted to this can be changed to anywhere in the ROM area
db "STAR"        ;\
dw $0080, $FF7F  ;/ A RATS tag used to protect 80 byte
Main:
          lda $19       ;\
          cmp #$02      ; |If Mario is Super
          BCS to_super  ; |then {
          STZ $19       ; |set Mario to normal ($00)
          lda #$29      ; |this is the instruction we removed to put the JSL
          rtl           ;/ return }
to_super:               ;\ 
          lda #$01      ; |else {
          sta $19       ; |set Mario to super ($01)
          lda #$29      ; |this is the instruction we removed to put the JSL
          rtl           ;/ return }

To patch the ROM with Xkas, create a new text file with:

Xkas 'yourpatchname'.asm 'yourromname'.smc

Then put the patch, the ROM and Xkas in the same folder, save it as a .bat file, and double-click on it.

[edit] Testing and debugging

To debug your code, load the patched ROM in the debugger(don't forget to make a back-up) and set an execute breakpoint to where you inserted the JSL, then keep hitting step into to go to the next instruction until you find where you screwed up, if you can't find the problem, post the .asm code in the ASM help thread in the adv. SMW hacking forum

Personal tools