Author
|
Topic: Fastrom help?? (Read 2 times)
|
stryfe23
Guest
|
|
« on: September 05, 2008, 08:29:45 am » |
|
Hello, a while back I remember someone hacking a Super Mario World for fastrom capabilities. Where would I start if I wanted to convert some of my other slowroms to fastrom format?
|
|
|
|
Disch
Guest
|
|
« Reply #1 on: September 05, 2008, 07:06:16 pm » |
|
As far as I know... the only thing that needs to be done on the software end is:
1) write to reg $420D indicating you want to use FastROM
2) Ensure that all code/data (or anything else you want to be fast) is accessed through banks $80-FF and not banks $00-7D
#2 could be a bit of a large job if the game uses the lower bank numbers. You might have to hunt down all the bank numbers and change their to their respective fast bank counterpart (there may be several hundred occurances).
|
|
|
|
stryfe23
Guest
|
|
« Reply #2 on: September 29, 2008, 04:06:56 pm » |
|
I know you answered this a few weeks ago already, but exactly what is the "reg", and what are the banks your talking about? Sorry, but I don't have any experience hacking yet. I opened a rom with the program WindHex, but couldn't find the hexadecimal string you posted. Are the slow (or fast) rom strings in the same form for any SNES game?
|
|
|
|
Disch
Guest
|
|
« Reply #3 on: September 29, 2008, 04:51:21 pm » |
|
Unfortunately this is one of those things where if you have to ask, you probably can't do it.
This would be an asm hack. You would have to add code to the game which writes to a CPU register (the "reg" I was talking about) to indicate it should use FastROM mode. This involves finding space for the code somewhere in ROM, and making sure it gets jumped to sometime at startup.
You'd also have to make sure the game is using the right banks. By which I mean.... iirc PRG-ROM gets mirrored at both banks $00-7D and $80-FF... the only difference between the sections being that the low section ($00-7D) is always slow, and the high section can switch between being slow and fast. So if the game is using banks $00-7D (again this would be something you'd see by examining the disassembly, or a tracer -- ie: it's asm work) you'd have to change it to make it use the mirrored bank in the $80-FF range.
This isn't something that can be done once for one game, and the copy/pasted to another game. It would have to be handled specifically on a per-game basis... and depending on the game, might take a whole lot of work (even if you know what you're doing).
I can't explain it in any more detail than that without starting to explain assembly fundamentals and the SNES memory map, which I'm not really in the mood to do. Maybe someone else will feel more generous.
|
|
|
|
creaothceann
Guest
|
|
« Reply #4 on: September 29, 2008, 05:51:26 pm » |
|
http://www.romhacking.net/docs/memmap.txtAt the end of this file is the SNES memory map. The CPU can read and write to 2^24 addresses (256 banks, 65536 addresses per bank). Some areas of this map are "mapped" (assigned) to the RAM chips, some are mapped to other hardware (graphics, audio, pads, ...) and many are mapped to the cartridge ROM. Read/write accesses need a certain number of clock cycles (6, 8 or 12), depending on the area of an address. "FastROM" means 6 cycles. You have to literally rewrite parts of the game to use different bank values. (The rewriting is probably the easier part; the hard one is finding all the opcodes that have to be edited.)
|
|
« Last Edit: September 29, 2008, 06:02:48 pm by creaothceann »
|
|
|
|
stryfe23
Guest
|
|
« Reply #5 on: September 30, 2008, 06:09:56 pm » |
|
Ok, thanks for the info everybody. Any chance someone could give me a recommendation for an utility to accomplish this task?
|
|
|
|
Karatorian
Guest
|
|
« Reply #6 on: September 30, 2008, 07:45:15 pm » |
|
While I can't recommend specific tools, I can tell you what sort you're going to need. You'll need a hexeditor to make actual changes to the ROM image. (I like the one by Prez, but it's a un*x program, so that may not be much use to you.) You will also need either (your choice) a SNES dissassembler or debugger (or both) to locate the code that needs modification.
You should be able to find some useful tools in the database. However, if you're looking for some sort of automated utility specifically for Fastrom modification hacking, you're out of luck. As Disch said, this isn't some generic operation that can be simply applied to any given ROM. The code that needs alteration will vary by ROM and must be specifically located for each one.
Slightly Off-Topic Aside
This brings to mind an idea, I don't know precisely how feasable it would be, but I'll throw it out there anyway. This seems like something that could, in theory, be mostly automated. Obviously, writing to register 0x420D would require hand hacking, but automatically changing the bank numbers may be possible.
The idea is pretty simple on paper, but as I don't know much about the SNES ISA, I can't say how it would work out in practice. Basically, the idea is to use a customized dissasmbler to locate bank accesses. Provided one has a method of determining what is code and what is data, direct accesses should be fairly easy to change. Indirect accesses would be more complicated, but with some sort of code analysis should be doable.
However, as this all implies some fairly sophisticated code tracing functionality, it'd probably only be practical (if at all) if one had access to an advanced debugger/disassembler to modify. So anyway, it's an idea. Anyone who actually knows SNES internals want to comment on this?
|
|
|
|
Ryusui
Guest
|
|
« Reply #7 on: September 30, 2008, 08:02:47 pm » |
|
Have you ever been to a message board for a particular game and see a lot of topics asking the exact same question, and in each and every one there's somebody pointing out that the answers are in the game's manual and/or built-in tutorial/help feature? The Newbie Package of REQUIRED MaterialHere's the manual. ROMHacking.net FAQ: You ask, we answer!ROMHacking.net Getting Started Section: Newbies Go HERE!ROMHacking.net Documents Section!How to ask questions the smart way.On the Essence of ROM HackingIf you don't know what registers and banks are, you don't have any business asking how to convert a game to use FastROM. Start with something small. Change all the dialogue in The Legend of Zelda to obscene cursing, if you like. Maybe put Princess Peach at the end of Super Mario Bros. in a bikini. Those are projects more in line with an absolute beginner such as you. I'm serious. You don't have to do exactly those things, but fooling around with the fundamentals of text and graphics in ROMs is bound to be more fruitful than climbing the cliff of assembly hacking (which, as I've discovered from a failed attempt to teach someone else, cannot be taught to someone who has no experience with programming whatsoever). Romhacking doesn't come in prebuilt kits. What few there happen to be are very, very game-specific, and are not guaranteed to do everything you want. What romhacking has are hammers, nails and saws, and a nigh-infinite supply of lumber to work on. Just using these tools requires talent and practice; using them properly requires knowledge and intuition. And ASM hacking takes almost an entirely different set of skills; being good at hacking resources doesn't even give you a start at modifying the game's code. All I can say is, good luck. Learning the basics of romhacking takes an open mind and that's about it. Doing what you're asking? It's gonna be a while before you're at that level.
|
|
|
|
Disch
Guest
|
|
« Reply #8 on: September 30, 2008, 08:08:28 pm » |
|
Basically, the idea is to use a customized dissasmbler to locate bank accesses. Provided one has a method of determining what is code and what is data, direct accesses should be fairly easy to change. Seperating code from data is hard enough on its own. SNES has the additional challenge of of having variable widths for some opcodes (ie: LDA immediate can be either 2 bytes or 3... depending on the current mode) so even simple disassembly isn't as cut and dry as it is for other systems. IIRC, this is something SNES disassemblers are still struggling with -- though I haven't actually used one in a long time so I could very well be wrong. Sure it might not be terribly difficult to get all the hardcoded long addresses -- but those might not even make up half of the bank numbers used by the game. My 65c816 is rusty, but iirc to change the data bank, you have to push the bank number to the stack, then pull it into the data bank reg with PLB. So something like: LDA #$05 PHA PLB
Which doesn't look too menacing on its own, but if the PLB doesn't immediately follow the PHA it could be harder for automation to detect. Plus that could get complicated for data blocks that cross bank boundaries... like a large chunk of text or level data where the bank number might be calculated with some math operations, rather than just a simple LDA immediate. IMO you could probably make a program which partially automates the process (gets a bunch of the easy stuff), but it's output would be unreliable at best, and you'd still have to go in by hand and touch up a lot of things.. and get the really tricky stuff. I think a more useful tool for something like this would be a feature in an emulator that dumps a log of every line of code which changes the data/program bank registers (omitting duplicates of course) -- that is... every PLB/JSL/etc. Emulators are great for this kind of thing since they're actually executing the code -- so it could easily make a list of all the information that needs to be changed, and then you could just go in and change it (it, too, might even be able to do some of the easier changes for you). The downside to the emulator approach is that you'd have to run the emulator for the entire game. In order to get it to log everything, you'd need to play the game from beginning to end, getting every little obscure secret in the game to ensure it runs all the code and logs all the bank changes. Still this seems like a better idea since you'd have to make some log like this for seperating code/data anyway (no other reliable way to do it). Emulators, too, can be tricked though... with things like relocatable or selfmodifying code.
|
|
|
|
Karatorian
Guest
|
|
« Reply #9 on: September 30, 2008, 09:10:42 pm » |
|
Why am I not surprized the answer would be something like that. In retrospect, it seems obvious that the sophistication of the code analysis required would basically be on the complexity level of an emulator, so that method would be more feasable. I suppose it goes back to the point I made at the end: it'd only be practical if such sophisticated tracing software already existed, which apparently it doesn't. (It wouldn't surprize me to find this level of tools for more common platforms, like x86. However, that's irrelevant.)
|
|
|
|
byuu
Guest
|
|
« Reply #10 on: October 01, 2008, 01:48:19 am » |
|
This seems like something that could, in theory, be mostly automated ... Anyone who actually knows SNES internals want to comment on this? Very impractical. lda #$00; pha; plb inc; sta variable_that_must_be_one_or_game_crashes phb; pla bne crash_the_game Rare? Probably, but do you like the idea of automating anything that might end up crashing the game in some odd location on your end users? My 65c816 is rusty, but iirc to change the data bank, you have to push the bank number to the stack, then pull it into the data bank reg with PLB. You can use plb, mvn or mvp to change the data bank register. In retrospect, it seems obvious that the sophistication of the code analysis required would basically be on the complexity level of an emulator, so that method would be more feasable. The modification itself is infeasible. Even if you succeed 100%, you could cause all sorts of timing problems with the game as a result. A lot of SNES games are very timing sensitive. Though to be fair, first-party titles are usually the top-notch ones that aren't coded so shoddily. I doubt you intend to run this on actual copiers anyway, why not take a much easier approach and modify an emulator to act as though FastROM is always on, and that $00-7f:8000-ffff count as FastROM regions? Sure, it's not as nice as the real thing, but it's at least an order of magnitude less complex for you to do. And even if it works, I'm not sure what your expectations are. This won't be like doubling the clock speed on SuperFX1 games like Star Fox. It is, at best, a ~10-15% speed up, assuming 100% CPU utilization (eg no wait for NMI loops, etc.)
|
|
|
|
MathOnNapkins
Guest
|
|
« Reply #11 on: October 01, 2008, 07:18:34 am » |
|
I still don't really know how d4s did this without wasting a lot of time to SMW.
|
|
|
|
Nightcrawler
Guest
|
|
« Reply #12 on: October 01, 2008, 09:50:15 am » |
|
I'd also add that at times the value sent to the data bank register is derived dynamically from pointer math or other game logic. In cases like that, you'd have to find and edit it by hand. I don't think you could detect such instances automatically and you certainly couldn't automatically correct for them.
Another similar case is 24-bit addressing based on some dynamic values stored in RAM. How are you going to automatically detect that kind of thing?
Regarding your comment MathOnNapkins, I can't speak about SMW specifically, but depending on the game code, there could be a huge range of difficulty for a FastROM hack depending on the game code. It may be that SMW lends itself better to this type of a hack. Though I could be wrong.
|
|
|
|
byuu
Guest
|
|
« Reply #13 on: October 01, 2008, 10:07:37 am » |
|
It could also be an incomplete conversion, eg not accounting for 24-bit indirect accesses, just making sure the program itself runs in FastROM.
|
|
|
|
MathOnNapkins
Guest
|
|
« Reply #14 on: October 01, 2008, 01:44:35 pm » |
|
Yeah... the thought had crossed my mind but I've never bothered to investigate whether the patch works fully as advertised.
|
|
|
|
|