[FINISHED] Read a SNES Button input for an ASM code? (EarthBound)

Started by ShadowOne333, April 13, 2015, 04:35:24 PM

Previous topic - Next topic


My guess would be to change the address that gets loaded, so that it loads 0066 instead and compares it to one of the 4X variations for Y and a Directional input to hopefuly make it work.
Well, the problem with that is that that snippet of code you posted will only run when you eat a skip sandwich, so changing any of that to look for the Y button is a red herring.

What you need is to put that Y button check into a string of code that is constantly running, which is where
$80/94E6 8D 58 0A    STA $0A58  [$7E:0A58]   A:FFFF X:0036 Y:0008 P:eNvmxdIzc
comes in.
That's a piece of code that runs over and over and over when you're wandering around, which means if you splice your y-button/run status code into that, then the game will also check constantly for whether the Y button is being pressed (and if so, will set running status).

OK, so this is a STA command, as I said, these are good commands to replace, but we need to steal a little bit more space in order to have enough bytes to jump to your subroutine at EFF641.

SO, the offset of that opcode is 8094E6...
Set a breakpoint, if you would, for execution of 8094E5 (so we can see the opcode that immediately precedes that one).
At the break click "step in" two or three times, and copy and paste up the three or four ops that show up in the debug window.
Believe it or not, we're getting close to making this work now...

Am I doing a good job of explaining exactly what we're doing here, BTW?
Because what I'm hoping is that by the time we're done with this, I'll have helped you understand a bit better how this stuff works, so that if you have more ideas about things you want to do, you'll have the basis of the skill set to do them.
Ongoing project: "Final Fantasy IV: A Threat From Within"

Latest Demo


Ok so I set the breakpoint to 8094E6 and I ran Step Into for like 4 times I think and got this:
$80/94E6 8D 58 0A    STA $0A58  [$7E:0A58]   A:FFFF X:0030 Y:0002 P:eNvmxdIzc
$80/94E9 20 06 95    JSR $9506  [$80:9506]   A:FFFF X:0030 Y:0002 P:eNvmxdIzc
$80/9506 A6 8A       LDX $8A    [$00:1E8A]   A:FFFF X:0030 Y:0002 P:eNvmxdIzc
$80/9508 BD 72 13    LDA $1372,x[$7E:1374]   A:FFFF X:0002 Y:0002 P:envmxdIzc
$80/950B D0 47       BNE $47    [$9554]      A:0000 X:0002 Y:0002 P:envmxdIZc

And yes! You are explaining yourself quite well, indeed.

One thing, I tried doing the Step Into and Breakpoint from scratch again, and I got a completely different offset this time which stops the game everytime, I think it was somewhere around C056XX or somewhere around that address.
Does that have anything to do? Or can we work with $8094E6 with no issues?

Because I set Breakpoints for $8094E6 in several parts of the game and it stops no matter what, so I guess this one might be good.
Even better, I tried setting that Breakpoint during a battle and it does not stop! :D

Still, I have the little curiosity as to what happens with those other addresses running alongside that one.


Like I said, there's a lot of code that must be constantly running when you're simply standing still in order to keep the game running.

Chances are, one of those strings of code is the check for controller movement, while another one is making NPCs do what they do.

So good, except I wanted a breakpoint set to 8094E5. I want to see the opcode that comes before STA $0A58.

What we're trying to do here is find two opcodes that will be good candidates to replace with a jump to your custom routine.
Whatever we "replace," though, is probably important to the normal workings of the game, so those codes will have to be run instead within your custom routine. We could probably use
$80/9506 A6 8A       LDX $8A    [$00:1E8A]   A:FFFF X:0030 Y:0002 P:eNvmxdIzc
$80/9508 BD 72 13    LDA $1372,x[$7E:1374]   A:FFFF X:0002 Y:0002 P:envmxdIzc

except the opcode immediately after that is a BNE, meaning we would have to splice those ops into the end of your routine in order to not break the game (because the BNE is dependent on whatever is loaded into A as a result of that LDA $1372,x).
Because your routine has multiple return points, it would be messy to try to stick code in at the end (because we'd have to stick it into all possible ending points), so the ideal situation is to find codes we can splice into the beginning of your routine.
What I'm hoping is that the op that comes immediately before STA $0A58 is LDA $[something]. That would be a nice, clean couple of codes that would work just fine no matter where we squeezed them in.
Ongoing project: "Final Fantasy IV: A Threat From Within"

Latest Demo


Oh, I thought you wrote 8094E6 and not 8094E5.
I simply overlooked the last number, a sincere apology from my part.

So, with the offset now corrected, I set the breakpoint to Execute 8094E5 and got the following opcodes upon break (The first LDA $125A is the one when 8094E5 is executed):

$80/94E3 B9 5A 12    LDA $125A,y[$7E:125A]   A:0030 X:002E Y:0000 P:envmxdIZc
$80/94E6 8D 58 0A    STA $0A58  [$7E:0A58]   A:FFFF X:002E Y:0000 P:eNvmxdIzc
$80/94E9 20 06 95    JSR $9506  [$80:9506]   A:FFFF X:002E Y:0000 P:eNvmxdIzc
$80/9506 A6 8A       LDX $8A    [$00:1E8A]   A:FFFF X:002E Y:0000 P:eNvmxdIzc
$80/9508 BD 72 13    LDA $1372,x[$7E:1372]   A:FFFF X:0000 Y:0000 P:envmxdIZc
$80/950B D0 47       BNE $47    [$9554]      A:006C X:0000 Y:0000 P:envmxdIzc
$80/9554 DE 72 13    DEC $1372,x[$7E:1372]   A:006C X:0000 Y:0000 P:envmxdIzc
$80/9557 60          RTS                     A:006C X:0000 Y:0000 P:envmxdIzc

So by the looks of the code, LDA $125A is the opcode that gets loaded before STA #0A58.
So yes, just like you were hoping for, we do have a LDA $XXXX code BEFORE STA, so that is nice.

One question,
Remember I mentioned that the Y Button input changes when you combine it with a D-Pad input?
How would that affect the code? Or should I simply focus first on getting my custom code to execute in-game and THEN focus on the details? :P

PS: I think it is worth mentioning...
I am doing these tests in a room in the game where there are no enemies NOR NPCs at all.
That means it's only the Playable Character(s), along with the room's sprites and music, but that's it.


Ok, perfect. I'm sat work until 4 EDT today, and my WiFi sucks, so I'll explain the next step when I get home.

Don't worry about the d-pad changing that value. Remember that AND function in your custom routine? It's there so that the game doesn't get confused by other buttons being pushed.

April 18, 2015, 05:31:25 PM - (Auto Merged - Double Posts are not allowed before 7 days.)

Alright, here we go...

So, starting at 8094E3 you have

B9 5A 12 8D 58 0A

Assuming your custom routine is going to be in the same place as previously posted, you're going to want to change that to

22 41 F6 EF EA EA

... which in ASM will look like this:
$80/94E3  22 41 F6 EF  JSL $EFF641
$80/94E7  EA           NOP
$80/94E8  EA           NOP

The JSL is the jump to your custom routine.
NOP is "no operation." It is exactly what it looks like.
You see, we've overwritten the first four of six bytes with a subroutine jump, but when the subroutine is done running, the game will jump back to where it left off, which if we don't overwrite will be

$80/94E7  58  CLI
$80/94E8  0A  ASL A

Honestly, I don't even know what the CLI operation does, but it's definitely not something we want to do. Nor do you want to multiply the accumulator by 2, which is what ASL A does.

Believe it or not, NOP does occasionally have actual uses, specifically in performing longer multiplication and division operations, but it also comes in handy for needs like this, when you want to tell the game "don't do anything. just skip to the next op." Don't worry, in real time the amount of time that "nothing" lasts is an imperceptibly small fraction of a second.

Now you've jumped to your custom routine.
But... remember that we have to replace those two operations we just cannibalized before your routine runs.
So at EFF641 you have

AD 40 98  LDA $9840
29 01    AND #$01

etc, etc...

You're going to want to change the beginning of your routine to include those two ops we replaced with the JSL. So, you'll have

$EF/F641  B9 5A 12  LDA $125A,y
$EF/F644  8D 58 0A  STA $0A58

After that, you'll want to write the rest of what you have for your routine already.

Remember that you'll have to change all of the RTSs (opcode 60) in your routines to RTLs (6B). If you jump to a subroutine with a JSL, you need to return with a RTL or selse the game gets confused about where you want it to go back to (and crashes).

So, give it a try and see how it works.
Again, don't be discouraged if it doesn't work right on the first try. We can always debug if necessary.

Lemme know how it goes.
Ongoing project: "Final Fantasy IV: A Threat From Within"

Latest Demo


Damn, I didn't notice that RomHacking posted your new reply as a merged post.
I just saw it. XD

First off, when I first edit $8094E3:
$80/94E3  22 41 F6 EF  JSL $EFF641
$80/94E7  58  CLI
$80/94E8  0A  ASL A

That's the output when I press enter for the JSL opcode.
Now... I assume both CLI and ASL A are being written because of the leftovers of the STA, which are 58 and 0A, since we just overwrote "B9 5A 12" for "22 B0 FF EE" ($EEFFB0: New address since I am working straight into my already hacked ROM).
So you are telling me to overwrite both CLI and ASL (58 and 0A) for NOP (EA)?

If that's so, then that's how I did it.

With that said, here's what I wrote in $C094E3:
$80/94E3  22 B0 FF EE  JSL $EEFFB0
$80/94E7  EA  NOP
$80/94E8  EA  NOP

And at $EEFFB0 I got this:
$EE/FFB0  B9 5A 12  LDA $125A,y
$EE/FFB3  8D 58 0A  STA $0A58

$EE/FFB6  AD 40 98  LDA $9840
$EE/FFB9  29 01  AND #$01
$EE/FFBB  C9 01  CMP #$01
$EE/FFBD  D0 01  BNE $FFC0

$EE/FFC0  AD 66 00  LDA $0066
$EE/FFC3  29 40  AND #$40
$EE/FFC5  D0 09  BNE $FFD0
$EE/FFC7  AD 40 98  LDA $9840
$EE/FFCA  29 01  AND #$01
$EE/FFCC  8D 40 98  STA $9840

$EE/FFD0  AD 40 98  LDA $9840
$EE/FFD3  09 03  ORA #$03
$EE/FFD5  8D 40 98  STA $9840

In a HEX editor, the addresses are correct.
One thing though...

For some reason, ASMDevKit keeps splitting up the first LDA opcode in my custom code like this:

I noticed that it has to do with the 16-bit/8-bit arrangement in the software, because I sometimes get a 29 01 C9 in the first AND opcode instead of the broken LDA, and that happens with 16-bit arrangement, while with 8-bit arrangement I get the broken LDA.
However, the HEX editor shows up the HEX values for the opcodes just fine in EEFFB0 and onwards.

Is that an issue?

Edit: Just ran the ROM with Snes9X Debugger, doesn't even load up the Title Screen. XD


QuoteEdit: Just ran the ROM with Snes9X Debugger, doesn't even load up the Title Screen. XD

Ugh... I'm wondering if maybe the DEVkit inserted extra bytes into your ROM or something (thus resulting in a ROM that is, like, one or two bytes longer than it's supposed to be. If it was just a problem with the code, then the game would run fine until that code runs, then would crash. But not even loading the title screen seems to indicate to me that the ROM was made into an invalid file, which most likely is the result of an unacceptable file size.
First thing I would do to check that would be to open the ROM in a regular hex editor and see how many bytes long the file is. It should be a nice round number (a multiple of 10000 assuming it has no header). If it's not, then extra bytes got inserted somewhere.
Check the places you just edited - 8094E3 and EEFFBO - to see if there are things there that you know should not be (remnants of old code that should have been overwritten, but maybe stuff got inserted in front of them instead).

The way things look on that DEVkit screenshot shouldn't be an issue. If you'll notice, the offset you're viewing there is EEFFAF, not EEFFB0. Because the program is looking at the code starting from the wrong offset, it's doing its best to interpret what it sees. If you use the Goto in the menu and tell it to go to EEFFBO, things should appear just fine.

But anyway, we have to figure out why the game isn't loading up before we can do anything else. Let me know what you find.
Ongoing project: "Final Fantasy IV: A Threat From Within"

Latest Demo


It's not DevKit, I already edited manually the offsets with a HEX editor so that they match the ASM code, and the game still reacts in the same way.

I tried loading up 3 different save states, one in a cutscene, another one in a random town and the last one during a fight.
Turns out only the one inside the fight loads up fine, all others are messed up.

So it is not any traces of old code NOR the offset, since I tried a different one, and I even tried using the ROM address + C00000 and with BFFE00, none of those work.

My guess goes into saying that there is something wrong with the jump in $94E3 that is causing that.
22 B0 FF EE and the two EA EA are not making the jump properly to the new offset, screwing up everything that loads the LDA and STA in game (hence why only the battle system works).

That's what I can tell at least from my tests.



OK, I'm going to try to walk through the debugging process with you...

So, we're pretty sure it's got to do with the jump and/or the custom code.

So you're going to set a breakpoint to the point where the game executes the jump op (8094E3).

You may need to load up the save state that's in-battle, then set the breakpoint, then finish the battle - or set the breakpoint then click reset - in order to make the break actually happen observably.

At the break, click Step In.

If things are working right up to that point, then your debug window should read
$80/94E3  22 BO FF EE  JSL $EEFFB0
$EE/FFB0  B9 5A 12     LDA $125A,y

If you see that, then keep clicking Step In, you should see the progression of code responding the way it should (It will not read the burnt status, presumably, then will move on to the y button check, which will return false, then will return back to those two NOPs).

Once you see something that isn't happening right, that's the bug that's causing the problem.

Post the debug window output here, and we'll see if we can get to the bottom of this.
Ongoing project: "Final Fantasy IV: A Threat From Within"

Latest Demo


Did just that and here's the output:

$80/94E3 22 D0 FF FF JSL $FFFFD0[$FF:FFD0]   A:FFFF X:0000 Y:0000 P:envmxdIZc
$FF/FFD0 B9 5A 12    LDA $125A,y[$7E:125A]   A:FFFF X:0000 Y:0000 P:envmxdIZc
$FF/FFD3 8D 58 0A    STA $0A58  [$7E:0A58]   A:FFFF X:0000 Y:0000 P:eNvmxdIzc
$FF/FFD6 AD 40 98    LDA $9840  [$7E:9840]   A:FFFF X:0000 Y:0000 P:eNvmxdIzc
$FF/FFD9 29 01 C9    AND #$C901              A:0000 X:0000 Y:0000 P:envmxdIZc
$FF/FFDC 01 D0       ORA ($D0,x)[$7E:00A3]   A:0000 X:0000 Y:0000 P:envmxdIZc
$FF/FFDE 01 6B       ORA ($6B,x)[$7E:0000]   A:2200 X:0000 Y:0000 P:envmxdIzc
$FF/FFE0 AD 66 00    LDA $0066  [$7E:0066]   A:2200 X:0000 Y:0000 P:envmxdIzc
$FF/FFE3 29 40 D0    AND #$D040              A:0000 X:0000 Y:0000 P:envmxdIZc
$FF/FFE6 09 AD 40    ORA #$40AD              A:0000 X:0000 Y:0000 P:envmxdIZc
$FF/FFE9 98          TYA                     A:40AD X:0000 Y:0000 P:envmxdIzc
$FF/FFEA 29 01 8D    AND #$8D01              A:0000 X:0000 Y:0000 P:envmxdIZc
$FF/FFED 40          RTI                     A:0000 X:0000 Y:0000 P:envmxdIZc
$9F/8094 85 49       STA $49    [$00:1E49]   A:0000 X:0000 Y:0000 P:eNVMxdIZc
$9F/8096 DA          PHX                     A:0000 X:0000 Y:0000 P:eNVMxdIZc
$9F/8097 00 59       BRK #$59                A:0000 X:0000 Y:0000 P:eNVMxdIZc

Well.. At least the custom code is now running. XD
After BRK, Snes9X crashes and closes.
It does jump into the subroutine, but somehow it is getting messed-up 16-bit opcodes starting from AND and it is getting the wrong opcodes due to that afterwards.

Oh and just to be clear, I moved the entire ASM code to the end of the ROM to be sure it doesn't intertwine with any other data, hence the $FFFFD0 offset. At least it shows up the beginning of the custom code, so the offset is not the issue.
However, if I click into the "Disassembly"option and choose the offset I put them into, it shows up the correct ASM code along with its correct opcodes.

$FF/FFD0 B9 5A 12    LDA $125A,y[$00:125A]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFD3 8D 58 0A    STA $0A58  [$00:0A58]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFD6 AD 40 98    LDA $9840  [$00:9840]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFD9 29 01       AND #$01                A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFDB C9 01       CMP #$01                A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFDD D0 01       BNE $01    [$FFE0]      A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFDF 6B          RTL                     A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFE0 AD 66 00    LDA $0066  [$00:0066]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFE3 29 40       AND #$40                A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFE5 D0 09       BNE $09    [$FFF0]      A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFE7 AD 40 98    LDA $9840  [$00:9840]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFEA 29 01       AND #$01                A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFEC 8D 40 98    STA $9840  [$00:9840]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFEF 6B          RTL                     A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFF0 AD 40 98    LDA $9840  [$00:9840]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFF3 09 03       ORA #$03                A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFF5 8D 40 98    STA $9840  [$00:9840]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFF8 6B          RTL                     A:0000 X:0000 Y:0000 P:EnvMXdIzc

This is really odd. :/


Got it... Turns out that when the jump happens, the accumulator is in 16-bit mode.
It's not a problem, but it will require a little bit of reworking of the custom routine.

First, a little bit about what this all means.

So, A, the accumulator... As I'm sure you know by now, this is a a register that the SNES uses for many purposes... Primarily to load specific values into various locations in RAM. SNES can also use x and y for this purpose, but unlike x and y, SNES can also perform simple mathematic operations (adding, subtracting and multiplying and dividing by 2) on A.
So I don't claim to know how old you are, but if you're old enough to remember the actual debut of the SNES, you'll remember that thee advancement of the technology to "16-bit processing" was the biggest buzz surrounding it.
Now, I was 12 (or so) at the time, so I really had no idea what that meant beyond the fact that it meant compared to NES, SNES was a much faster and more powerful machine.
Well, the primary reason for the increase in speed and power is SNES's ability to perform mathematic operations on as many as 16 bits at a time (or, two bytes).
So, whereas with NES, A was always a single byte, with SNES, A could be two bytes if you needed it to be. The audiovisual possibilities that were opened up by this advancement were... Well, you know the observable difference between the two.

SO, the point is, A can be two bytes long if you need it to be. BUT, sometimes, you don't want it to be. Sometimes (lots of times, actually) you only need A to be a single byte.
Your custom routine runs on the assumption that A will be a single byte (8-bit mode) when it's running, but at the time the jump is performed, A is actually in 16-bit mode. That means that all operations on A at the time will be 16-bit operations, and therefore all operations that use a constant (#$[number]) will use two-byte parameters instead of one-byte parameters. With that in mind, look again at the debugger output and you'll see that it's all of those CMPs, ANDs and ORAs that are getting the code out of whack, because we used one-byte parameters.

Like I said, the fix won't be too tough.

So, there are two possible ways to go about fixing this. Neither one is necessarily better than the other, really. One method may end up producing a routine that is a few bytes shorter than the other in the end, and generally shorter code is better code, because it leaves more free space to write more code later if you need to or want to. I'll explain both methods. For the record, I prefer the second method, but like I said, it doesn't really matter.

1) change the parameters of all of your CMPs, ANDs and ORAs to two bytes. I count five altogether, so this won't be too hard to do. If you're writing it out in the DEVkit, make sure you click the 16-bit accumulator toggle.
As for what the other byte should be... Generally, it'll be 00.
$FF/FFD6 AD 40 98    LDA $9840  [$00:9840]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFD9 29 01       AND #$01                A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFDB C9 01       CMP #$01                A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFDD D0 01       BNE $01    [$FFE0]      A:0000 X:0000 Y:0000 P:EnvMXdIzc

