Well, seems to me like I maybe didn't supply enough instructions here. But, that can be fixed: here's a short tutorial.
InvalidComponent's guide to easy romhacking with ANDA
Hi kids! Tonight we're gonna fix that Mario's game for good! And I am, of course, talking about doing something fun with Dr. Mario.
We'll start up by firing up an emulator which supports the log format described in the .nfo file (y'all windows folks probably want to open it in notepad) and playing the game a bit. (Yay!)
This is probably the hardest step, since at the moment, no official emulators seem to do the trick, so you'll probably be better off just rolling the feature in your own.
Alright, let's play the game a little bit... due to the nature of the disassembler, you have to play the game so that all code you want disassembled is traveled upon at least once. Also, if your game uses some nasty tricks to do jumping, there's a high chance you're going to have to write those addresses accessed in that way down in the log file yourself. ("push bytes to stack, then rts" nasty)
Then, let us run anda!
Code:
invalidco@localhost ~/anda $ ./anda drm.nes drm.s drm.chr drm.jumps
After ANDA warns you about indirect jumps, it'll write the output to drm.s and the graphics to drm.chr. Since this disassembler is still a beta versision, you'll want to make sure the assembler didn't screw anything up and fire up ophis already with the just-disassembled rom:
Code:
invalidco@localhost ~/anda $ ophis drm.s test.nes
And check for differences between files...
Code:
invalidco@localhost ~/anda $ md5sum test.nes drm.nes
d3ec44424b5ac1a4dc77709829f721c9 test.nes
d3ec44424b5ac1a4dc77709829f721c9 drm.nes
Looks good to go, so let's get cracking!
The first thing we need to do is find some unused space to use to store our code. After some search, we'll find something that looks like a padding pattern or something similar at nearly the end of the drm.s. These bytes look like they store nothing significant, (I get a feeling that $0, $ff pattern is a leftover from the eeprom or some other low-level electronics thing) so we'll erase 'em and replace it with our padding code:
Code:
supercoolfunction:
rts
.advance $ffd0
sub_b1_ffd0:
Since we'll have to be careful in order not to mess the bytes up, we'll just stick a label, an rts and an assembler directive to pad the rest with zeroes. Now, let's find someplace to inject! If you look for the address $4014, you'll find the OAM subroutine pretty fast! There's the usual addresses being written to registers, we'll cut the second one and copy it to our own subroutine, leaving the sprite update routine in the following condition:
Code:
sub_b0_b788:
lda #$0
sta $2003
jsr supercoolfunction
rts
.advance $b793
sub_b0_b793:
Note that we need to the padding, again, because there are far more complex dependencies hidden in there than I have the time to explain.
Now, we'll do something fun in the supercoolfunction subroutine, like flip all sprites vertically:
Code:
supercoolfunction:
ldx #$00
*
lda #$80
eor $0202,x
sta $0202,x
inx
inx
inx
inx
bne -
lda #$02
sta $4014
rts
Now, assemble, test and feel the newly acquired power coursing through your veins!
EDIT: If you feel some glitching, that's because this code is taking up too much time, you might want to try to restrict the flipped sprites to only a few of the first or use some code that has been optimized a bit better.