Points of Required Attention™
Please chime in on a proposed restructuring of the ROM hacking sections.
Views: 88,478,924
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search 04-24-24 09:19 PM
Guest: Register | Login

0 users currently in ROM Hacking | 3 guests | 1 bot

Main - ROM Hacking - Help with Hijacking a Routine! New thread | New reply


Gavzilla1000
Posted on 07-15-14 06:27 PM Link | Quote | ID: 157440


Red Paragoomba
Level: 18

Posts: 52/60
EXP: 29356
Next: 541

Since: 05-22-13

Last post: 1909 days
Last view: 1834 days
So lately I've been interested in trying to conquer the beast that is NES ASM. So, what I did was download the Megaman Update Patch, and tried doing some ASM related things on that. The thing is, I failed. Miserably.

From what the title reads, I need help trying to hijack a routine. I don't really know where to start. In the .txt document relating to the Megaman Update Patch, it says that the author added tons of extra ASM space, but didn't give any addresses on where it's located.

I fired up the debugger & code / data logger, and just messed around for a little bit in Cut Man's stage. (I wanted to make sure the code was going to be active when Megaman was playing) When looking through the debugger, I didn't find anything I could replace so I could hijack a routine to my custom ASM code. I had the code at $1360 (because there was nothing but 0's there). It was simply going to be the JMP code I would replace. All I wanted was to put a break at that address and see if it actually worked before I start doing more stuff with it.

Sorry for the long post, there really isn't any tutorials for this kind of stuff, so I'm sticking with the places I know that could help me. Doesn't really help that the author of the patch converted it to MMC3, so I have to deal with Bank Swapping too.

Oh well,

Vanya
Posted on 07-16-14 01:25 AM Link | Quote | ID: 157446


Red Koopa
Level: 27

Posts: 67/139
EXP: 105068
Next: 11091

Since: 01-22-13

Last post: 3292 days
Last view: 3291 days
The MMC3 conversion is actually a very good thing. Let's you do lots of cool stuff that would otherwise be impossible.

Anyway, what exactly are you trying to do? Depending on what it is can influence how you go about things.

____________________
Krakenskin Leather Works, my Etsy store.
LordVanya, my art page.
FundamentalEssence, my game development page.

Gavzilla1000
Posted on 07-16-14 01:39 AM Link | Quote | ID: 157447


Red Paragoomba
Level: 18

Posts: 53/60
EXP: 29356
Next: 541

Since: 05-22-13

Last post: 1909 days
Last view: 1834 days
Well, I just wanted to start with some very basic things.

My first idea was going to be constantly checking Megaman's health and keep checking it until it got to a certain point, including every variable below it (Not counting death of course). Then it would JMP to the "get health capsule" routine, and then two RTS would send it back to the routine I took it from.

Like I said, I just wanted to start with little ASM programing like this, then I would try bigger things. But, yea, that was my idea I was going to try.

Vanya
Posted on 07-16-14 01:45 AM Link | Quote | ID: 157448


Red Koopa
Level: 27

Posts: 68/139
EXP: 105068
Next: 11091

Since: 01-22-13

Last post: 3292 days
Last view: 3291 days
In that case what I would do is start by setting up a read break point on Megaman's health. That should lead you to any routines that deal with specific health values like the damage routine or death routine.

____________________
Krakenskin Leather Works, my Etsy store.
LordVanya, my art page.
FundamentalEssence, my game development page.

RetroRain
Posted on 07-16-14 07:15 AM Link | Quote | ID: 157450


Fuzz Ball
Level: 66

Posts: 758/994
EXP: 2437873
Next: 23978

Since: 09-30-07

Last post: 1933 days
Last view: 956 days
In order to see all of the free space, simply open up the hex editor (make sure you are looking at the "ROM file"), and find the big blocks of 00s. In order to take advantage of the free space, you definitely have to use the bankswitch routine. Each bank in a MMC3 mapper is $2000 bytes long (8K), but because Megaman 1 was originally an UNROM mapper, in which the banks were $4000 bytes long (16K) the MMC3 bankswitch loads two banks together into what would be one bank in an UNROM mapper.

For example, in an UNROM:

Swappable Bank ($8000 - $BFFF)
Bank 0 ($4000 bytes, 16K, $8000 - $BFFF)

Hardwired Bank ($C000 - $FFFF)
Last Bank ($4000 bytes, 16K, $C000 - $FFFF)

In a MMC3:

Swappable Bank ($8000 - $9FFF)
Bank 0 ($2000 bytes, 8K, $8000 - 9FFF)

Swappable Bank ($A000 - $BFFF)
Bank 1 ($2000 bytes, 8K, $A000 - $BFFF)

Hardwired Bank ($C000 - $DFFF)
Last Bank 1/2 ($2000 bytes, 8K, $C000 - $DFFF)

Hardwired Bank ($E000 - $FFFF)
Last Bank 2/2 ($2000 bytes, 8K, $E000 - $FFFF)

But you don't really have to be concerned too much about the operation of it, as the Bankswitch Routine takes care of everything. Just know that if you want to switch banks in the MMC3 ROM, you simply load the bank you want (let's say bank 0), and then JSR to the bankswitch routine.

LDA #$00
JSR $FF00

Even though the MMC3 using 8K banks, loading bank 0 will load a 16K bank, because the Bankswitch Routine combines MMC3 banks 0 and 1. Megaman 1 has 8 swappable banks (0 through 7). That doesn't include the hardwired bank, which simply stays at $C000 - $FFFF.

So, if you are confused, open up the hex editor (make sure you are looking at the "ROM file"). Offset 10 to offset 400F (Ox10 - 0x400f) is bank 0. 0x4010 - 0x800F is bank 1, and so on.

So, wherever you want to hijack code (there needs to be enough free space, but this isn't a problem as you can always copy and paste original code in one of the bigger free space banks right before you return from it), you load the bank, jump to the spot in the bank, carry out your own code, add the original game code, and then return. Then, you have to make sure you load the previous bank back in.

For example, let's say you are in Bank 2, you have some free space, and you want to load Bank 4 and carry out your own code. Your code would look like this:

LDA #$04 ; Load Bank 4
JSR $FF00 ; Jump to Bankswitch Routine
JSR _ _ _ _ ; The spot you want to go in Bank 4
LDA #$02 ; Load Bank 2, previous bank
JS4 $FF00 ; Jump to Bankswitch Routine

In Bank 4:

Your code
Original code, if any
RTS ; This is very important. This RTS will take you to the LDA #$02 line above.

Hopefully that helps you a little bit with the bankswitch routine. You can always check what bank is currently loaded by looking at address $42 in the RAM viewer.

Now, as for the ASM hack you want to do, first up, I would recommend downloading the Megaman 1 Disassembly. You can get it at romhacking.net. This will come in handy if you plan on ASM hacking the game. You can search it if you want, for your health code. Otherwise, you can just find it yourself with the FCEUXD tools (cheat search, RAM editor, and the Debugger).

Now, am I correct in assuming that you want to make it so that when Megaman's health gets to a low enough point, it automatically recharges?

If so, it's simply a matter of finding the two code blocks, adding a CMP to the original health code to check for how low the health has to be, and then jumping to the health capsule routine (see the disassembly document, it will come in handy).

Just to let you know though, you don't necessarily have to use my Upgrade Patch to do a hack like this. In fact, you might learn more working with the original ROM. I learned a ton by studying the MM1 ROM, and I'm glad I did. I never really did bankswitching before until messing with Megaman 1.

Also, as I would tell anyone, you need your documentation. It is a MUST.

Download the mapper documents, 6502.txt, and nestech.txt. Even I still have to refer to them when I do hacking. Without documentation and notes, you will not get far. Even the most experienced hackers use documentation, because as a human, you simply can't remember everything. You need to refer to them when you need the precise information you're looking for. But as you will find out, that even at times some of the information in documents can be wrong as well. I found that in a nes mapper document, the MMC3 horizontal and vertical scrolling addresses were reversed, which caused me a problem.

Yeah, so what I would do is open up an original Megaman 1 ROM, open up the disassembly for the game, and use the code/data logger in conjunction with the trace logger, if you can't find what you are looking for in the disassembly document.

I hope this information has helped you in anyway. Good luck!

____________________
My YouTube Channel

Gavzilla1000
Posted on 07-17-14 05:52 AM Link | Quote | ID: 157457


Red Paragoomba
Level: 18

Posts: 54/60
EXP: 29356
Next: 541

Since: 05-22-13

Last post: 1909 days
Last view: 1834 days
I want to thank both of you guys for helping me out, but this reply is for RetroRain.

*cough* *cough*

So, the main reason why I wanted to use your Upgrade Patch was because of the MMC3. (I know, I made it sound bad in my original post) I know what MMC3 is, so that means more programming space for my ASM coding.

An issue that I had while doing this was finding the bank that the game was using. For reference, all of my tests and coding are going to be in Cutman's stage.

From what you said, each MMC3 bank is about 4000bytes. Using a programming calculator, I subtracted 0x400F by 0x10, which equals 3FFFbytes. So, I did the same with the addresses 0x800F and 0x4010, and still got the answer 3FFF. I see that you added a byte to the last address, (It goes from 400F to 4010, which makes sense) so I made a nice equation because I can!

(x + 1) + 3FFF

x = the ending address of the bank.

Using this convenient equation I made, I determined all 8 Banks.

;Bank 0 0x10 - 0x400F
;Bank 1 0x4010 - 0x800F
;Bank 2 0x8010 - 0xC00F
;Bank 3 0xC010 - 0x1000F
;Bank 4 0x10010 - 0x1400F
;Bank 5 0x14010 - 0x1800F
;Bank 6 0x18010 - 0x1C00F
;Bank 7 0x1C010 - 0x2000F

This didn't quite make sense to me because it didn't line up with the Hard Wired bank you gave in your reply. So... I looked up a wiki page talking about MMC3 itself. Including its Banks.

http://wiki.nesdev.com/w/index.php/MMC3#Banks

What then I came to realize is that this was originally a MMC1 ROM, so no wonder my "equation" and the Wiki Page itself didn't line up with the Hardwired bank you gave in the your reply. But still comment on if this is right or not. Its no use if I can't get the banks right.

After this, my next challenge was to figure out what Bank loaded when I played Cutman's level. So, using my non-existent genius, I decided to put a break at $FF00 using the debugger to see if I could see what the accumulator was so I could see what bank it was. But... that didn't work. And... there really wasn't anything on the internet that told me how I could figure it out. BUT! I used the code data logger and played through the stage. The debugger started at 14010! (Bank 6) After the RAM of course, so I got really excited! I thought that the bank was 6, so I went into the FCEUX Hex Editor, and tried to find empty space. I was looking for stuff highlighted in Yellow because that's programming, plus I can only assume that's what the CPU reads when in game.

I found an JMP routine that I hijacked, but I didn't have to use a Bank Swap, because there was about 5A empty bytes at the end of the bank. Literately right next to the JMP routine I wanted to use. I still had to use a JMP command to get to that empty space. I knew that I couldn't use the actually address that the Hex Editor said I was at, so I replaced the Bank's ending address, 1800F, with 400F. Then, I subtracted 5A from 400F to get my address. $3FA5. Did I do that the right way? Or was I completely off? I think I was completely off.

Anyway, then I started writing my ASM. Which is written below.

----
Start of ASM Code
----


JMP $3FAF <--- Jumps to the code under the RTS. The LDA $6A
RTS <--- This is activated last

LDA $6A <--- Megaman's Life Value
CMP #$1C <--- Compare of Megaman has Full Health
BNE originalcode <--- If not zero skip to the original code

==
This code is taken from the Megaman Disassembly you told me to get
==

LDA CapsuleObtained (#$40) <--- RAM address is $AD | In this instance I did a Large Capsule so its #$40
AND #$7F
STA MiscCounter1 <--- RAM address is $3C

originalcode: <--- I did some math to figure out the actual value, but forgot it, and I forgot to save the ASM file I was using during this three hour process!
(Original code from the JMP routine goes here.)
RTS

----
End of ASM Code
----

What this is supposed to do, is if Megaman's health is under 1C (Max) is was going to freeze the game like Megaman was picking up a capsule. ( P.S It was pretty dumb, because if it worked I wouldn't know because it was supposed to pause.... I'm pretty dumb)

So, I reset the game, and it didn't crash... yet. But the title screen showed up, and everything was all good until I got to those wall things in Cutman's stage.

BUT! That's a good thing! I know that there's something wrong with my code I need to fix, AND that my code is being read / executed by the CPU!

At this point I've been working on this for about three hours, and really needed a break. So, that's all I really did.

There's probably tons of stuff I did wrong here, SO PLEASE CORRECT MY MISTAKES! Don't worry about the ASM code too much, I want to work on that alone, but everything else you can yell at me for!

Also, does the RAM addresses listed in the disassembly document of Megaman still work with this Patch too? Or are the RAM addresses different? Sorry if this reply seems confusing and unorganized, I can only work for a few hours before getting a headache, and writing this for the past hour didn't help...

Sorry for the long reply.... again...

Main - ROM Hacking - Help with Hijacking a Routine! New thread | New reply

Acmlmboard 2.1+4δ (2023-01-15)
© 2005-2023 Acmlm, blackhole89, Xkeeper et al.

Page rendered in 0.021 seconds. (339KB of memory used)
MySQL - queries: 62, rows: 88/88, time: 0.016 seconds.