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.

ASM > Using libfat from asm

#167447 - headspin - Thu Mar 12, 2009 1:32 pm

Were writing a game in pure asm and would like to break the 4 MB limit of the DS because we wan't some high quality music playing in the background.

After quite a bit of research I've found our only choice is to use libfat. We may just have to accept the fact that some "C" code will be required to support libfat, but I guess we'll have to get over that.

Right now I have written a libfat_demo.zip where it reads two image files ("fat2:/dev/pic1.bin" and "fat2:/dev/pic2.bin") and dmacopy them into VRAM.

I have managed to get this working but for some reason I have to add 9108 bytes to the buffer for it to display the full picture. I have no idea where this value comes from as the data is raw and I have sucessfully dma'ed the same files using bin2o and gbfs so I'm not sure what's going wrong.

Here is my readFile() function

Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

unsigned char *buffer = NULL;

int readFile(char *fileName)
{
   FILE *pFile;
   struct stat fileStat;
   size_t result;
   
   if(buffer != NULL)
      free(buffer);

   pFile = fopen(fileName, "rb");
   
   if (pFile == NULL)
      return 0;

   if(fstat(pFile->_file, &fileStat) < 0)
      return 0;

   buffer = (unsigned char *) malloc(fileStat.st_size);
   
   if (buffer == NULL)
      return 0;

   result = fread(buffer, 1, fileStat.st_size, pFile);
   
   if (result != fileStat.st_size)
      return 0;

   fclose(pFile);
   
   return fileStat.st_size;
}


And here is my code to dmacopy the buffer into VRAM

Code:
bl fatInitDefault

ldr r0, =strPic1
bl readFile

mov r1, #BG_BMP_RAM(0)
mov r2, r0
ldr r0, =(buffer + 9108)
bl dmaCopy

ldr r0, =strPic2
bl readFile

mov r1, #BG_BMP_RAM_SUB(0)
mov r2, r0
ldr r0, =(buffer + 9108)
bl dmaCopy


Everything seems to be working fine apart from this strange 9108 byte offset. Why do I need to add that value to get the full picture displayed?

Also is there a way I can read the files from the same folder the .nds file is in? I seem to have to give the full path which would force people to use a file structure and I would prefer to avoid that.
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#167450 - Ruben - Thu Mar 12, 2009 3:10 pm

Because you have to read the buffer first. :)

Aka..

Code:
ldr r0, =buffer @ Get address of unsigned char *buffer;
ldr r0, [r0] @ Get the pointer stored in 'buffer'


EDIT:
You might be able to get away with "ldr r0, buffer" to avoid 2 loads, but it will depend on the location of "buffer" (you can probably declare it in the assembler file to be sure it will be nearby).

#167468 - headspin - Thu Mar 12, 2009 11:49 pm

Thanks for that Ruben. I can't believe I missed that. I guess that's what happens when you code tired!

I did notice there seems to be some buffer corruption and the very beginning and end which dispalys on the screen as a few random pixels. I have no idea what that could be.
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#167472 - elhobbs - Fri Mar 13, 2009 3:45 am

you probably need to flush the data cache. dma bypasses the data cache and reads the memory directly.
Code:
DC_FlushAll();