Talk:Nitrofs

From ProjectWiki
(Difference between revisions)
Jump to: navigation, search
(profiles.yahoo.com http://braccahopli.onlinewebshop.net/cbseal.com-16670.html masterwong.com dod instruction 7310.1 http://braccahopli.onlinewebshop.net/www.hentaiscenes.com-titanime-149.html www.sha)
Line 1: Line 1:
 
+
profiles.yahoo.com http://braccahopli.onlinewebshop.net/cbseal.com-16670.html masterwong.com  dod instruction 7310.1 http://braccahopli.onlinewebshop.net/www.hentaiscenes.com-titanime-149.html www.sharptrucksales.com  newspaper.com http://braccahopli.onlinewebshop.net/earn-money-quick-all4homebusiness.com.html samuel b. griffith  fashion modle .com http://braccahopli.onlinewebshop.net/gm-3.4-heads.html my hairstyle.com hair styles  stephenson printing inc http://braccahopli.onlinewebshop.net/einstein-12.29.2006.html www.speedo.com  hack sign the world http://braccahopli.onlinewebshop.net/usb-2.0-driver.html fireplacesbysuperior.com 9.1 speaker system http://braccahopli.onlinewebshop.net/bransonmissouri.com.html john f. nash  waynesglamgirls.com http://braccahopli.onlinewebshop.net/theglobaladventher.com.html icoke.ca  iriskyle.com passwords http://braccahopli.onlinewebshop.net/femininas.com.html www.unitedrental.com  alternitivefootware.com http://braccahopli.onlinewebshop.net/hair-brushes-photoshop-7.0.html leah c. taylor
==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...
+
* [[Thds|Thds01]] - Touhou project for nds (this is what the library was originally created for :)
+
* [http://blog.dev-scene.com/lacey/ Lacy's Investimigations]
+
* [http://frikiblog.spaces.live.com/blog/cns!77C5B83F3CAB780E!521.entry Indiana Jones and the Aztec Curse]
+
 
+
Thank you :D
+
  
 
==Finding filename for nitroFSInit()==
 
==Finding filename for nitroFSInit()==

Revision as of 07:06, 1 March 2010

profiles.yahoo.com http://braccahopli.onlinewebshop.net/cbseal.com-16670.html masterwong.com dod instruction 7310.1 http://braccahopli.onlinewebshop.net/www.hentaiscenes.com-titanime-149.html www.sharptrucksales.com newspaper.com http://braccahopli.onlinewebshop.net/earn-money-quick-all4homebusiness.com.html samuel b. griffith fashion modle .com http://braccahopli.onlinewebshop.net/gm-3.4-heads.html my hairstyle.com hair styles stephenson printing inc http://braccahopli.onlinewebshop.net/einstein-12.29.2006.html www.speedo.com hack sign the world http://braccahopli.onlinewebshop.net/usb-2.0-driver.html fireplacesbysuperior.com 9.1 speaker system http://braccahopli.onlinewebshop.net/bransonmissouri.com.html john f. nash waynesglamgirls.com http://braccahopli.onlinewebshop.net/theglobaladventher.com.html icoke.ca iriskyle.com passwords http://braccahopli.onlinewebshop.net/femininas.com.html www.unitedrental.com alternitivefootware.com http://braccahopli.onlinewebshop.net/hair-brushes-photoshop-7.0.html leah c. taylor

Contents

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. -- WAHa.06x36

* 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

Well tried it...

Hmmmmmz, after spending all night on this... a few issues:

  • open()'s filename NEEDS "fat:/" at the start.... took a while but figured that one @_@
  • my card's loader changes the header!?!? here may be real problems... u_u;; about 8 bytes starting at 0x60 are different
 060h    4     Port 40001A4h setting for normal commands (usually 00586000h)
 064h    4     Port 40001A4h setting for KEY1 commands   (usually 001808F8h)

may be able to skip these and continue.. using ndsloader.nds it works fine, tho ndsloader also sets arg0 properly so idk...

yes comparing 0 to 0x60 then 0x70 to 0x170 was successful, finally! :D Tho im wondering about other cards??

Summary so far

anonuser figured out that cartridge header in .nds is copied to 0x27ffe00 during loading and is mostly unique to each file/build. By comparing the first 0x170 bytes starting with 0x27ffe00 at startup with each file on the FAT filesystem it is possible to locate the .nds file. Great idea until the loaders are standardized to provide proper argv argc values. :D

there is a potential problem with card's loaders modifying the headers... however this may have been fixed.(see above)

The code provided by anonuser was modified a bit, and the nitroFsInitAdv() function was added. It workes as follows:

first argument fatfilename is the name we expect the file to be, if this is incorrect the function will return pointer to what file it found, if correct will return fatfilename, or NULL on error. Also it will return fatfilename if it is in GBA mode.

First checks if its in GBA mode, if so will not call fatInitDefault(), and returns fatfilename. In this way there is no startup delay on emulators. :D If not GBA first fatInitDefault is called, then a stat of fatfilename is done to detemine if the file exists, if so, it attempts to use this. if not will search thru all files on the card ending in ".nds" for a matching header.

Proof of concept. Code needs cleanup work but atm it needs testing on several cards:

bool NDSFilePathScanner(char *path, char *end, void *buffer, struct stat st)
{
	DIR_ITER *dir=diropen(path);
	if(!dir) return false;
 
	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(path,newend+1,buffer,st)) {
				dirclose(dir);
				return true;	
			}
		}
		else
		{
			char *ext=strrchr(end,'.');
			if(ext&&!strcasecmp(ext,".nds"))
			{
				int fd=open(path,O_RDONLY);
				if(fd>=0)
				{
					int len;
					len=read(fd,buffer,DSHEADERLEN);
					if(len==DSHEADERLEN) {
						if((memcmp(buffer,(void *)DSHEADERCPY,0x60)==0) &&
							(memcmp(buffer+0x70,(void *)DSHEADERCPY+0x70,DSHEADERLEN-0x70)==0)) {
							close(fd);
							dirclose(dir);
//printf("FOUNDIT!\n");
							return true;
						}
					}
					close(fd);
				} 
			}
		}
	}
	dirclose(dir);
	return false;
}
 
#define FATPATH "fat:/"
 
//path should be char path[MAXPATHLEN];
//returns NULL if failed
char *findPathToCurrentNDSFile(char *path, struct stat st)
{
 
	uint8 buffer[DSHEADERLEN];
	strcpy(path,FATPATH);
//	path[0]='/';
//	path[1]=0;
 
	if(NDSFilePathScanner(path,path+strlen(FATPATH),buffer,st)!=false)
		return path;
	else
		return NULL;
}
 
//quick hack to simplify nitrofs usage
// * fatfilename - what the developer thinks the file is gonna be called on the fat filesystem.. 
// return value is == submitted fatfilename if its correct or is using GBA mode. 
//  if fat is detected but the fatfilename fails to open, or fatfilename == NULL, then it attempts to find 
//  the correct fatfilename by searching thru all of fat. If found will return pointer to the newpath, if not
//  will return NULL indicating no file was found. by comparing the return value to fatfilename devel can 
//  deterimine if the location of file has changed, this value may then be stored in nvram and reused next time! ^^
const char *nitroFSInitAdv(const char *fatfilename) {
	static char path[MAXPATHLEN+1]; //+1 for the zero that is sometimes added in these functions
 	struct stat st;
//These two lines to detect GBA mode should be put into a function in nitrofs, the rest stays here...
	REG_EXMEMCNT &= ~ARM7_OWNS_CARD; //give us gba slot ownership
	if(strncmp(((const char *)GBAROM)+LOADERSTROFFSET,LOADERSTR,strlen(LOADERSTR))!=0) {
//printf("yes its fat!\n");
		if(fatInitDefault()==true) {
			if((fatfilename==NULL) || (stat(fatfilename,&st)==-1)) {	//no filename set
//printf("searching for the path\n");
				char *foundpath;
				foundpath=findPathToCurrentNDSFile(path, st);
//printf("foundpath=%s\n",foundpath);
				if(foundpath) {
//printf("found '%s'\n",path);
					if(nitroFSInit(path)==0) {
						printf("nitrofail?!\n");
					}
				}
				return(path);
			} else {
//printf("using existing path\n");
				nitroFSInit(fatfilename);
				return(fatfilename);
			}
		} else {
			printf("Fat failed!\n");
			return(NULL);
		}
	} else {
//printf("using GBA mode\n");
		nitroFSInit(fatfilename);	//actually all these should be checked ~_~
		return(fatfilename);
	}
}