$FF/FFD6 AD 40 98    LDA $9840  [$00:9840]   A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFD9 29 01 00    AND #$0001              A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFDC C9 01 00    CMP #$0001              A:0000 X:0000 Y:0000 P:EnvMXdIzc
$FF/FFDF D0 01       BNE $01    [$FFE0]      A:0000 X:0000 Y:0000 P:EnvMXdIzc

Note that, in code, the parameters' bytes are written in reverse order, like the parameters of the JSL.

The only exception to everything I just said would be this op:
$FF/FFEA 29 01       AND #$01                A:0000 X:0000 Y:0000 P:EnvMXdIzc

I would change it to
$FF/FFED 29 01 FF    AND #$FF01              A:0000 X:0000 Y:0000 P:EnvMXdIzc

The reason is, here you are actually affecting RAM with an AND operation (in all other instances of AND in this routine you're only observing RAM with AND). But you really only want to affect the single byte at 9840. If you AND the two bytes at 9840-9841 with 0001 and 9841 happens to have any value besides 00 in it at the time, you will zero that out. If you AND 9840-9841 with FF01, then 9841 will be unaffected. FF is the identity property of AND. Any number AND #$FF equals itself.

Or, you could do...

2) switch out of 16-bit mode for your custom routine.
The way SNES switches between 16-bit A and 8-bit A is with the SEP and REP opcodes. Specifically, SEP #$20 makes A 8 bits, and REP #$20 makes A 16 bits.
Why 20? Well, there are 8 different processor flags that can be set and reset (turned on and off) with the SEP and REP commands. The size of the accumulator is controlled by the sixth flag. The parameter is bitwise, so SEP #$20 means SEP %00100000 (set the sixth flag). The only other flag I have ever set or reset with these ops is #$10, which does essentially the same thing to the x and y registers. But we're going to leave those alone for now...
Now, the thing to keep in mind about changing to an 8-bit accumulator is, when it's time to return to the original code (when your routine is done running), the code there will be expecting a 16-bit accumulator, so you'll have to insert a REP #$20 in front of every RTL in your routine, so the last thing the game does before jumping back to its regular routine is switch back to the proper processing status.

