Language…
7 users online: anoMaly666, anonimzwx, DanMario24YT, Gamet2004, Saela, Scags, Tomi P - Guests: 269 - Bots: 390
Users: 64,795 (2,378 active)
Latest user: mathew

How to *add* code without overwriting.

Hi everyone!

I will admit that I'm only about 3-4 days into learning about ASM, so I'm sorry for these noobie questions.

I have read various tutorials and tried to search, but couldn't find an answer to this question...

If patching can only overwrite code, how do I add code via patch if I don't want to overwrite what's in that org?

For example, I wanted touching a coin to decrease PowerUp status, and if small, die.

I'll include the code below. I am patching the original SMW code.

I hijack at 008F28 and the code seems to work fine. Except, I have 99 lives. I'm guessing this is because I overwrote the 4 lines below the hijack which deals with lives, I think.

So how can I insert code without impacting the other code around it? I understand if I'm replacing functionality, but in this case I'm adding to it.

Also, how does this impact balancing the bytes?

My apologies if this isn't super clear, just let me know if it's not. :S

Thanks in advance!

Code
Org $008F28		                ; routine to hack
autoclean JSL OurCode	; jump to our code
NOP #14

freecode

OurCode:
LDA $0019	; load powerup status
CMP #$0        ; is powerup status >0?
BEQ .kill	        ; if powerup status is small, kill Mario
DEC $0019	; decrease powerup value
RTL

.kill
LDA #$90			;
STA $7D				;
LDA #$09			;
STA $1DFB			;
LDA #$FF			; 
STA $0DDA			;
LDA #$09			; KillMario
STA $71				;
STZ $140D			;
LDA #$30			;
STA $1496			;
STA $9D				;
STZ $1407			;
STZ $188A			;
RTL	
Originally posted by Doherty192
If patching can only overwrite code, how do I add code via patch if I don't want to overwrite what's in that org?

the safest way to *add* code into smw is to include the code you hijacked into your custom code, so no original code is actually lost. then add whatever you like into your custom code

you're hijacking $008F28 again and only used 14 NOPs, but you mentioned overwriting stuff, so i dont know what your ROM currently looks like

Originally posted by smwdisc.txt
Code
CODE_008F28:        AD BF 0D      LDA.W RAM_StatusCoins     ; \  
CODE_008F2B:        C9 64         CMP.B #$64                ;  |If coins<100, branch to $8F3B
here is the original code again, except your goal is to hijack as few bytes as possible, since you want to add code. this is 5 bytes, but you can see they're in 2 blocks. you want to preserve how the blocks are, since that affects how the code could be read. if you use the wrong number of NOPs, you will likely overwrite half a block and cause that code to be read incorrectly. remember that JSL takes 4 bytes regardless, so you need 1 NOP to safely hijack here

if you only want to hurt mario, i highly recommend just replacing your entire custom code with "JSL $00F5B7" instead. this will call one of many smw subroutines; this one is used to hurt mario, since the original coders know that writing out the entire hurt routine every single time they need something to hurt mario would be a drag, since a lot of things can hurt mario

so um if you want coin collecting to function normally and still hurt mario (which will occur with all ways of obtaining coins, like yoshi eating a sprite), your code should look like this:
Code
;tested on a clean lorom
Org $008F28		; routine to hack
autoclean JSL OurCode	; jump to our code
NOP

freedata

OurCode:
JSL $00F5B7 ; hurt mario subroutine
LDA $0DBF   ; \ 
CMP #$64    ; / restored code
RTL

~<3
Hi chillyfox!

Thanks so much for getting back!

The challenge was to have Mario's powerup status decrease by 1 each time. So if flower, would get cape, then big mario, then small, then dead. Though if my goal was just to have hurt mario, I wouldn't have known about the power of subroutines, so that helps a ton!

Originally posted by chillyfox
the safest way to *add* code into smw is to include the code you hijacked into your custom code, so no original code is actually lost. then add whatever you like into your custom code


Not sure I understand. So using my previous custom code, it works as intended, except that it gives me 99 lives. This was done on a regular vanilla SMW rom. I thought that because my code was being added in (I'm leaving the code that's there where I hijacked in place, just adding my code before it) that it overwrote some lines.

So I don't want to replace that code, just added code before it, if that makes sense?

Thanks again!
your kill code is the exact same as smw's, so you could replace that section with "JSL $00F606" (the kill mario subroutine). you can also shorten ram address $0019 to $19. i should have shown this image earlier too: http://prntscr.com/nfjngj. if this patch is meant to go onto a clean rom, then it has an error, because you only use 14 NOPs instead of 15. i wont post the original code again, but your JSL and 14 NOPs hijack will stop in the middle of an asm block, which can sometimes crash the game. fixing your hijack in this case will solve the 99 life glitch

so i should probably distinguish what i say: the "hijack" is above the freedata part, your "custom code" is below it (which is stored by Asar into freespace elsewhere). the "hijack" overwrites smw's code and gives it new instructions to JSL to your "custom code" instead, so that original code is lost. if you want it back, then include the hijacked code you overwrote into your "custom code", so technically, you are not losing any original code at all. this is essentially "adding new code only"

you can look back at the previous code i posted as an example: all i wanted to do was call another JSL to hurt mario, but since i am hijacking original code, i needed to restore the original smw code by including it in my custom code
~<3
Ahh, I think I'm getting it...

Question though... where did you get the 15 NOPs? Instead of my 14.

I counted 10 bytes in the original code, plus 4 from the JSL.

Where did the extra one come from?

Thanks again!
here is a visualization of what your hijack is doing to the original code. the total code is 19 bytes. JSL takes up 4, so you need 15 NOPs to cancel out the rest of the original code
~<3
Gotcha! It makes sense looking at it like that.

I guess I was thinking that the code I was replacing didn't go that far down.

I thought I was only replacing $8F28 to $8F2F; which is LDA to INC.

I didn't know it covered the next LDA as well.
Originally posted by Doherty192
I thought I was only replacing $8F28 to 8F2F; which is LDA to INC.

if you want to stop at $008F32, then you only need 6 NOPs. however, the rest of the original code (which subtracts 100 coins from your total) will execute as normal now, when it's usually a conditional code that only executes once you collect 100 coins. this is why i lumped that in with the 100 coins check that you've been hijacking, because it's dependent on that check

EDIT: an easy way to tell what code can be depending on is to see where branches are and where they jump to. in this case, there's a branch (BCC) that goes to just outside of the code i've been posting, so everything between that and where the branch goes is one code
~<3
Oh OK, I think I'm getting it now.

Originally posted by chillyfox
if you want to stop at $008F32, then you only need 6 NOPs. however, the rest of the original code (which subtracts 100 coins from your total) will execute as normal now, when it's usually a conditional code that only executes once you collect 100 coins


This makes a lot of sense! ^^ I guess I wasn't paying attention to the conditional code.

Thanks again for your help, chillyox! Hopefully I'll eventually become good enough to be able to contribute to this forum like you do!