• My previous blogs have been full of complaints about libgba already but we can add libfat to the party aswell! In the days with many different flashcards on both GBA and DS there were issues with compatibility for homebrew and a solution was created called DLDI. In simple terms it allows for a driver to be patched into the homebrew that enables it to access the specific flashcard hardware. And this DLDI layer then gives libfat something to talk to and access the files on the flashcard. This works great on the DS with it's many variations of storage options that used SLOT-2 and later SLOT-1 cards that auto-patch the specific DLDI driver at runtime. This way homebrew was compatible with any card that had a DLDI driver for it and you would think that DLDI was the solution then right?

    That's where I get to my point and the struggle mentioned in the title....for many hours I have tried to solve outdated compiler issues on a modern toolchain. But no matter what I tried DLDI seems to only work for DS and unlike this site makes you beleive it does NOT WORK on the GBA!! At least not without patching libfat to make use of it that is!!! You see, the DLDI layer is present in libgba for libfat to talk too but it does not. So I dived into it and figure out how to make DLDI work on the GBA and load a driver for my SuperCard miniSD. Just to not scare anyone I put the code example into a spoiler block, but it shows and explaines what's missing to make DLDI work on the GBA.

    Code:
    /* ====================== NDS ====================== */
    #elif defined (NDS)
    #include <nds/system.h>
    #include <nds/memory.h>
    #include <nds/arm9/dldi.h>
    
    const INTERFACE_ID _FAT_disc_interfaces[] = {
        {"sd",  get_io_dsisd},
        {"fat", dldiGetInternal},
        {NULL, NULL}
    };   
    
    /* ====================== GBA ====================== */
    #elif defined (GBA)
    #include <disc.h>
    
    const INTERFACE_ID _FAT_disc_interfaces[] = {
         {"fat", discGetInterface},
        {NULL, NULL}
    };   
    
    I am sure without programming experience you might not see what's happening here. In the fist section labeled NDS it includes header files telling the compiler about the memory address and value types used by libnds. Then it tries to detect the DSi SD cardfirst and then a DLDI driver. Below that is a section labeled GBA and it calls a different function named discGetInterface() that is part of libgba. This function in theory loops through a series of popular GBA flashcarts and tries to initialize one of them. This explains why it takes a little while for fatInitDefault() to fail on the GBA as it needs to try every single one of those drivers first. Even while the SuperCard SD is included mine are not detected. Possibly they are clones that work differently or the SCSD is truly different form the miniSD version that I have.

    Funny thing is that libgba actually has a dldiGetInternal() function but it either not used (anymore) or it never was! Or for those that wanted to make use of it had to do just what I have done....and replace the function "discGetInterface" with "dldiGetInterface" and compile it myself. So while I can't complain it's not available at all this time ;)...it is hidden deep inside the libraries and absolutly NO clue on how to use it! At least I did not find anything!

    So what I did was add the DLDI header and changed the function name to have libfat compatible with the dlditool:
    CODE]/* ====================== GBA ====================== */
    #elif defined (GBA)
    #include <disc.h>
    #include <dldi.h>

    const INTERFACE_ID _FAT_disc_interfaces[] = {
    // {"fat", discGetInterface},
    {"fat", dldiGetInternal},
    {NULL, NULL}
    };[/CODE]
    And by recompiling libfat with these changes and having my Makefile use this one instead of the one included in Devkitpro I could finally patch in the DLDI drivers I had found for the SuperCard SD. Unfortunatly the card is not detected and I still get errors from fatInitDefault()! Using the GBAMP CF driver was a little more successful as it passes the initialize function and can read files from the card. It also created the directories required during the BatteryCheck install and all filenames are created....as empty files with 0 bytes!! I am not sure if this was because of the DLDI driver or an issue of running out of memory which is sparse on the GBA ofcourse. Even with DLDI patching working now it's useless if the drivers are apparently not working!
    Because I wanted to make sure the DLDI drivers are actually working I wanted to try them on the DS. So I have ported over my "GBA abstraction layer" to the DS and that was quite easy since they are very similar. I first tried writing to the SD card of the SuperCard DS One which does auto-patching for it's DLDI driver and just magically works! I also have an M3 Simply and that did not work at first until I read it needed manual patching with the "R4 drivers" as it was noted somewhere that might work. And it did! On both SLOT-1 cards the files are extracted and I checked the SHA1 hashes of the extracted files which were a perfect match! Funny how my attempt of porting to the GBA ends up working earlier and better on the DS instead! Even when it's really only the installer unpacking the gamefiles that's currently running:D

    What is not working in the DS installer (yet) is unpacking setup.exe directly from batterycheck.zip as that file is 12MB and that does not fit into the DS or GBA onboard RAM. The reason for that is that on the other platforms I can simply unpack it entirely into a 12MB buffer because the RAM is available, and it's MUCH faster this way too. Maybe I should rewrite it a little to switch to unpacking the file to the SD card on the DS for now and either delete it when done or leave it there. That should at least make it possible to just drag and drop the ZIP file onto the card I guess :D

    0 Comments

You need to be logged in to comment