So there you have it.

One small problem, two possible solutions.
Bear in mind that in either case, you'll likely have to adjust all of your branching ops (BNE, BEQ, etc) to account for the different length of code.

I know that was a lot, and I do go on... Did that all make sense?
Ongoing project: "Final Fantasy IV: A Threat From Within"

Latest Demo


So the 16-bit opcodes were indeed the problem.

Method #1 seems to have done the trick. :)
I got confused with the SEP/REP thing though, if I wanted to implement that method, how would my code look to make the ASM read 8-bit instead of 16-bit with those opcodes?

So the game loads and everythings seems fine now.
$7E9840 seems to start off as #$00, so that's good.

So I went ahead and pressed the Y Button... and the characters RUN NOW!
One thing though...
The RAM Address #9840 stays at 03 with the button press, I have to do a failed teleportation so that it resets back to 00.

That means the button is now being read and it is indeed changing the RAM address to 03 upon first press..
But the 03 status stays there even if I let go of the Y Button.

So from now on it is only a matter of debugging the code and polishing it.

One thing to keep in mind, even if the status is being set as 03, whenever I do a failed teleportation, the burnt sprites do not mess up like they did with the Run Patch, so that's a plus.
Only thing left to do now is just to make the code read ONLY when the Y Button is being held, and that should be it!

