Language…
15 users online: Alex No,  AmperSam, Big Brawler, GiraffeKiller, Green, h.carrell, Hammerer, LadiesMan217, Mecke1990, Metal-Yoshi94, Ray Hamilton,  Segment1Zone2,  StayAtHomeStegosaurus, steelsburg, Tulip Time Scholarship Games - Guests: 286 - Bots: 570
Users: 64,795 (2,369 active)
Latest user: mathew

Patch making tutorial

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:
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.
i dont know much about asm but as far as i know, there are somethings you shouldnt hijack like the nmi routine, why not explain what things should be hijacked and what shouldnt or preferably shouldnt. also,

Originally posted by tutorial
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 things underlined. For example our code had this for are bytes:


what things underlined? it took me a few to figure out what you meant since nothings underlined from what i can see, maybe the code tags make underlines and other stuff not appear within the tag?
I think a smiley messed up a sentence on which I got confused. try putting two "s before and after the colon.
both autoclean JSL and freespace came back as errors in asar even when I copied and pasted the code from the example it was having trouble patching, what problem am I running into?
"Reluctance gets you nowhere, if you never ask for help you won't ever receive help. if you never try you may never fail but you'll never succeed either"
--Falkenheart
http://www.smwcentral.net/?p=post&do=reply&t=62550 finishing up my first patch any help is appreciated
Replace freespace either with freecode or freespace ram (you'll need those most of the time).
You can also use freedata or freespace noram, but those will try to put data in banks $40+ (where the last 2MB of the ROM are mapped), which lack RAM mirrors for $0000-$1FFF, so only do it if the data bank register isn't changed using i.e. PHK PLB.
I was porting over koyuki's turnsfx patch into asar and I know you can just apply the patch by putting @xkas at the top but I didn't really like how that works out because I would still have to define my own free space, so I rewrote it so asar would just do that automatically, however when I did that the patch applied fine except for one thing, it said my free space is leaked, is that something to be concerned about? I did try both the terms freecode and freespace ram thinking that might solve the problem, but I still got the free space is leaked and something that basically said it would throw out a bunch of warnings, but from what seems like it applied no problem. I'm also working on porting over climbsfx into asar, and I can be more specific when I get around to finishing the transfer of that into asar language and since I'm a little wary on entering either freedata or freespace noram I just figured I would see what other options may be available or what I can do differently
"Reluctance gets you nowhere, if you never ask for help you won't ever receive help. if you never try you may never fail but you'll never succeed either"
--Falkenheart
http://www.smwcentral.net/?p=post&do=reply&t=62550 finishing up my first patch any help is appreciated
Unless I'm mistaken, the freespace leaked warning means that asar just filled a bank, so you usually don't need to worry about that.
Also, it might be worth mentioning that freecode is a shortcut to freespace ram (they're the same thing).
Same goes for freedata and freespace noram.
Originally posted by Lui37
Unless I'm mistaken, the freespace leaked warning means that asar just filled a bank, so you usually don't need to worry about that.

Why would I throw a warning for anything you're not supposed to worry about?
It means that, as far as Asar knows, not all freespace used by this patch will be removed if the patch is reapplied. This means that you'll lose a chunk of freespace every time the patch is reapplied, despite these lost chunks not being used by anything, which is a pointless waste.
<blm> zsnes users are the flatearthers of emulation