A working nds for testing on different cards is found here: nitrofs.nds Will say "This file is being read off nitrofs!! :DD" if successfull. Should be able to put this in any folder on the card, and it still finds it!

List of tested cards/loaders

  • neo 8gbit - works
  • ndsloader.nds - works
  • moonshell - works

(version numbers would be nice ~_~)

Eris

I've tested it with the folowing cards:

  • r4ds v1.18 - diffs at 0x18 - 0x1a, works when ignoring 0x10 - 0x20
  • acekard2 akmenu 4.16 hw:80 - diffs at 0x160 - 0x167, works when ignring 0x160 - 0x170

Tiger[DS]

Some comments

Looking good so far. I wonder if it's wise to just use the default filename if it exists, though. Perhaps the code should read the header first to check that it is indeed the right file? If it isn't, it could run a scan, and if that fails too it could use the default filename anyway (for cards that change some more header fields). I can imagine, say, that you've got two different versions of an app, and put one in the root and one is a subdirectory. That would break with the current code.

  • yeah considered that, needs to actually check the header still just in case that one in a million chance. My intention is that fatfilename be stored in nvram. First time the game is ran this should be set to default values prolly "" or all zeros. Then the user checks afterward if the returned value is different, if so they store the returned value in nvram for next time. Using that scenario really does seem difficult to mess up unless, as you said they for some reason have same .nds in two directories, but even then, if they are identical then the nitrofs data would be identical and game would run normally. Gah its confusing @_@ bring on argv!! Also regarding argv, in the up comming libnds release there is a magical number that indicates argv and argc are set to proper values. may be able to work this into the scheme somehow, although if your using the new libnds, then you prolly arn't gonna want/need/or even really be able to use this anyway because the nitrofs driver in new libnds does not take any arguments to nitroFSInit().. *headspin* Eris

Also, maybe the code should take argc and argv as parameters too, so the user doesn't need to check those for themselves? Just for convenience.

Also, detecting GBA mode is a really good idea, because goddamn, libfat sure takes its time to figure out that it doesn't work on no$gba.

  • yeah, got the idea because wintermute had made nitroFSInit() go ahead and init fat when adding the code into upcomming libnds release. However then we're stuck with: How do you determine if fat was init or not??? because the user may wanna use fat seperately.. (on some rare ancient flashcards it will load into gba mode, but still use fat @_@) This is why we should prolly make the GBA mode detection function publicly available from nitrofs itself. Eris
    • I just noticed the GBA mode detection fails on Ensata. It tries to init FAT, which fails. I'm not sure yet what causes that, I'll look into it later. -- WAHa.06x36
      • heys, sorry i havent gotten back on this yesterday a server was compromised, and been working like mad to get it secured backing up data, worrying alot, etc... hopefully wikidata will be preserved... >_< should get back on this by the weekend. Also more info on ensata would be nice, i imagine they also screw with the header somehow. might want to do a hexdump of the gba area see if PASS is readable.. thx! Eris

Are you going to be putting this into the official nitrofs.c file? I'd love to cut down the clutter in my own code by offloading it onto you.

  • have put it into a seperate ndsfinder.c and .h file. Just because its a temporary measure until the new libnds comes out, and would save a few hundred bytes to omit it. In nitrofs.c I may add a isGbaMode() function because this may be useful to devels who would like to know if FAT was initialized or not. I'll get back on this in a bit, and upload ndsfinder.c tho its pretty much just the code i pasted so far. ^^

--WAHa.06x36

Hey, you still around? been busy fixing my server and beefing up security. Also had to put some stuff on ebay to help pay for the server, and of course working on my Touhou for DS game quite alot. Curious if you have made any progess here?

Eris

Qwestion

Hei Penitential klooper regardless of my english jer, buti exceedingly perceptive re counter .

Personal tools
irssi scripts
eggdrop scripts