Introduction
WARNING: This is an advanced topic. Don't expect this guide to make any sense if you don't already have a fairly good grasp of MIPS assembly and/or programming and assembly language in general. If you've only just learned what hexadecimal is, you may read on, but don't contact us asking for a guide in laymen's terms. It just isn't possible to make one.
I'm going to try to make this guide so novice hackers can get nearly as much out of it as more advanced hackers. For that reason, some things may not make sense to some people and some people will find other things to be tedious review. I feel for both groups, but please bear with me anyway.
Subroutine codes work by forcing the game to execute a small bit of machine code that you've written. They are sometimes also called "breakpoint codes," "branch codes," and a few other names. Unlike the usual "ASM" codes, or codes that modify the game's own machine code directly to produce an effect, subroutine codes are created almost entirely from scratch by the hacker and stored in memory external to the game's executable.
Forcing execution of these external subroutines creates several problems that you must address in your code.
There are times when you can violate all the rules except the last one. Unfortunately there isn't any concrete method for making codes that call custom subroutines. Every program is different, but if you try to follow the rules above, you'll have less trouble in the long run.
When To Jump
That's the thorny issue. Do you really need a custom subroutine to produce the effect you want?
When you make the decision, you need to be aware that codes containing subroutines are harder to make; they're harder to test; they're usually fairly long, making them prohibitive to the user; and the chance of user error is greatly increased once the code is released. Don't misunderstand. It's not that these codes are undesirable or a choice of last resort. It's simply that the vast majority of effects can be created with less than a handful of code lines by modifying the game's data or its op codes. On the other hand, I have one subroutine code that is over seventy lines long. I spent a week looking for a way to use the game's programming to accomplish the same effect and never found one.
Those issues are things to keep in mind. The ultimate decision to jump to a custom subroutine is made by one factor: The number of code lines needed to produce the effect exceeds the number you can replace without negatively impacting the program. That's all there is to it. If you need seven lines of op codes to create an effect and the part of the program you need to put them in has only two lines that you can safely replace, you need a subroutine.
ASM Codes
Let's start with a simple example of regular ASM codes. The final product of this borders on a subroutine code; it replaces several parts of the game's code with custom instructions that make a loop behave differently. The modified code is part of a larger subroutine, but by looking at it, you can get a bit of an idea how to write custom code without being thrown into all the issues surrounding subroutines right away.

The above is a screen shot from the game in question, "Disgaea: Hour of Darkness." What is shown is the starting inventory: Three items named, "Mint Gum". Three is hardly a treasure trove and you're allowed sixteen in the item bag, so let's start out by trying to fill all 16 slots.
Here's the code that creates the initial inventory:

The highlighted line is setting up the item digit to be sent to the function "Item_Generate." The label is mine, not the programmer's. (Don't ask me why it was moved to one register and then immediately shifted to another. I don't get it either.) Looking down toward the bottom of the image, you can see the operation "slti v0, s1, $0003," at address 0x001A3B88. The branch following it checks the results of the operation and branches to the top of the loop (address 0x001A3B40). Since three seems a bit paltry, let's try changing the comparison to "slti v0, s1, $0010" and see if all 16 slots get filled with a Mint Gum. The cheat code for that will be: 201A3B88 2A220010.

