gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > How do I work this FAT driver thing?

#69156 - HyperHacker - Sat Jan 28, 2006 9:20 pm

I downloaded Chism's FAT driver, extracted it, and put the gba_nds_fat directory in my NDSLib include directoy (as I couldn't see any documentation saying where I should actually be putting it). Read through the header files, include gba_nds_fat.c, and write a simple test app to open a file, write to it, and close it. When I try to compile I get about 2000 'undefined reference' errors. Including more of the .h and .c files mostly fixed this (if they're required, why aren't they included in gba_nds_fat.h?) but I still got undefined reference errors regarding M3CF_GetInterface, MPCF_GetInterface etc... I've tried including both the .h and .c files that these are in, but that just makes a lot more errors! >_< How exactly am I supposed to use this?

Also, I get other errors that should be checked out...
Code:
F:\dos\DevKitPro\libnds\include/gba_nds_fat\gba_nds_fat.c:219: warning: non-local variable '<anonymous enum> filesysType' uses anonymous type
F:\dos\DevKitPro\libnds\include/gba_nds_fat\gba_nds_fat.c: In function 'u32 FAT_ftell(FAT_FILE*)':
F:\dos\DevKitPro\libnds\include/gba_nds_fat\gba_nds_fat.c:2302: warning: converting negative value '-0x000000001' to 'u32'


This is all my ARM9 code does:
Code:
int main(int argc, char** argv)
{
   powerON(POWER_ALL_2D); //Turn stuff on (required for some flash cards)
   //videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
   videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
   videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
   vramSetMainBanks(VRAM_A_MAIN_BG_0x6000000, VRAM_B_LCD, VRAM_C_SUB_BG_0x6200000, VRAM_D_LCD);
   MainScreenBuf = CreateGraphicBuffer(SCREEN_WIDTH,SCREEN_HEIGHT);
   SubScreenBuf = CreateGraphicBuffer(SCREEN_WIDTH,SCREEN_HEIGHT);
   lcdMainOnTop();

   BG3_CR = BG_BMP16_256x256;
   BG3_XDX = 1 << 8;
   BG3_XDY = 0;
   BG3_YDX = 0;
   BG3_YDY = 1 << 8;
   BG3_CX = 0;
   BG3_CY = 0;

   SUB_BG3_CR = BG_BMP16_256x256;
   SUB_BG3_XDX = 1 << 8;
   SUB_BG3_XDY = 0;
   SUB_BG3_YDX = 0;
   SUB_BG3_YDY = 1 << 8;
   SUB_BG3_CX = 0;
   SUB_BG3_CY = 0;

   //Init interrupts
   REG_IME = 0; //Disable interrupts while changing them
   IRQ_HANDLER = Interrupt; //Set handler callback
   REG_IE = IRQ_VBLANK; //Interrupt on vblank only
   REG_IF = ~0;
   DISP_SR = DISP_VBLANK_IRQ;
   REG_IME = 1; //Enable interrupts

   swiWaitForVBlank();
   swiWaitForVBlank();
   swiWaitForVBlank(); //Let things set up

   uint32 Coords = 0;
   if(!FAT_InitFiles())
      Coords = printxy2(MainScreenBuf,0,(Coords >> 16),(Coords & 0xFFFF),"FAT_InitFiles() failed\n");

   FAT_FILE* fp = FAT_fopen("/test.bin","w");
   if(!fp)
      Coords = printxy2(MainScreenBuf,0,(Coords >> 16),(Coords & 0xFFFF),"FAT_fopen() failed\n");

   char data[] = "All your base!\xFF\x00\x0A\x0D\xD0\x6F\xEC\xE5";
   Coords = printxy2(MainScreenBuf,0,(Coords >> 16),(Coords & 0xFFFF),"fp=0x%08X\nWrote %d of %d bytes\n",fp,FAT_fwrite(data,1,sizeof(data),fp),sizeof(data));
   Coords = printxy2(MainScreenBuf,0,(Coords >> 16),(Coords & 0xFFFF),"FAT_fclose() returned %d\n",FAT_fclose(fp));
   SwapBuffers = true;


   while(true) swiWaitForVBlank();
   return 0;
}

void Interrupt()
{
   if(REG_IF & IRQ_VBLANK) //VBlank interrupt
   {
      KeysPressed = IPC->buttons_pressed; //Best to keep a local copy, since the ARM7 may modify it
      KeysHeld = IPC->buttons_held;

      if(SwapBuffers)
      {
         dmaCopyWords(0,MainScreenBuf->Pixels,BG_GFX,(SCREEN_WIDTH*SCREEN_HEIGHT) << 1);
         dmaCopyWords(1,SubScreenBuf->Pixels,BG_GFX_SUB,(SCREEN_WIDTH*SCREEN_HEIGHT) << 1);
         SwapBuffers = false;
      }

      VBLANK_INTR_WAIT_FLAGS |= IRQ_VBLANK; //Signal that vblank interrupt has been processed
      REG_IF |= IRQ_VBLANK; //Signal that vblank interrupt processing is done. We need to trigger a write even though this shouldn't change the value.
   }
   else
      REG_IF = REG_IF; //Trigger a write
}


ARM7 is just in a loop fetching system info, it isn't involved in FAT so it's not really important.

[edit] Well, poo. In my not-quite-awake state of mind I'd forgotten to include one of the headers. ^_^;; For anyone else having problems, all I had to do was copy the gba_nds_fat folder into the libnds include folder (where you'll find nds.h and the nds folder) and include quite a few files in my main header:
Code:
#include <gba_nds_fat\io_mpcf.h>
#include <gba_nds_fat\io_fcsr.h>
#include <gba_nds_fat\io_m3cf.h>
#include <gba_nds_fat\io_sccf.h>
#include <gba_nds_fat\gba_nds_fat.h>
#include <gba_nds_fat\disc_io.h>

#include <gba_nds_fat\gba_nds_fat.c>
#include <gba_nds_fat\disc_io.c>
#include <gba_nds_fat\io_mpcf.c>
#include <gba_nds_fat\io_fcsr.c>
#include <gba_nds_fat\io_m3cf.c>
#include <gba_nds_fat\io_sccf.c>


One thing I noticed, though, is it killed the volume name! The card used to show up as "LEXAR MEDIA" (the default name I didn't bother to change) in Windows, but now just shows "Removeable Drive" just as if no card were inserted. It works fine, just the name is gone. O_o (Or maybe it's a Windows thing.)

[edit 2]
Quote:
H:\>vol
Volume in drive H is LEXAR MEDIA
Volume Serial Number is 19D3-1D2F

False alarm. Just Windows being weird again.

#69426 - cory1492 - Mon Jan 30, 2006 7:16 pm

you put the source and headers directly in with your other source code that you are compiling, and #include "gba_nds_fat.h", you can also use the source line in the makefile to include the gbandsfat dir wherever you put it (instead of dropping source code files in with a pre-compiled ndslib library)

You could also pre-compile it in a similar way to how ndslib is compiled (see its makefile from cvs) and drop a .a and the .h files into ndslib, otherwise you will keep having to compile the source files (although I dont know why you have to include them).

#69531 - HyperHacker - Tue Jan 31, 2006 9:25 am

Is it absolutely necessary to copy the files into my source every time? Just leaving them in their own directory in \ndslib seems to have worked fine, and it's a lot cleaner that way. (No having the same files scattered about each source directory, and a lot easier to fix things in them.)

#69562 - FireSlash - Tue Jan 31, 2006 3:19 pm

Yeah, that should work.

You WILL get weird side effects from using the FAT lib. Files and folders will magically dissapear, volumes will modify themselves, and other strange things are liable to happen. Its probably a good idea to run chkdsk /r every week or so.
_________________
FireSlash.net

#69634 - josath - Tue Jan 31, 2006 9:52 pm

yeah, rain corrupted my CF card once...so basically the FAT lib is very experimental code which is known to corrupt the filesystems. I think as long as you are only reading, it should be safe (someone who knows how it works should say this, dont take my word)