+  RHDN Forum Archive
|-+  Romhacking
| |-+  General Romhacking
| | |-+  Inserting new code in a ROM (NES)
Pages: [1]
Author Topic: Inserting new code in a ROM (NES)  (Read 1 times)
PolishedTurd
Guest
« on: March 17, 2009, 08:13:08 am »

I'd like to add some new functionality to Ninja Gaiden (NES). I've searched the documents section and this forum. I have read Disch's document on memory mapping, which I presume I'll need to do, but I haven't found anything regarding a basic insertion of new code.

The 'Select' button is often unused in normal NES gameplay. Let's say I want to make it so that when you push select, your jump height is doubled on your next jump. After that jump, the jump height is reset to normal. I suspect I need to add instructions for the following:
  • 'Listen' for the select key, which is currently not used for anything
  • Set a byte in memory that indicates whether select key has been pressed since last player jump
  • Inside the player jumping subroutine, check the status of the 'select key pressed' byte, and set the jump height accordingly. Then clear the 'select key pressed' byte.
So, I need to find space in the ROM to add these new instructions, add pointers (JMP or JSR) to the new space I am using, and make sure they either exist on a page currently in memory, or that I load the page they are on before trying to access them. Can someone point me to some documents to help me, or provide an example? It could be something simple like adding 100 points to the score when select is pressed. If it helps at all, the jump height in Ninja Gaiden is at 0x01EBA4 and is 37 by default. The score is in $0060.

Another thing that may help is that I already need to obliterate the stuff that happens when pausing and unpausing, in this and probably subsequent ROMs that I hack. So that gives me some space to use that is always available during regular gameplay, although I admit it is not pretty.

I'd also like some help on listening for more complex button combinations, such as simultaneous keypresses (select + start gives you a powerup) or button sequences where there is a limited time to execute the sequence (e.g., A-B-B-A pressed during 1 second adds a life). How can I find the main subroutine that is constantly checking for buttons? Is there a usual location for it? I see a few values in the CPU being set to precise values while I press buttons, but putting read breakpoints on them leads to a constant series of rapid snaps at different locations.



Thanks.
KingMike
Guest
« Reply #1 on: March 17, 2009, 08:32:20 am »

Many games I've seen automatically read the controller and store both buttons "pushed" and "held" as bitfields.
So, you'd just have to find it (usually somewhere within the first $100 bytes of RAM). (or you can use the debugger and set a breakpoint for a read on $4016, and step through a few instructions. Usually there will be a shift instruction (ror/rol) used to store the button-press to a certain address.
Jigglysaint
Guest
« Reply #2 on: March 17, 2009, 06:09:33 pm »

How about Up and Jump to make a higher jump?  I know the select button is unused, but since Up is also not used while walking except for subweapons, it would fit perfectly into the controls.  I don't know anything about the Ninja Gaiden rom, but I did do somthing a little while back in Megaman 4 where I made it so you can press up and B to shoot a fully charged mega buster shot.  What I do is I find where the jump routine is called, then I add a JSR to free space.  You will overwrite bytes, so you need to include them after at some point. Basically what you want to do is first make a check to see if the Up button is held.  If it's true, keep going.  If it's false, regular jump value is used.  Then you re-define the new jump value after A is pressed.  Of course this is assuming you know how the jump mechanics work.  Some games have different ways of coding jumps than others.  Doing a Select powerup requires at least one free byte in ram.  Basically, you need to insert this routine somewhere where it will read button commands.  It obviously must be somewhere within the main program for the Ryu sprite.  You define that the select button has been pressed, and if it has, then a check is made to see if the ram slot is empty or not.  If it's not, then it moves on.  If so, do an INC for either Zero Page or Absolute(depends on where the byte is).  Now, in the jump call routine, it can check for that one address and branch off as desired.  If the value is detected, then load the new jump value.  When the actual jump button is pressed, that value is always erased.  The only stipulation is that there has to be some space left in the main PRG bank, or know what bank is also loaded while you are jumping.
Pages: [1]  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC