Not long ago I updated DTW to be able to import differently sized DOL files. A small update, and a small feature (though not so simple as replacing other differently sized files), but not a small deal! Here's an example of how this can be useful; creating a DOL with more codespace.
Update: The original file that I uploaded, NTSC 1.02.01, had an error in it (Data 8's RAM offset was incorrect). While it worked on Dolphin, it did not work on console. This has been fixed and tested, and works on both emulator and hardware.
Currently, out of 0x438500 bytes of code in the original NTSC 1.02 DOL, we have defined a bit more than 0x114B0 bytes of it as "free space". That is, codespace that's [as far as we know] safe to be overwritten for custom code. (I'm not counting the space CrazyHand uses in that number, since the end point of the region it overwrites is not set.) This is how much space you would currently have available in MCM if you enable all of the default custom code regions. The DOL above has been expanded to accommodate 0xE900 more bytes of free space for custom code, for a new total of 0x1FDB0 bytes of space. That's 84% more codespace for us to use!
Conceivably we could also shrink the DOL, to reduce the game boot time. But the amount of space we currently have defined as "free" is only a few percent of the total size of the file, which wouldn't make for a big difference if we removed it.
This is not compatible with versions of MCM before 4.0. Making further iterations of this such as to add more space might be possible, but I'll go into that at the end of the Documentation section below.
Perhaps besides the fact that it's written in assembly, the DOL is a pretty simple and straitforward dude. As probably most of you know at this point, the DOL is the main game executable, and contains the game's functions and logic. But it does have a small quirk, which is one of the reasons things like adding code injections, doing branch calculations, or converting codes to other game versions manually used to be such a pain. The quirk is that it's not loaded into RAM as one 1:1 block of code. Before the DOL is loaded, the first thing that the GameCube IPL (Initial Program Loader) runs on the game disc is the Apploader. Part of what that does is break up the DOL file a bit and place each section into various places in RAM, before it then hands execution off to it. The locations are defined in the DOL, and vary for different games.
For Melee, if you've ever wondered how the DOL is distributed in RAM, it's this:
This was created by a script I wrote, which you can download here. Should work for almost any GameCube/Wii game; just drag-and-drop your DOL onto the batch file and it will create a png (or you can edit the python script to create an svg). So far, I've noticed that other games have similar section patterns, with different sizes and start/end locations.
So basically I just defined a new region in the file header to follow immediately after the last vanilla region. I tried adding a larger area at first, but I found that, even though it appeared to have loaded fine, the area was soon later overwritten in RAM by other things. The apploader and the SDK both define the upper limit to usable RAM space for the DOL (DOL_ADDRESS_LIMIT) as 0x80700000. But I saw RAM being overwritten well before that (and I don't remember it being the BSS section). The section I've defined in this current file I observed as OK after booting the game and loading some matches in some 1 Player & VS. modes.
Update: The original file that I uploaded, NTSC 1.02.01, had an error in it (Data 8's RAM offset was incorrect). While it worked on Dolphin, it did not work on console. I haven't retested larger DOL areas yet, so I don't know if the problem I mention above is still relavant. Please let me know if you test this, so I can update this post.
I'm not sure what exactly is "reserving" the space where the DOL is being placed, or how the system knows not to place anything into where the DOL will be, but I know there's a global __OSDOLSize that the Apploader sets. I haven't double-checked it, but logically that should be correct even for this custom DOL, since its new section is built exactly as a real one would be.
If we figure out more about this, we could most likely load even larger DOLs. We don't want to go too crazy with it though, if we care about loading times. The SDK, in "Nintendo GameCube Optical Disc Drive Guidelines Version 1.41.pdf", section 5.3, says that the recommended size limit is 4 MB, to help curb loading times, and vanilla Melee is already 4.21 MB (now 4.27 with this). It also says 'the total section size must be less than 4 Mbytes', but that doesn't appear to actually be true/necessary, at least in terms of loading the file. The apploader checks the DOL size when loading it, and compares its size to a variable called "dolLimit", which is in 'DVD Boot Info' (the DVDBI2 struct) which I believe comes from the Bi2.bin file on the disc, as part of the disc header. In there, as with everything else, the variable appears to be just 0. Maybe the struct is different when in-RAM than when in-file. In this case, zero means unlimited, so I don't think the apploader cares how big the DOL is, as long as it doesn't go beyond that huge upper limit.
Update: The original file that I uploaded, NTSC 1.02.01, had an error in it (Data 8's RAM offset was incorrect). While it worked on Dolphin, it did not work on console. This has been fixed and tested, and works on both emulator and hardware.
Currently, out of 0x438500 bytes of code in the original NTSC 1.02 DOL, we have defined a bit more than 0x114B0 bytes of it as "free space". That is, codespace that's [as far as we know] safe to be overwritten for custom code. (I'm not counting the space CrazyHand uses in that number, since the end point of the region it overwrites is not set.) This is how much space you would currently have available in MCM if you enable all of the default custom code regions. The DOL above has been expanded to accommodate 0xE900 more bytes of free space for custom code, for a new total of 0x1FDB0 bytes of space. That's 84% more codespace for us to use!
Conceivably we could also shrink the DOL, to reduce the game boot time. But the amount of space we currently have defined as "free" is only a few percent of the total size of the file, which wouldn't make for a big difference if we removed it.
This is not compatible with versions of MCM before 4.0. Making further iterations of this such as to add more space might be possible, but I'll go into that at the end of the Documentation section below.
This file has been planned for, so this space will already automatically show up in MCM's Code-Space Options menu when this DOL is loaded, as "Gecko Code Handler Storage" and "Gecko Code List Storage". This is because, if you use Gecko codes, I recommend changing the save locations for those to use these new areas, since both of those items are relatively large and must be contiguous.
To change the save locations for those items, so that they're stored in the new regions of this DOL when Gecko codes are used, open the settings.py file, found in the root directory of MCM. You can open it in any standard text editor. Scroll most of the way down to about line 116, where you should see some Gecko configuration info. Here you can specify the name of the region to store the codelist/codehandler in. So change,
"'codelistRegion': 'Tournament Mode Region'," to "'codelistRegion': 'Gecko Code List Storage'," and change,
"'codehandlerRegion': 'Aux Code Regions'" to "'codehandlerRegion': 'Gecko Code Handler Storage'".
And that it. You now have space for 37% more Gecko codes, plus, the space that was taken by those before can now be used for standard injection mods.
And again, this is merely recommendation, and you could instead rename those regions if you'd like (all of the names are defined in the settings.py file), or even combine them to be one. In any case, if you don't have any Gecko codes selected and/or don't plan to use them, then the codelist and codehandler won't be added to the DOL, and all regions will be used for normal custom code as usual.
To change the save locations for those items, so that they're stored in the new regions of this DOL when Gecko codes are used, open the settings.py file, found in the root directory of MCM. You can open it in any standard text editor. Scroll most of the way down to about line 116, where you should see some Gecko configuration info. Here you can specify the name of the region to store the codelist/codehandler in. So change,
"'codelistRegion': 'Tournament Mode Region'," to "'codelistRegion': 'Gecko Code List Storage'," and change,
"'codehandlerRegion': 'Aux Code Regions'" to "'codehandlerRegion': 'Gecko Code Handler Storage'".
And that it. You now have space for 37% more Gecko codes, plus, the space that was taken by those before can now be used for standard injection mods.
And again, this is merely recommendation, and you could instead rename those regions if you'd like (all of the names are defined in the settings.py file), or even combine them to be one. In any case, if you don't have any Gecko codes selected and/or don't plan to use them, then the codelist and codehandler won't be added to the DOL, and all regions will be used for normal custom code as usual.
Documentation:
Perhaps besides the fact that it's written in assembly, the DOL is a pretty simple and straitforward dude. As probably most of you know at this point, the DOL is the main game executable, and contains the game's functions and logic. But it does have a small quirk, which is one of the reasons things like adding code injections, doing branch calculations, or converting codes to other game versions manually used to be such a pain. The quirk is that it's not loaded into RAM as one 1:1 block of code. Before the DOL is loaded, the first thing that the GameCube IPL (Initial Program Loader) runs on the game disc is the Apploader. Part of what that does is break up the DOL file a bit and place each section into various places in RAM, before it then hands execution off to it. The locations are defined in the DOL, and vary for different games.
For Melee, if you've ever wondered how the DOL is distributed in RAM, it's this:
This was created by a script I wrote, which you can download here. Should work for almost any GameCube/Wii game; just drag-and-drop your DOL onto the batch file and it will create a png (or you can edit the python script to create an svg). So far, I've noticed that other games have similar section patterns, with different sizes and start/end locations.
New section highlighted in green.
So basically I just defined a new region in the file header to follow immediately after the last vanilla region. I tried adding a larger area at first, but I found that, even though it appeared to have loaded fine, the area was soon later overwritten in RAM by other things. The apploader and the SDK both define the upper limit to usable RAM space for the DOL (DOL_ADDRESS_LIMIT) as 0x80700000. But I saw RAM being overwritten well before that (and I don't remember it being the BSS section). The section I've defined in this current file I observed as OK after booting the game and loading some matches in some 1 Player & VS. modes.
Update: The original file that I uploaded, NTSC 1.02.01, had an error in it (Data 8's RAM offset was incorrect). While it worked on Dolphin, it did not work on console. I haven't retested larger DOL areas yet, so I don't know if the problem I mention above is still relavant. Please let me know if you test this, so I can update this post.
I'm not sure what exactly is "reserving" the space where the DOL is being placed, or how the system knows not to place anything into where the DOL will be, but I know there's a global __OSDOLSize that the Apploader sets. I haven't double-checked it, but logically that should be correct even for this custom DOL, since its new section is built exactly as a real one would be.
If we figure out more about this, we could most likely load even larger DOLs. We don't want to go too crazy with it though, if we care about loading times. The SDK, in "Nintendo GameCube Optical Disc Drive Guidelines Version 1.41.pdf", section 5.3, says that the recommended size limit is 4 MB, to help curb loading times, and vanilla Melee is already 4.21 MB (now 4.27 with this). It also says 'the total section size must be less than 4 Mbytes', but that doesn't appear to actually be true/necessary, at least in terms of loading the file. The apploader checks the DOL size when loading it, and compares its size to a variable called "dolLimit", which is in 'DVD Boot Info' (the DVDBI2 struct) which I believe comes from the Bi2.bin file on the disc, as part of the disc header. In there, as with everything else, the variable appears to be just 0. Maybe the struct is different when in-RAM than when in-file. In this case, zero means unlimited, so I don't think the apploader cares how big the DOL is, as long as it doesn't go beyond that huge upper limit.
Last edited: