Patch Making Tutorial
Welcome! In this tutorial you will learn how to make patches. If you came here to know how to insert patches, you can find one for xkas here. If you are using asar it is easy, just open asar and enter your ROM name and patch name. .bat files and anything else will also work.
I would recommend using asar.
Lets Begin:
First make a text file and rename it to:
(Your File Name).asm
If you are using xkas you need to put this at the top of your file:
header
lorom
header - This is only added if your ROM has a header. And most SMW ROMs used around here do.
lorom - This is the ROM mapping. You can just leave it as 'lorom' you won't find many other SMW ROMs around here that use a different mapping.
These are not needed in asar (I would especially recommned not putting 'header' in the patch), but it is good to know what they do.
Actual Code:
First let’s do some basic coding. Let’s hex edit through a patch. Say we wanted to change the Nintendo Presents logo sound. Well if we go to the ROM Map (Not RAM Map) you should be able to find this:
015C1 $00:93C1 1 byte Sound effect "Nintendo Presents" logo sound effect
How do we change it? Well first we have to tell the assembler the starting SNES addresses we want to modify. How do we do that? We use org. The 'org' command is not a opcode however. So put this in your ASM file:
org $0093C1
You should still have the header and lorom at the top of your file if you are using xkas. Now how do we actually change it? We use db. 'db' is not a opcode either, it just lets us change a byte in this case. To make the nintendo present logo make a bullet sound. We would do this:
org $0093C1
db $09
The Nintendo presents logo uses sfx bank $1DFC. Try it out.
Now that only changed one byte. What if you wanted to change more than one byte? You could do this:
org $04828D
db $80,$06
That would disable the lives exchanger. Here is another example:
org $0485CF
db $EA,$EA,$EA,$EA
That would disable Mario from the OW border.
You could also do:
org $0485CF
db $EA
db $EA
db $EA
db $EA
or even:
org $0485CF
NOP #4
Hex-editing trough patches is good because it allows you to keep track of your changes.
All.log:
All.log is very useful when making patches. It’s a entire disassembly of SMW. It shows all of the code that gets run in SMW, and it very useful for patch making. For now you can look through it if you want.
Routine Hacking:
It’s time to start our first ACTUAL patch. For now let’s make a patch that instead of giving you a 1-up when you get 100 coins, you will get a power up depending on what power up Mario already has. Let’s begin. First we have to find the code in All.log that gives you a 1-up when you get 100 coins. Got to All.log and hit ctrl+f and type in 100. Hit “Find Next” until you see this:
That looks like what we want. Now it says “If coins <100, branch”. So if Mario’s coins are below 100, it will branch. Scroll down a bit and you should see this:
How ‘bout we hijack this? We are going to hijack $008F32. (Do you see where I got this? Look back up there if you don’t.). Now we should have this so far:
org $008F32
Now we need to get rid of all relevant code. Look at this code:
See those things underlined? Those are how many bytes it takes up. So it takes up 9. If you’re wondering how I got that just count the hex numbers underlined. After hijacking the correct address and figuring out how many bytes it takes up, we have to jump to our code.
You can use any relevant jump command you'd like, and you should know how they work. JSR takes up three bytes , JSL takes four, BRA takes two, JMP takes three, JML takes four, etc. Normally though, you will usually use JSL or JML. Also note that when using JML, it is EXTREMELY important to jump back to the original code, otherwise you will end up with a crash. Remember this.
Now do this to jump to our code:
Org $008F32
autoclean JSL OurCode
(I used 'OurCode' as a label, but you can use whatever you'd like.)
'autoclean' is needed in front of JSL and JML for asar (it erases old data before patching).
Now JSL only takes up 4 bytes and the code we are hijacking takes up 9. So we just need to fill up or skip the rest. There are five extra bytes so we can do this:
Org $008F32
autoclean JSL OurCode
NOP #5
or:
Org $008F32
autoclean JSL OurCode
BRA skip
NOP #3
skip:
It is important not to leave behind any unwanted bytes, but it is also important not to go over, otherwise you will overwrite other code. For example let’s say the code we wanted to overwrite took up four bytes. We would not do this:
Org $xxxxxx
autoclean JSL Code
NOP #3
That will likely cause your game to crash. After that we have to set the freespace. You will need slogger to find freespace in your ROM. So we should now have this if you are using xkas:
Org $008F32 ; Routine to hack
JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
Org $Freespace ; your freespace
OurCode:
for asar:
Org $008F32 ; Routine to hack
autoclean JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
freecode
OurCode:
'freecode' will search for freespace for you. Much easier eh?
Now remember those extra bytes we got rid of? Before writing our custom code, we need to restore that overwritten code. If we don't put it back, then that code won't be executed (although sometimes you do want this). So the code we need to put back is this:
LDA.W RAM_StatusCoins ; \
SEC ; |Decrease coins by 100
SBC.B #$64 ; |
STA.W RAM_StatusCoins ; /
Now there are some things we have to do first. If you are using xkas you will need to get rid of the .B's, .W's, .L's or make them lowercase. Now we should have this:
LDA RAM_StatusCoins ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA RAM_StatusCoins ; /
We now need to get replace those definitions. Go back to all.log and search for “RAM_StatusCoins”. Do this until you get to the LAST search result. You should see this:
7E0DBF RAM_StatusCoins
Now replace “RAM_StatusCoins” with “$0DBF”. We should have this:
LDA $0DBF ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA $0DBF ; /
There now we can put this into our hack. So now are code should look like this:
Org $008F32 ; Routine to hack
JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
Org $Freespace ; your freespace
OurCode:
LDA $0DBF ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA $0DBF ; /
Now we can write our code. First let’s make it so Mario can’t get a 1-up. To do that we would do this:
DEC $0DBE
Good now he won’t get a 1-up after getting 100 coins! Now let’s finish the code:
LDA $19 ; If Mario has a…
CMP #$03 ; Flower!
BEQ Flower ; Branch
INC $19 ; Otherwise increase his power up status and…
RTL ; Return
Flower:
LDA #$FF ; \ Set star timer
STA $1490 ; /
LDA #$0D ; \
STA $1DFB ; / Change music
ASL $0DDA
SEC
ROR $0DDA
RTL ; Return
You should be able to understand what happened here. Now our WHOLE code should be this:
org $008F32 ; Routine to hack
autoclean JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
freecode
OurCode:
LDA $0DBF ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA $0DBF ; /
DEC $0DBE
LDA $19 ; If Mario has a…
CMP #$03 ; Flower!
BEQ Flower ; Branch
INC $19 ; Otherwise increase his power up status and…
RTL ; Return
Flower:
LDA #$FF ; \ Set star timer
STA $1490 ; /
LDA #$0D ; \
STA $1DFB ; / Change music
ASL $0DDA
SEC
ROR $0DDA
RTL ; Return
Try it out. Did it work? If so you just made your first patch!
Rats Tag:
If you are using asar just skip this, asar inserts RATS tags for you, unless you want to know what they do.
Now there is one more thing we can do to make this code even better. And that is add a rats tag. A rats tag is an extremely useful and important thing to put in patches because at some point, Lunar Magic or any other tool can overwrite your patch data. When this happens, your patch probably won't function anymore or something bad might happen like the ROM crashing.
To set up a RATS Tag, you protect each and every byte in your routine. It is set up RIGHT after the org $freespace, like this:
JSL CustomCode
org $168000 ; <- Freespace.
!CodeSize = End-Start ; <- RATS Tag define.
db "STAR"
dw !CodeSize-$01
dw !CodeSize-$01^$FFFF
Start: <- Beginning of RATS Tag, and bytes to protect.
;=========;
;PATCH CODE GOES HERE
;=========;
End: ; <- End of RATS Tag and number of bytes to protect..
As you can see, you mark the ending and beginning of the RATS Tag in the !CodeSize define. The start of my RATS Tag is called Start and the end of my RATS Tag is called End.
You can also notice that unlike labels, you put a colon (":") when making the RATS labels. It is Start: and End:, not Start and End!
So our code with a RATS Tag will look like this:
Header
Lorom
Org $008F32 ; Routine to hack
JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
Org $Freespace ; your freespace
!CodeSize = End-Start ; <- RATS Tag define.
db "STAR"
dw !CodeSize-$01
dw !CodeSize-$01^$FFFF
Start:
OurCode:
LDA $0DBF ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA $0DBF ; /
DEC $0DBE
LDA $19 ; If Mario has a…
CMP #$03 ; Flower!
BEQ Flower ; Branch
INC $19 ; Otherwise increase his power up status and…
RTL ; Return
Flower:
LDA #$FF ; \ Set star timer
STA $1490 ; /
LDA #$0D ; \
STA $1DFB ; / Change music
ASL $0DDA
SEC
ROR $0DDA
RTL ; Return
End: ; <- End of RATS Tag and number of bytes to protect..
Don't forget putting RATS Tags inside your code, it's even been made a rule to submit patches with a RATS Tag. If you find it difficult to make one, just copy/paste from another patch ;)
Re-apply the patch, this time with a RATS Tag, and your code is now safe in the ROM.
And that is it you are pretty much done! Post below if you need any help with anything.
Welcome! In this tutorial you will learn how to make patches. If you came here to know how to insert patches, you can find one for xkas here. If you are using asar it is easy, just open asar and enter your ROM name and patch name. .bat files and anything else will also work.
I would recommend using asar.
Lets Begin:
First make a text file and rename it to:
(Your File Name).asm
If you are using xkas you need to put this at the top of your file:
header
lorom
header - This is only added if your ROM has a header. And most SMW ROMs used around here do.
lorom - This is the ROM mapping. You can just leave it as 'lorom' you won't find many other SMW ROMs around here that use a different mapping.
These are not needed in asar (I would especially recommned not putting 'header' in the patch), but it is good to know what they do.
Actual Code:
First let’s do some basic coding. Let’s hex edit through a patch. Say we wanted to change the Nintendo Presents logo sound. Well if we go to the ROM Map (Not RAM Map) you should be able to find this:
015C1 $00:93C1 1 byte Sound effect "Nintendo Presents" logo sound effect
How do we change it? Well first we have to tell the assembler the starting SNES addresses we want to modify. How do we do that? We use org. The 'org' command is not a opcode however. So put this in your ASM file:
org $0093C1
You should still have the header and lorom at the top of your file if you are using xkas. Now how do we actually change it? We use db. 'db' is not a opcode either, it just lets us change a byte in this case. To make the nintendo present logo make a bullet sound. We would do this:
org $0093C1
db $09
The Nintendo presents logo uses sfx bank $1DFC. Try it out.
Now that only changed one byte. What if you wanted to change more than one byte? You could do this:
org $04828D
db $80,$06
That would disable the lives exchanger. Here is another example:
org $0485CF
db $EA,$EA,$EA,$EA
That would disable Mario from the OW border.
You could also do:
org $0485CF
db $EA
db $EA
db $EA
db $EA
or even:
org $0485CF
NOP #4
Hex-editing trough patches is good because it allows you to keep track of your changes.
All.log:
All.log is very useful when making patches. It’s a entire disassembly of SMW. It shows all of the code that gets run in SMW, and it very useful for patch making. For now you can look through it if you want.
Routine Hacking:
It’s time to start our first ACTUAL patch. For now let’s make a patch that instead of giving you a 1-up when you get 100 coins, you will get a power up depending on what power up Mario already has. Let’s begin. First we have to find the code in All.log that gives you a 1-up when you get 100 coins. Got to All.log and hit ctrl+f and type in 100. Hit “Find Next” until you see this:
Code
CODE_008F28: AD BF 0D LDA.W RAM_StatusCoins ; \
CODE_008F2B: C9 64 CMP.B #$64 ; |If coins<100, branch to $8F3B
CODE_008F2D: 90 0C BCC CODE_008F3B ; /
That looks like what we want. Now it says “If coins <100, branch”. So if Mario’s coins are below 100, it will branch. Scroll down a bit and you should see this:
Code
CODE_008F32: AD BF 0D LDA.W RAM_StatusCoins ; \
CODE_008F35: 38 SEC ; |Decrease coins by 100
CODE_008F36: E9 64 SBC.B #$64 ; |
CODE_008F38: 8D BF 0D STA.W RAM_StatusCoins ; /
How ‘bout we hijack this? We are going to hijack $008F32. (Do you see where I got this? Look back up there if you don’t.). Now we should have this so far:
org $008F32
Now we need to get rid of all relevant code. Look at this code:
Code
CODE_008F32: AD BF 0D LDA.W RAM_StatusCoins ; \
CODE_008F35: 38 SEC ; |Decrease coins by 100
CODE_008F36: E9 64 SBC.B #$64 ; |
CODE_008F38: 8D BF 0D STA.W RAM_StatusCoins ; /
See those things underlined? Those are how many bytes it takes up. So it takes up 9. If you’re wondering how I got that just count the hex numbers underlined. After hijacking the correct address and figuring out how many bytes it takes up, we have to jump to our code.
You can use any relevant jump command you'd like, and you should know how they work. JSR takes up three bytes , JSL takes four, BRA takes two, JMP takes three, JML takes four, etc. Normally though, you will usually use JSL or JML. Also note that when using JML, it is EXTREMELY important to jump back to the original code, otherwise you will end up with a crash. Remember this.
Now do this to jump to our code:
Org $008F32
autoclean JSL OurCode
(I used 'OurCode' as a label, but you can use whatever you'd like.)
'autoclean' is needed in front of JSL and JML for asar (it erases old data before patching).
Now JSL only takes up 4 bytes and the code we are hijacking takes up 9. So we just need to fill up or skip the rest. There are five extra bytes so we can do this:
Org $008F32
autoclean JSL OurCode
NOP #5
or:
Org $008F32
autoclean JSL OurCode
BRA skip
NOP #3
skip:
It is important not to leave behind any unwanted bytes, but it is also important not to go over, otherwise you will overwrite other code. For example let’s say the code we wanted to overwrite took up four bytes. We would not do this:
Org $xxxxxx
autoclean JSL Code
NOP #3
That will likely cause your game to crash. After that we have to set the freespace. You will need slogger to find freespace in your ROM. So we should now have this if you are using xkas:
Org $008F32 ; Routine to hack
JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
Org $Freespace ; your freespace
OurCode:
for asar:
Org $008F32 ; Routine to hack
autoclean JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
freecode
OurCode:
'freecode' will search for freespace for you. Much easier eh?
Now remember those extra bytes we got rid of? Before writing our custom code, we need to restore that overwritten code. If we don't put it back, then that code won't be executed (although sometimes you do want this). So the code we need to put back is this:
LDA.W RAM_StatusCoins ; \
SEC ; |Decrease coins by 100
SBC.B #$64 ; |
STA.W RAM_StatusCoins ; /
Now there are some things we have to do first. If you are using xkas you will need to get rid of the .B's, .W's, .L's or make them lowercase. Now we should have this:
LDA RAM_StatusCoins ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA RAM_StatusCoins ; /
We now need to get replace those definitions. Go back to all.log and search for “RAM_StatusCoins”. Do this until you get to the LAST search result. You should see this:
7E0DBF RAM_StatusCoins
Now replace “RAM_StatusCoins” with “$0DBF”. We should have this:
LDA $0DBF ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA $0DBF ; /
There now we can put this into our hack. So now are code should look like this:
Org $008F32 ; Routine to hack
JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
Org $Freespace ; your freespace
OurCode:
LDA $0DBF ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA $0DBF ; /
Now we can write our code. First let’s make it so Mario can’t get a 1-up. To do that we would do this:
DEC $0DBE
Good now he won’t get a 1-up after getting 100 coins! Now let’s finish the code:
LDA $19 ; If Mario has a…
CMP #$03 ; Flower!
BEQ Flower ; Branch
INC $19 ; Otherwise increase his power up status and…
RTL ; Return
Flower:
LDA #$FF ; \ Set star timer
STA $1490 ; /
LDA #$0D ; \
STA $1DFB ; / Change music
ASL $0DDA
SEC
ROR $0DDA
RTL ; Return
You should be able to understand what happened here. Now our WHOLE code should be this:
org $008F32 ; Routine to hack
autoclean JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
freecode
OurCode:
LDA $0DBF ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA $0DBF ; /
DEC $0DBE
LDA $19 ; If Mario has a…
CMP #$03 ; Flower!
BEQ Flower ; Branch
INC $19 ; Otherwise increase his power up status and…
RTL ; Return
Flower:
LDA #$FF ; \ Set star timer
STA $1490 ; /
LDA #$0D ; \
STA $1DFB ; / Change music
ASL $0DDA
SEC
ROR $0DDA
RTL ; Return
Try it out. Did it work? If so you just made your first patch!
Rats Tag:
If you are using asar just skip this, asar inserts RATS tags for you, unless you want to know what they do.
Now there is one more thing we can do to make this code even better. And that is add a rats tag. A rats tag is an extremely useful and important thing to put in patches because at some point, Lunar Magic or any other tool can overwrite your patch data. When this happens, your patch probably won't function anymore or something bad might happen like the ROM crashing.
To set up a RATS Tag, you protect each and every byte in your routine. It is set up RIGHT after the org $freespace, like this:
JSL CustomCode
org $168000 ; <- Freespace.
!CodeSize = End-Start ; <- RATS Tag define.
db "STAR"
dw !CodeSize-$01
dw !CodeSize-$01^$FFFF
Start: <- Beginning of RATS Tag, and bytes to protect.
;=========;
;PATCH CODE GOES HERE
;=========;
End: ; <- End of RATS Tag and number of bytes to protect..
As you can see, you mark the ending and beginning of the RATS Tag in the !CodeSize define. The start of my RATS Tag is called Start and the end of my RATS Tag is called End.
You can also notice that unlike labels, you put a colon (":") when making the RATS labels. It is Start: and End:, not Start and End!
So our code with a RATS Tag will look like this:
Header
Lorom
Org $008F32 ; Routine to hack
JSL OurCode ; Jump to our code
NOP #5 ; Get rid of extra 5 bytes
Org $Freespace ; your freespace
!CodeSize = End-Start ; <- RATS Tag define.
db "STAR"
dw !CodeSize-$01
dw !CodeSize-$01^$FFFF
Start:
OurCode:
LDA $0DBF ; \
SEC ; |Decrease coins by 100
SBC #$64 ; |
STA $0DBF ; /
DEC $0DBE
LDA $19 ; If Mario has a…
CMP #$03 ; Flower!
BEQ Flower ; Branch
INC $19 ; Otherwise increase his power up status and…
RTL ; Return
Flower:
LDA #$FF ; \ Set star timer
STA $1490 ; /
LDA #$0D ; \
STA $1DFB ; / Change music
ASL $0DDA
SEC
ROR $0DDA
RTL ; Return
End: ; <- End of RATS Tag and number of bytes to protect..
Don't forget putting RATS Tags inside your code, it's even been made a rule to submit patches with a RATS Tag. If you find it difficult to make one, just copy/paste from another patch ;)
Re-apply the patch, this time with a RATS Tag, and your code is now safe in the ROM.
And that is it you are pretty much done! Post below if you need any help with anything.