Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
1 user currently in Super Mario World hacking: labmaster | 3 guests
Acmlm's Board - I2 Archive - Super Mario World hacking - Code Replacement? [Issue, ASM] | |
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
User Post
Escherial

Shyguy
Level: 17

Posts: 82/90
EXP: 20866
For next: 3877

Since: 03-15-04
From: Pasadena, CA

Since last post: 202 days
Last activity: 38 days
Posted on 03-20-05 09:05 AM Link | Quote
Normally I'd feel silly about asking such a trivial question, but this is starting to bug me. Without further ado...

I've been trying to change the INC $19 at $00D156 (ROM address) to a JSL to another location far, far away in the ROM. Unfortunately, the instruction for an absolute long JSL is four bytes and the INC $19 is only two. Granted this, I was forced to move the instruction directly after (LDA #$0) into my target subroutine. This seemed to work fine at the time, but some code later on jumps to that old LDA #$0, which now happens to be the middle of the JSL command, and ends up moving execution to some random section of crash-happy code.

So, to put it simply, how do you replace a short segment of code with a longer one without hitting these kinds of issues? I'm assuming that blocktool's and Lunar Magic's ASM hacks jump to unused portions of the ROM, but how do you make sure that you're not screwing up some code following it? Are there unused portions of the ROM local to $00D156 so I can just use a direct JSR rather than the longer JSL?

On an unrelated note, anyone know where I can find a copy of 65c816.hlp? (It's a windows help file of all the 65c816 instructions and their hex equivalents.) I left my computer at school and now the dorm's locked up, so I can't get it. I believe it was downloadable on HabsoluteFate's jSmwDev site, but that doesn't exist anymore, as far as I can see .

Thanks in advance
FuSoYa
Defender of Relm
Level: 26

Posts: 159/255
EXP: 99529
For next: 2746

Since: 03-15-04
From: Moon

Since last post: 7 days
Last activity: 7 hours
Posted on 03-20-05 12:15 PM Link | Quote
Originally posted by Escherial

So, to put it simply, how do you replace a short segment of code with a longer one without hitting these kinds of issues? I'm assuming that blocktool's and Lunar Magic's ASM hacks jump to unused portions of the ROM, but how do you make sure that you're not screwing up some code following it?


By carefully checking out the surrounding code beforehand. The 2 byte branch instructions don't have much range. Of course, longer branches are possible, and sometimes you simply miss something. Which is why extensive testing is always recommended.

Anyway, just by taking a quick glance in SPASM, I can see at least 4 branches at $D145, $D16D, $D18A, and $D270 that could give you trouble. If all the places calling this subroutine don't care about the value in A upon returning (unlikely, but I haven't looked), it might be tempting to redirect all the branches to $D15A and change it to a STZ. But I'd suggest just looking into hooking the code at an earlier point to avoid the issue (is $D14A the only branch to $D156?).
MathOnNapkins

Math n' Hacks
Level: 67

Posts: 1619/2189
EXP: 2495887
For next: 96985

Since: 03-18-04
From: Base Tourian

Since last post: 1 hour
Last activity: 32 min.
Posted on 03-20-05 05:28 PM Link | Quote
What I would recommend doing, assuming the operation after the A9 00 is 2 bytes long and moving it won't cause further mayhem, is to change the INC $19 to NOP; SEI; and hook at the LDA with your JSL. You will have to take the next one or two instructions along for the ride depending on their lengths. Now what I am about to describe only works if I assume interrupts are never disabled at this point. Check your logs to make sure they never are at this point. Usually interrupts are only disabled in interrupts themselves (to avoid interrupts being called from interrupts) or during code at the beginning of the game when vital setup routines have to occur without interruption.

Once you reach your routine, do a PHP (push status reg) Then do PLA to get that byte off of the stack. Look at the bit that corresponds to the interrupt disable flag. I don't remember what bit it is off hand but you can do an AND to mask out the other bits. Then it's simply a matter of doing BEQ. If after masking, you get a zero result, you know that it wasn't called from where that INC used to be (It must have been called from one of those places that gave you problems earlier). If you get a nonzero result, you know if must have passed through where the INC used to be. I'm sure you can figure out what to do from there. Just make sure you call CLI if you do get the nonzero result. Otherwise you could have some problems.

