Assembly FAQ
Jump to navigation
Jump to search
Brief overview!
- Assembly refers to the code on the game disc; it's the language the game runs in. More specifically, it runs on MIPS r300. When using psxfin, use the r3000 debugger. - The game disc also contains tabular data interwoven with the code, and individual files for things like images and sound. These are not all in RAM at once, and cannot be accessed at a whim.
[FFTPatcher Suite] [How to use the patching tools] Please see these pages to learn about the tools we use for patching!
Contents
- 1 Q. Some data points/routines in the wiki have the same ram addresses; how can a routine/data point be 2 different things at the same time?
- 2 Q. How can I access these files if they aren't open? Can I open them?
- 3 Q. Some routines start and end making changes and then undoing them with r29 and r31. What's up with that?
Q. Some data points/routines in the wiki have the same ram addresses; how can a routine/data point be 2 different things at the same time?
A. They're not! The files in FFT are very large and not all of them can actually be open at the same time! For example, BATTLE.BIN and WORLD.BIN are mutually exclusive and are never opened at the same time. A short rundown: * SCUS_942.21 -> Always open. This is the executable of the game itself. * WORLD.BIN -> Opened when not in battle. This handles everything from shops/towns to saving to the formation screen. * WLDCORE.BIN -> Opened at the same time as WORLD.BIN. It mostly contains sprite and portrait data, though does handle some things on its own. * BATTLE.BIN -> Opened during any combat OR during events. This is where all of ability formula processing takes place, as well as handles things like the map and playing events. * OPEN.BIN -> Opened at startup. This shows the movie at the beginning of the game, and also handles starting a new game. It may be open in place of WLDCORE for this. * ATTACK.OUT -> Opened during the deployment screen. It exclusively handles deployment and displaying graphics for deployment. * REQUIRE.OUT -> Opened when ending battle. This handles the formation screen if dismissing units to make room for others, and which units leave due to low brave/faith, among other things. * OPTION.OUT -> Opened when changing options during battle. This mimics the WORLD routines that allow changing the game options. * ETC.OUT -> Handles showing other battle/event graphics such as chapter title cards and game over. * EQUIP.OUT -> Opened when using re-equip. This mimics the WORLD routines that allow equipment changing. * CARD.OUT -> Opened when saving between events. This mimics the WORLD routines that allow saving to the memory card. * BUNIT.OUT -> Opened when viewing the unit list during battle. It mimics the WORLD routines for the formation screen, though the units present are snapshotted from their poses in combat. * JOBSTTS.OUT -> Opened when viewing unit jobs & abilities during battle. It mimics the WORLD routines that display the scrollable jobs/abilities menus. All other files tend to be opened on demand (such as effect files, extra combat graphics, etc.). Any file that is not open cannot have its routines called or its data read/written to, so be careful.
Q. How can I access these files if they aren't open? Can I open them?
A. No, you probably can't. There's a lot of communication back and forth that goes into opening a file, which relies on precisely timing connecting to hardware IO ports and making sure the disc is spinning and that it's spinning to the correct hour, minute, and second of the CD, having another hardware function read the disc into ram, and all this requires a million checks and balances and making sure the cpu is still reading game code in the background... So, no, not yet. Only attempt to modify files when they are open.
Q. Some routines start and end making changes and then undoing them with r29 and r31. What's up with that?
A. That's the stack. Which does need more explanation: * "r29" or "sp" depending on the assembly is the "stack pointer". It contains the current address of the stack currently being utilized. * The "stack" is a nebulously large amount of space used to store temporary information. it is handled from the bottom up. * "r31" or "ra" is especially prevalent since any "jal" will overwrite r31. so it needs to be preserved in the stack, and grabbed later to use jr r31. * Failure to preserve r31 will cause your routine to return into itself and freeze your game. * When you subtract from the stack pointer, you are in essence creating temporary storage space. When you add it again, you are deleting said storage space. * The stack pointer always needs to be preserved going in and out of a routine. * Other registers that need to be preserved with the same method as r31 are r16, r17, r18, r19, r20, r21, r22, r23, r26, r27, r28, and r30. * r24 and r25 are exempt from this, for some reason. * Because of how these registers are treated, you as the compiler need to assume that any other register will contain garbage data after any routine call. * Without manually checking it yourself there is no guarantee a register will hold its information between calls.
More questions to come soon. answers? perhaps.