Could it be something about the LDA, AND, STA after the first branch?


That's great. Isn't it awesome when it actually starts working the way it's supposed to?

I looked over your code again and I see now why they don't stop running.
It's that first AND #$0001, CMP #$0001, BNE $01.

The problem is, when you AND #$0001 and #$0003, the result is #$0001. So when Running status is on, the rest of the routine is being skipped as though Burnt status was on.

The solution SHOULD be quite simple: change the AND #$0001 to AND #$00FF. That way, if run status is set, the CMP #$0001 will return false and the routine will continue, but if burnt status is set, the CMP #$0001 will return true and the routine will end.

I'm pretty sure that should do it!
Ongoing project: "Final Fantasy IV: A Threat From Within"

Latest Demo


Changed the first AND from $0001 to $00FF, here are the results:

When you press the Y Button, the characters do run as expected, when I let go of the Run button, the characters stop running...
BUT their sprites switch to that of the burnt sprites, which means after I let go of the Y Button, the RAM offset changes to 01 instead of going back to 00.

As for the failed teleportation and such, it still works as intended, no weird glitched out sprites.

Turns out the status was being set back to 01 after the first button press, and after that I always got #$01, which didn't responded to button press because the branch always turns out false and never entered any subroutines due to it.

Got it working.
I simply changed this:

