One of the biggest annoyances when developing a homebrew application for the Nintendo DS is when your application is using the FAT library to read files and you want to be run your application in an emulator like nocash (no$gba) and have it work on the DS with minimal changes.
I have finally found a technique to do this that works very well. It lets you use FAT file access in an NDS emulator or another way to put it is libfat in an emulator. The only catch is that is only works for reading and not writing. The result is also in two separate NDS roms. One works in the emulator and one will work on your DS. However, this big plus is that your homebrew code does not need to change to work with both. It allows you to code, test, and repeat without any extra work.
I found the information to solve this issue from two separate articles:
- FCSR Tutorial – I actually just found this so haven’t used it myself, but it looks simpler and I think it should work too.
Something to remember is that I have only been able to get .ds.gba files to work in the no$gba emulator. I don’t know why, but the other filenames don’t seem to work.
- Development Environment Set Up – Refer to various tutorials for creating NDS homebrew using the devKitPro method. The devKitPro install includes the libfat library.
- fcsrimage – download link is on the left hand side of GPF Dev Site.
- fcsr.dldi file – download link is on the left hand side of GPF Dev Site.
- dlditool – this is included with you devKitARM installation
- no$gba NDS emulator. Download the latest version.
- Your own dldi file for your homebrew card if you want to patch for it too.
Procedure For Setting Up the NDS Filesystem
Assuming that the file structure in C:\files represents the files that will be on the flash card and that your NDS homebrew app is called nds_app.
The basic process is as follows:
- Unzip the fcsrimage application from above and then change directory into this folder.
- build nds_app.img c:\files
- copy nds_app.img to the folder with nds_app.ds.gba. It is important that you have the .ds.gba file. no$gba doesn’t appear to work if it isn’t that extension.
- padbin 512 nds_app.ds.gba
- cat nds_app.ds.gba nds_app.img > nds_app_fs.ds.gba
- dlditool fcsr.dldi nds_app_fs.ds.gba. This file should now work in the no$gba emulator.
- You should already know how to patch your main rom for your homebrew card, but if not I run this command: dlditool sclt.dldi nds_app.nds
After this, you should now have to roms: nds_app_fs.ds.gba (the _fs is for filesystem) and nds_app.nds. The first file will work with a libfat homebrew app in no$gba and the second will work on the DS hardware itself.
Makefile Changes To Automate It
I use the same Makefile that is packaged in the PALib examples.
Look for these targets in your Makefile and change the sections to look like this. Keep in mind I have mine also dldi patching for the supercard lite. You can swap that out for you own card. Some assumptions in my explanation are:
- Assume your application is stored in C:\nds_app folder.
- Your .dldi files (including fcsr.dldi plus your homebrew card’s dldi…mine is sclt.dldi) are stored in the $(devkitARM)/bin/dldi folder.
- You previously created your filesystem image as C:\nds_app\nds_app.img.
cd C:\fcsrimage build C:\nds_app\nds_app.img C:\nds_app\data
# Makes a temporary copy before appending the filesystem # image and that dldi patching it for use in an emulator. %.ds.gba: %.nds @echo built ... $(notdir $@) @dsbuild $< @cp $(CURDIR)/../$(notdir $@) ../$(notdir $(OUTPUT)).sc.nds @cp $(CURDIR)/../$(notdir $@) ../$(notdir $(OUTPUT))_temp.ds.gba @padbin 512 $(OUTPUT)_temp.ds.gba @cat ../$(notdir $(OUTPUT))_temp.ds.gba ../$(notdir $(OUTPUT)).img > ../$(notdir $(OUTPUT))_fs.ds.gba @dlditool fcsr.dldi ../$(notdir $(OUTPUT))_fs.ds.gba @rm ../$(notdir $(OUTPUT))_temp.ds.gba # This auto dldi patches for the supercard lite # I don't have USE_EFS enabled so it is always # using the else part. #--------------------------------------------------------------------------------- %.nds: %.bin ifeq ($(strip $(USE_EFS)), YES) @ndstool -c $@ -9 $(TARGET).bin $(ARM7BIN) $(LOGO) $(ICON) "$(TEXT1);$(TEXT2);$(TEXT3)" -d ../efsroot @$(CURDIR)/../efs $(OUTPUT).nds @cp $(CURDIR)/../$(notdir $@) ../$(notdir $(OUTPUT))_SC.nds @dlditool sclt.dldi ../$(notdir $(OUTPUT))_SC.nds else @ndstool -c $@ -9 $(TARGET).bin $(ARM7BIN) $(LOGO) $(ICON) "$(TEXT1);$(TEXT2);$(TEXT3)" @cp $(CURDIR)/../$(notdir $@) ../$(notdir $(OUTPUT))_SC.nds @dlditool sclt.dldi ../$(notdir $(OUTPUT))_SC.nds endif
I find this works the best for me, except that I am still manually running the build command in the fcsrimage folder to create the .img filesystem. If you can give me the Makefile commands to do that too, I would be eternally grateful.