Sure enough, we get 16 Mint Gums. They aren't very useful though. This game allows characters to have millions of hit points, so an item that restores 40 doesn't stay useful for long. Since we know what op tells the game to make Mint Gum, we could replace it with another item, but how useful is a code that gives you 16 of the same thing? So let's try to create a customized inventory.
To do that, we obviously can't just replace ops. You could just increment the item digit, you'd have to replace about three instructions, but that's still not very "custom". So what we'll do in this example is allow the player to create an inventory list in memory, that our new code will retrieve and use.
To save on operations, we'll put the list in memory at 0x000F0000. That way the address can be loaded onto a register with just a load upper immediate (LUI) op. The item digits are 16 bits wide (halfword) so the code will need to store a series of halfwords starting at that address. The part of the program that loads 0x7D2 prior to the Item_Generate call will need to load those halfwords onto the appropriate register. We'll also need the the code that modified the loop limit from our previous example.
Let's start with the custom list codes:
100F0000 00000???
100F0002 00000???
100F0004 00000???
100F0006 00000???
100F0008 00000???
100F000A 00000???
100F000C 00000???
100F000E 00000???
100F0010 00000???
100F0012 00000???
100F0014 00000???
100F0016 00000???
100F0018 00000???
100F001A 00000???
100F001C 00000???
100F001E 00000???
Pretty simple, right? I'll insert random item values for testing; it's not really important for this guide.
Now let's get the address loaded onto a register so we can retrieve the values. But there's a problem here. We can't corrupt the data that the game is going to use. Putting new values on registers only works if you're replacing data with new data that serves the same function. Here, we'll be replacing god knows what with an address. Chances are the address we load isn't going to be a useful bit of data for the game and unless we're careful, the game will crash. We're going to have to look around and find registers that we can safely use. How do we do that? It's pretty simple really. The easiest way is to look near the end of the subroutine and see what registers are restored prior to the JR op. Here's the end of the subroutine we're working in:
Quite a few registers are getting restored. That doesn't necessarily mean we can use them safely, but it does mean that using them won't result in corrupt data on the register once the subroutine returns control to its caller. Now we need to look through the code and make sure that, between the time we plan to use the registers and the time they're restored, they aren't being used by the game. It just so happens that several aren't, including s7 and we'll use that to store the address.
<i>Note: There are several ways of finding usable registers. The method above works, as does looking for memory loads (e.g. lw reg, off(reg)), immediate loads and register clears (e.g. daddu a0, zero, zero). As long as there's an instruction that <b>replaces</b> the value on the register prior to any instruction that might try to use the corrupted value you put on it, loading the register for your own purposes should be fine.</i>
Okay, we know where we can store the address to use in our load ops and now we need to find a place to put the instruction to load the address. It just happens that there's a NOP just above the block of instructions in figure 2. That's where we will place the LUI to set up the address. The operation is "lui s7, $000F"and the code will be: 201A3B3C 3C17000F
Now the address is on s7, the loop will execute 16 times, filling the inventory, and the custom digits are stored in memory from 0xF0000 to 0xF001E. All that's left is to retrieve all the values. All that's required there is to replace the instruction that loads a2 or a0 with 0x7D2. I'll replace the instruction at 0x001A3B48 with "lh a2, $fffe(s7)." I'll explain in a moment why the index/offset from the address is -2 (fffe) rather than zero.
The last thing that has to be done to get this code working is to increment the address so the same item isn't loaded each time. There just happens to be a NOP after the BNE instruction that we can replace with no worries. Register s7 will need to have 2 added to it after each item is generated. So that will be "addiu s7, s7, $2" and the code will be: 201A3B90 26F70002
The final product looks like this (modified lines are highlighted):
Notice the "beq zero, zero" op above the first highlighted line? That branches to the end of the loop and causes the address to immediately be incremented by two. That's why the index value off of s7 was -2 instead of 0. There are several ways this could have been dealt with. One is to start the list at 0xF0002. Another way would be to change the halfword load to load a1 instead and increment the address on the next line. Any of them will work and it just proves that there is more than one way to solve the same problem.
Now we have our final code:
<b>Disgaea: Hour of Darkness
Start With Custom, Filled Item Bag</b>
100F0000 00000???
100F0002 00000???
100F0004 00000???
100F0006 00000???
100F0008 00000???
100F000A 00000???
100F000C 00000???
100F000E 00000???
100F0010 00000???
100F0012 00000???
100F0014 00000???
100F0016 00000???
100F0018 00000???
100F001A 00000???
100F001C 00000???
100F001E 00000???
201A3B3C 3C17000F
201A3B48 86E6FFFE
201A3B88 2A220010
201A3B90 26F70002
After a quick in-game test:
Success! I duplicated item digits in the list a few times, that's why there's more than one of some things. (Don't ask about the item description. The game also has "Horse Weiner" as an accessory. The designers were frigging warped.)
<u>Simple Subroutine Codes - Slow Motion</u>
The previous example gave a brief demonstration of preserving registers. The game's programming had to be analyzed and a decision reached as to what register could be safely used in the cheat code. This is an important concept in creating custom subroutines that will be expanded upon in this example.
Here are some of the rules to follow when making a custom subroutine cheat:
WARNING: This is an advanced topic. Don't expect this guide to make any sense if you don't already have a fairly good grasp of MIPS assembly and/or programming and assembly language in general. If you've only just learned what hexadecimal is, you may read on, but don't contact us asking for a guide in laymen's terms. It just isn't possible to make one.
I'm going to try to make this guide so novice hackers can get nearly as much out of it as more advanced hackers. For that reason, some things may not make sense to some people and some people will find other things to be tedious review. I feel for both groups, but please bear with me anyway.
Subroutine codes work by forcing the game to execute a small bit of machine code that you've written. They are sometimes also called "breakpoint codes," "branch codes," and a few other names. Unlike the usual "ASM" codes, or codes that modify the game's own machine code directly to produce an effect, subroutine codes are created almost entirely from scratch by the hacker and stored in memory external to the game's executable.
Forcing execution of these external subroutines creates several problems that you must address in your code.
HTML Code:
<ul><li>Registers used by your subroutine's code must be preserved.</li><li>If you make any calls to other subroutines in your code, registers used by them may need to be preserved by your code.</li><li>Your subroutine must return cleanly to the game. Ideally, the only noticeable changes in the game's behavior will be the effects the code was designed to create.</li><li>You must be able to force the game to call your subroutine.</li></ul>
There are times when you can violate all the rules except the last one. Unfortunately there isn't any concrete method for making codes that call custom subroutines. Every program is different, but if you try to follow the rules above, you'll have less trouble in the long run.
When To Jump
That's the thorny issue. Do you really need a custom subroutine to produce the effect you want?
When you make the decision, you need to be aware that codes containing subroutines are harder to make; they're harder to test; they're usually fairly long, making them prohibitive to the user; and the chance of user error is greatly increased once the code is released. Don't misunderstand. It's not that these codes are undesirable or a choice of last resort. It's simply that the vast majority of effects can be created with less than a handful of code lines by modifying the game's data or its op codes. On the other hand, I have one subroutine code that is over seventy lines long. I spent a week looking for a way to use the game's programming to accomplish the same effect and never found one.
Those issues are things to keep in mind. The ultimate decision to jump to a custom subroutine is made by one factor: The number of code lines needed to produce the effect exceeds the number you can replace without negatively impacting the program. That's all there is to it. If you need seven lines of op codes to create an effect and the part of the program you need to put them in has only two lines that you can safely replace, you need a subroutine.
ASM Codes
Let's start with a simple example of regular ASM codes. The final product of this borders on a subroutine code; it replaces several parts of the game's code with custom instructions that make a loop behave differently. The modified code is part of a larger subroutine, but by looking at it, you can get a bit of an idea how to write custom code without being thrown into all the issues surrounding subroutines right away.

The above is a screen shot from the game in question, "Disgaea: Hour of Darkness." What is shown is the starting inventory: Three items named, "Mint Gum". Three is hardly a treasure trove and you're allowed sixteen in the item bag, so let's start out by trying to fill all 16 slots.
Here's the code that creates the initial inventory:

The highlighted line is setting up the item digit to be sent to the function "Item_Generate." The label is mine, not the programmer's. (Don't ask me why it was moved to one register and then immediately shifted to another. I don't get it either.) Looking down toward the bottom of the image, you can see the operation "slti v0, s1, $0003," at address 0x001A3B88. The branch following it checks the results of the operation and branches to the top of the loop (address 0x001A3B40). Since three seems a bit paltry, let's try changing the comparison to "slti v0, s1, $0010" and see if all 16 slots get filled with a Mint Gum. The cheat code for that will be: 201A3B88 2A220010.

Sure enough, we get 16 Mint Gums. They aren't very useful though. This game allows characters to have millions of hit points, so an item that restores 40 doesn't stay useful for long. Since we know what op tells the game to make Mint Gum, we could replace it with another item, but how useful is a code that gives you 16 of the same thing? So let's try to create a customized inventory.
To do that, we obviously can't just replace ops. You could just increment the item digit, you'd have to replace about three instructions, but that's still not very "custom". So what we'll do in this example is allow the player to create an inventory list in memory, that our new code will retrieve and use.
To save on operations, we'll put the list in memory at 0x000F0000. That way the address can be loaded onto a register with just a load upper immediate (LUI) op. The item digits are 16 bits wide (halfword) so the code will need to store a series of halfwords starting at that address. The part of the program that loads 0x7D2 prior to the Item_Generate call will need to load those halfwords onto the appropriate register. We'll also need the the code that modified the loop limit from our previous example.
Let's start with the custom list codes:
100F0000 00000???
100F0002 00000???
100F0004 00000???
100F0006 00000???
100F0008 00000???
100F000A 00000???
100F000C 00000???
100F000E 00000???
100F0010 00000???
100F0012 00000???
100F0014 00000???
100F0016 00000???
100F0018 00000???
100F001A 00000???
100F001C 00000???
100F001E 00000???
Pretty simple, right? I'll insert random item values for testing; it's not really important for this guide.
Now let's get the address loaded onto a register so we can retrieve the values. But there's a problem here. We can't corrupt the data that the game is going to use. Putting new values on registers only works if you're replacing data with new data that serves the same function. Here, we'll be replacing god knows what with an address. Chances are the address we load isn't going to be a useful bit of data for the game and unless we're careful, the game will crash. We're going to have to look around and find registers that we can safely use. How do we do that? It's pretty simple really. The easiest way is to look near the end of the subroutine and see what registers are restored prior to the JR op. Here's the end of the subroutine we're working in:
Quite a few registers are getting restored. That doesn't necessarily mean we can use them safely, but it does mean that using them won't result in corrupt data on the register once the subroutine returns control to its caller. Now we need to look through the code and make sure that, between the time we plan to use the registers and the time they're restored, they aren't being used by the game. It just so happens that several aren't, including s7 and we'll use that to store the address.
<i>Note: There are several ways of finding usable registers. The method above works, as does looking for memory loads (e.g. lw reg, off(reg)), immediate loads and register clears (e.g. daddu a0, zero, zero). As long as there's an instruction that <b>replaces</b> the value on the register prior to any instruction that might try to use the corrupted value you put on it, loading the register for your own purposes should be fine.</i>
Okay, we know where we can store the address to use in our load ops and now we need to find a place to put the instruction to load the address. It just happens that there's a NOP just above the block of instructions in figure 2. That's where we will place the LUI to set up the address. The operation is "lui s7, $000F"and the code will be: 201A3B3C 3C17000F
Now the address is on s7, the loop will execute 16 times, filling the inventory, and the custom digits are stored in memory from 0xF0000 to 0xF001E. All that's left is to retrieve all the values. All that's required there is to replace the instruction that loads a2 or a0 with 0x7D2. I'll replace the instruction at 0x001A3B48 with "lh a2, $fffe(s7)." I'll explain in a moment why the index/offset from the address is -2 (fffe) rather than zero.
The last thing that has to be done to get this code working is to increment the address so the same item isn't loaded each time. There just happens to be a NOP after the BNE instruction that we can replace with no worries. Register s7 will need to have 2 added to it after each item is generated. So that will be "addiu s7, s7, $2" and the code will be: 201A3B90 26F70002
The final product looks like this (modified lines are highlighted):
Notice the "beq zero, zero" op above the first highlighted line? That branches to the end of the loop and causes the address to immediately be incremented by two. That's why the index value off of s7 was -2 instead of 0. There are several ways this could have been dealt with. One is to start the list at 0xF0002. Another way would be to change the halfword load to load a1 instead and increment the address on the next line. Any of them will work and it just proves that there is more than one way to solve the same problem.
Now we have our final code:
<b>Disgaea: Hour of Darkness
Start With Custom, Filled Item Bag</b>
100F0000 00000???
100F0002 00000???
100F0004 00000???
100F0006 00000???
100F0008 00000???
100F000A 00000???
100F000C 00000???
100F000E 00000???
100F0010 00000???
100F0012 00000???
100F0014 00000???
100F0016 00000???
100F0018 00000???
100F001A 00000???
100F001C 00000???
100F001E 00000???
201A3B3C 3C17000F
201A3B48 86E6FFFE
201A3B88 2A220010
201A3B90 26F70002
After a quick in-game test:
Success! I duplicated item digits in the list a few times, that's why there's more than one of some things. (Don't ask about the item description. The game also has "Horse Weiner" as an accessory. The designers were frigging warped.)
<u>Simple Subroutine Codes - Slow Motion</u>
The previous example gave a brief demonstration of preserving registers. The game's programming had to be analyzed and a decision reached as to what register could be safely used in the cheat code. This is an important concept in creating custom subroutines that will be expanded upon in this example.
Here are some of the rules to follow when making a custom subroutine cheat:
Comment