LDA $0066
AND #$0040
LDA $9840
AND #$0000   ;Changed this part from #$0001 to #$0000 to ensure the status is set back to 00 (Normal) when the button is not being held
STA $9840

I just tested it, the Run Status is set as long as I hold down Y, when I let it go, the characters return to their normal walking animation.
I also tested out the weird sprite switching that occurred with the last Run Patch..
No longer present with this ASM hack! :)

I still have some more testing to do, I will test out other glitches that occurred with the past Run Patch and will see the results.
I will post them here.

Seriously, dude, many thanks for your help.
You helped me understand ASM coding, even if it was at a basic level, and you opened up the door for a new way to hack ROMs to me!

You will be included as a collaborator to the MaternalBound hack as soon as I release the patch. :)

Edit #2:
I already added you to the project's OP. :D

Yet another Edit (#3):
This ended up working better than I thought.
So far, none of the glitches encountered with the previous Run patch have appeared, which means...
Finally! A glitch free Run patch! :D



Hey, cool. Thanks!
I wasn't helping for the recognition, but I do appreciate it.
I just love EarthBound. Easily my favorite non-Square RPG, and in the running for my second favorite RPG ever (nothing tops FFIV for me, my "first love").
It wasn't too long ago that I was a complete ROM hacking novice, and I had some great help along the way, so it was nice to pay it forward a bit.

Glad to see you got it working. Good luck with everything going forward.
Ongoing project: "Final Fantasy IV: A Threat From Within"

Latest Demo


No need to thank!

I just think that credit should be recognized where credit is due, and you have been a great help to make this work the way I intended it to work.
Not crediting you for such thing feels almost like a disrespectful and rude action from my part, at least that's the way I think.

I just got into the Mother series less than a year ago, and it has certainly captivated me with its quirky nature.

Again, thanks for all your help!


Quote from: ShadowOne333 on April 20, 2015, 11:37:49 AM

LDA $0066
AND #$0040
LDA $9840
AND #$0000   ;Changed this part from #$0001 to #$0000 to ensure the status is set back to 00 (Normal) when the button is not being held
STA $9840

I believe the last three are effectively writing 0 to $9840, so you could just do STZ $9840.
"My watch says 30 chickens" Google, 2018


True indeed, KingMike.
In the earlier stages of this routine, I thought we needed to AND 9840 with 01, which turned out to be incorrect as ShadowOne discovered. As the AND was already there, and with an expanded ROM, he's not particularly concerned with space, keeping the AND was certainly the easier way to go. For the sake of learning, though, it is good to note that STZ is the far more efficient way to do it (takes up 1/3 of the space).
Ongoing project: "Final Fantasy IV: A Threat From Within"

Latest Demo


Thanks, KingMike!

I mentioned STZ a few posts back, I completely forgot about it. :P
Thanks for the reminder!
I simply let it like that since, as chillyfeez mentions, we originally had #$01 in there, but that was loading up the Burnt State, so that's why I changed it to #$00.

I will implement STZ in place of LDA, AND and STA to save up some space. :)

Done, replaced all three lines with:
9C 40 98     STZ $9840
Fully working as expected. :)