You have another option, though. I'm too tired to edit the above, but it is easier and unfortunately you will read it second. I've noted that the instruction you are hooking near (LDA #00) is assumedly two bytes long. This means that the M flag is set. If it is LDA #0000 we must assume the opposite. Whatever it is, use that to your advantage and do the same as the above, except test for the M flag's bits (instead of NOP; SEI; do REP #$20). The I flag is dangerous to toy with, and the M flag is not. All you have to do is make sure it's set (M = 1) by the time your routine returns. (Well, by the time you get to your LDA #00 + other instructions + RTL specifically)

good luck. I love asm challenges.

edit: if you're still looking for hex equivalents, try googling: brett tabke 65816.


(edited by MathOnNapkins on 03-20-05 08:30 AM)
(edited by MathOnNapkins on 03-20-05 08:54 AM)
(edited by MathOnNapkins on 03-20-05 11:59 AM)
FuSoYa
Defender of Relm
Level: 26

Posts: 160/255
EXP: 99529
For next: 2746

Since: 03-15-04
From: Moon

Since last post: 7 days
Last activity: 7 hours
Posted on 03-20-05 11:47 PM Link | Quote
Originally posted by MathOnNapkins
You have another option, though. I'm too tired to edit the above, but it is easier and unfortunately you will read it second. I've noted that the instruction you are hooking near (LDA #00) is assumedly two bytes long. This means that the M flag is set. If it is LDA #0000 we must assume the opposite. Whatever it is, use that to your advantage and do the same as the above, except test for the M flag's bits (instead of NOP; SEI; do REP #$20). The I flag is dangerous to toy with, and the M flag is not. All you have to do is make sure it's set (M = 1) by the time your routine returns. (Well, by the time you get to your LDA #00 + other instructions + RTL specifically)



A good solution... wouldn't have thought of that myself.

He'll have to be careful to throw a byte from A back on the stack though if it's set to 16 bit when he pulls it off (or just do two PHPs).



(edited by FuSoYa on 03-20-05 02:48 PM)
MathOnNapkins

Math n' Hacks
Level: 67

Posts: 1628/2189
EXP: 2495887
For next: 96985

Since: 03-18-04
From: Base Tourian

Since last post: 1 hour
Last activity: 32 min.
Posted on 03-20-05 11:53 PM Link | Quote
Hmm, yeah good point. I didn't think about that since it didn't come into play if you use the I flag.
Escherial

Shyguy
Level: 17

Posts: 83/90
EXP: 20866
For next: 3877

Since: 03-15-04
From: Pasadena, CA

Since last post: 202 days
Last activity: 38 days
Posted on 03-21-05 02:38 AM Link | Quote
I'm pretty sure that the processor's in 8-bit mode at $00D156, so I'll go with the REP #$20 and not worry about fixing the stack, etc. Preserving the A register shouldn't be a problem, either, since the instruction I'm replacing was going to set A to #$0 in any case (and I'm not going 16-bit in my new code, so there's no danger of screwing up the high byte).

So, in general, I'll have to remember that the solution to problems like these is to check the 8/16-bit flag, pad accordingly to fix immediate issues, and watch out for jumps from other sections of code to the one in which I'm working.

Thanks to both of you for all the information; I'm honored to be treated to such detailed and informative responses. Naturally, I'll post on my status once I get a chance to work with it again.
Glyph Phoenix

Level: 39

Posts: 131/745
EXP: 385876
For next: 18895

Since: 11-07-04

Since last post: 2 hours
Last activity: 2 hours
Posted on 03-21-05 02:44 AM Link | Quote
Then does a brief and uninformative response like this one dishonor you?
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 3831/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 03-21-05 09:05 AM Link | Quote
Maybe, maybe not, but it does anger the spam gods.
Originally posted by Escherial
I'll go with the REP #$20 and not worry about fixing the stack, etc.

Er, I'm pretty sure you will have to fix the stack if you're calling in 16-bit mode and returning in 8-bit.
FuSoYa
Defender of Relm
Level: 26

Posts: 165/255
EXP: 99529
For next: 2746

Since: 03-15-04
From: Moon

Since last post: 7 days
Last activity: 7 hours
Posted on 03-21-05 11:13 AM Link | Quote
Originally posted by HyperHacker
Er, I'm pretty sure you will have to fix the stack if you're calling in 16-bit mode and returning in 8-bit.


Not really, the M/X flags don't affect JSR/RTS/JSL/RTL. Or are you talking about something else?

Regarding fixing the stack, I think he just meant that he's going to do something like PHP, SEP #$20, PLA at the start of his subroutine. Then he'll be back in 8 bit mode again for his own code, and won't have to do any more playing with the stack.
MathOnNapkins

Math n' Hacks
Level: 67

Posts: 1630/2189
EXP: 2495887
For next: 96985

Since: 03-18-04
From: Base Tourian

Since last post: 1 hour
Last activity: 32 min.
Posted on 03-21-05 11:26 AM Link | Quote
^Right, that's the elegant fix I was thinking of but somehow couldn't yesterday.
Escherial

Shyguy
Level: 17

Posts: 86/90
EXP: 20866
For next: 3877

Since: 03-15-04
From: Pasadena, CA

Since last post: 202 days
Last activity: 38 days
Posted on 03-23-05 03:00 PM Link | Quote
Ok, just to put this matter to rest, I managed to implement your suggestion, MathOnNapkins, and it's working really well Before, I was having a kind of odd re-entry issue with getting mushroomed after coming out of a pipe (interestingly, the game immediately branches to the instruction right after that INC $19, which happened to be my jump before, heh), but this fixes it nicely.

So, thanks again I'm working on replacing the powerups with a hit counter, by the way, if anyone's curious. I should have progress (a test IPS, perhaps?) in about a week or so.


(edited by Escherial on 03-23-05 06:01 AM)
MathOnNapkins

Math n' Hacks
Level: 67

Posts: 1644/2189
EXP: 2495887
For next: 96985

Since: 03-18-04
From: Base Tourian

Since last post: 1 hour
Last activity: 32 min.
Posted on 03-24-05 08:41 AM Link | Quote
Don't mention it. In fact, I think I may use this in the future for some of my hooks when I run into such problems. Luckily almost all code is designed to run in 8bit mode or 16bit mode. If you want, you can just write MON = MathOnNapkins, it's easier to write and I go by it aswell.
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
Acmlm's Board - I2 Archive - Super Mario World hacking - Code Replacement? [Issue, ASM] | |


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 0.020 seconds.