Talk:Nitrofs

From ProjectWiki
(Difference between revisions)
Jump to: navigation, search
(Finding filename for nitroFSInit())
(Finding filename for nitroFSInit())
Line 168: Line 168:
 
* Oh, thanks. been wanting something like this but too busy to write it.. ill give it a try later, might tweak a few things, but otherwise looks very promising.
 
* Oh, thanks. been wanting something like this but too busy to write it.. ill give it a try later, might tweak a few things, but otherwise looks very promising.
  
[http://nocash.emubase.de/gbatek.htm#dscartridgeheader] <-- Ohh i didn't know this! Very nice :PPP
+
[http://nocash.emubase.de/gbatek.htm#dscartridgeheader http://nocash.emubase.de/gbatek.htm#dscartridgeheader] <-- Ohh i didn't know this! Was wondering where 0x27ffe00 came from. Very nice :PPP
  
[[User:Eris|Eris]]
+
[[User:Eris|Eris]]

Revision as of 23:08, 17 August 2008

Contents

Hellos...

Hi, thanks for viewing and hope you find the file-system driver useful. Have tried best to make the read-only nitro driver possible but here you may help improve it with comments, bugs report, and questions.

Feel am getting close to a 'final' release, however always seems something is left undone. u_u Really so long as no bugs are found v0.6 might just be the winnar! Am i forgetting anything?? >_>

Changes notes

Just today (2008-05-01) heard there was a discussion about nitrofs on gbadev's forums, and found out why i was not able before to use a .nds file with emulators. Both thanks to Wintermutes Thx!!!!!! :DD

After reading the forums found out there was a bug with fseek() and the SEEK_CUR, i am sorry. u_u This was not noticed immediately as I only used SEEK_SET in testing. The problem turned out to be an improper return value in my fseek() function. Guess i should thank noda for pointing this out, and btw, hellos! ^^/

Now, a single .nds file should work equally well with both emulators and flashcards, hopefully... I tried this before in the previous version but did not realize passing -o option to ndstool prevented GBA access. After fixing the Makefile and zeroing the offset used previously for the older style .ds.gba

2008-05-21 - fixed ftell() issues, and re-enabled support for ds.gba files in addition to .nds on emulators (best of both worlds! :PP).. also added stat() support for reading file lengths w/o opening..

2008-05-26 - Added chdir() functionality, lets see how long till someone usurp the insanely simple method...

2008-06-16 - Relased turbo version.

2008-06-19 - So soon another release :D this time "." and ".." is fully supported!! YAY!!

Why not read from the card directly?

Noticed someone asked about this on another forum. I'll try to explain (based on what i've been told so please correct me if am wrong)...

Original games are encrypted and read over SPI buss from the card which decrypts using hardware. When these games are loaded off flashcards, the flashcard's loader modifies the card/SPI functions which are patched to use flashcard specific functions that emulate normal SPI access to the card's data.

The details of this are foggy, since flashcard companies don't wanna say what they are doing exactly and help competitors. :/ So to make homebrew that uses official SPI style calls would be sort of pointless since the loaders would prolly not pick up on this, not patch them, and thus not work at all.

eris 

Multiple vs Single FAT filehandles when in .nds mode

After pondering this a bit, have decided most uses would prefer quicker open/close times versus a very slight slowdown when reading from multiple files.

When using the .nds file and FAT, is there any advantage in using opening only one ".nds" instead of opening a ".nds" file for each file opened on the nitrofs.

fopen uses up quite a few cpu cycles, so obviously f/opening of files from the nitrofs would be faster if the same .nds file were used instead of opening a new one each time. This would speed up most other operations as well such as directory openings, file/dir closes, stat() calls, etc.

What happens if your reading from two nitrofs files at once?? In this case the single .nds file would need be seeked back and forth like crazy every time a different nitrofs file was read from. Have heard that FAT may take a bit of time to search the allocation tables and change file position, is this take any longer than opening up multiple files that hafta read from different positions on the card, and how the different DLDI implementations would affect this is truly a guess to me??? If anyone wants to try I'd like some feedback here.

I tested it with my newflash 8gbit, here are the results:

Single vs Multiple .nds *
Test Multi Single diff
2files 956 1078 -122
fread 432 326 106
read 338 232 106
shortread 113 5 108
  • all results in ms

2files
this test reading 2 files simultainiously, 0x100 bytes at a time, over 10327 reads (file is 1032793 bytes), one file is fopen'd other is open'd.

As i suspected, reading multiple files with single .nds file is slower, but.... not by much at all, especially given the number of reads this spans.

fread & read
just freading (or reading) the same 1032793 byte file. Times include open/close calls. here the winner is the single file mode, saving about 106ms for both methods. open is always gonna be a bit faster because its a simpler method than fopen (this is why i prefer open to fopen *shrug*)

shortread
ok this is reading a short 16 bytes or so from a file and doing a bit of seeking around. Here the biggest advantage can be seen. If your opening alot of small files (as i suspect most will be doing) there would be a big improvement as all those fopen/open calls add up.

Bug in ndstool

Screenshot showing original file included into the nitrofs on the left, and the ndstool generated .nds file with mangled last byte on the right.

There is a bug in ndstool causing the last byte of the last file included into nitrofs to be 0!! Its a wonder no one has spotted this before rly. Thanks to Lacey for pointing this out and helping to find/fix it.

The bug was in the way it ensured the filesize would align along 4 byte borders, always zeroed last byte of file. Below is a diff, and a precompiled version until the next DKP update.

If you use the binarys or recompile the cvs sources, it may say something like:

Cannot open file 'c:/devkitPro/libnds/default.arm7'.

thats because the name of the default arm file has changed from basic.arm7 to default.arm7, just copy or ln -s basic.arm7 to default.arm7 and it should work. :D

heres a diff:

Index: ndstool/source/ndscreate.cpp
===================================================================
RCS file: /cvsroot/devkitpro/tools/nds/ndstool/source/ndscreate.cpp,v
retrieving revision 1.44
diff -u -r1.44 ndscreate.cpp
--- ndstool/source/ndscreate.cpp        14 Apr 2008 02:31:14 -0000      1.44
+++ ndstool/source/ndscreate.cpp        19 Jun 2008 04:12:45 -0000
@@ -581,10 +581,12 @@
 
        // align file size
        unsigned int newfilesize = file_end;    //ftell(fNDS);
-       newfilesize = (newfilesize + 3) &~ 3;   // align to 4 bytes
-       header.application_end_offset = newfilesize;
-       fseek(fNDS, newfilesize-1, SEEK_SET); int c = fgetc(fNDS);
-       fseek(fNDS, newfilesize-1, SEEK_SET); fputc((c >= 0) ? c : 0, fNDS);
+       if(newfilesize & 3) {
+               newfilesize = (newfilesize + 3) &~ 3;   // align to 4 bytes
+               header.application_end_offset = newfilesize;
+               fseek(fNDS, newfilesize-1, SEEK_SET); int c = fgetc(fNDS);
+               fseek(fNDS, newfilesize-1, SEEK_SET); fputc((c >= 0) ? c : 0, fNDS);
+       }
 
        // calculate device capacity
        newfilesize |= newfilesize >> 16; newfilesize |= newfilesize >> 8;

Games/Projects using Nitrofs

Below is a list of projects using the nitrofs driver. Thought of adding this to main page but figured should start here first. Curious who is using this and what they're working on, add to list if you wish...

Finding filename for nitroFSInit()

Here is some code I wrote to find the filename of the currently loaded NDS file. It relies on the fact that the header is quite probably unique for any given ROM, and so scans through the filesystem and checks all NDS files. It seems to run quite fast enough to be useful.

int NDSFilePathScanner(char *path,char *end,void *buffer)
{
	static struct stat st;
	DIR_ITER *dir=diropen(path);
	if(!dir) return 0;
 
	while(dirnext(dir,end,&st)==0)
	{
		if(end[0]=='.') continue; // skip all entries beginning with a .
		else if(st.st_mode&S_IFDIR)
		{
			char *newend=end+strlen(end);
			newend[0]='/';
			newend[1]=0;
			if(NDSFilePathScanner(buffer,newend+1,buffer)) return 1;
		}
		else
		{
			char *ext=strrchr(end,'.');
			if(ext&&!strcasecmp(ext,".nds"))
			{
				int fd=open(path,O_RDONLY);
				if(fd>=0)
				{
					if(read(fd,buffer,0x170)==0x170)
					if(!memcmp(buffer,(void *)0x27ffe00,0x170)) return 1;
					close(fd);
				}
			}
		}
	}
	dirclose(dir);
	return 0;
}
 
char *FindPathToCurrentNDSFile()
{
	static char path[MAXPATHLEN];
	static uint8 buffer[0x170];
 
	path[0]='/';
	path[1]=0;
 
	if(NDSFilePathScanner(path,path+1,buffer)) return path;
	else return NULL;
}

Feel free to add this to nitro.c too. I'd suggest making an init function that takes argc, argv and a default filename, and uses the name supplied by argc and argv if available, else tries to use this code to find it, and if that fails, uses the default name passed in. That is what my code does at the moment, anyway.

  • Oh, thanks. been wanting something like this but too busy to write it.. ill give it a try later, might tweak a few things, but otherwise looks very promising.

http://nocash.emubase.de/gbatek.htm#dscartridgeheader <-- Ohh i didn't know this! Was wondering where 0x27ffe00 came from. Very nice :PPP

Eris

Personal tools
irssi scripts
eggdrop scripts