#include <nds.h>
#include <fat.h>

#include <stdio.h>
#include <stdlib.h>

void pause() {
	iprintf("Press A to continue...\n");
	while (1) {
		scanKeys();
		if (keysDown() & KEY_A)
			break;
		swiWaitForVBlank();
	}
	scanKeys();
}

int main(int argc, char **argv) {
	tGBAHeader head;
	int saveSize, i;
	char file[15] = "fat1:/****.SAV";
	u8 memory[128 * 1024];
	// Note, we force this to be volatile, because we can actually touch the memory.
	vu8 *sramPtr = SRAM;
	
	// Init the console.
	consoleDemoInit();
	
	// Give ARM9 ownership.
	sysSetBusOwners(true, true);
	
	iprintf("Detecting ROM...\n");
	head = GBA_HEADER;
	
	if (!memcmp(head.gamecode, "AXVE", 4)) {
		iprintf("Detected Pokemon Ruby.\n(Save Size: 128K)\n");
		saveSize = 128 * 1024;
	} else if (!memcmp(head.gamecode, "AXPE", 4)) {
		iprintf("Detected Pokemon Sapphire.\n(Save Size: 128K)\n");
		saveSize = 128 * 1024;
	} else if (!memcmp(head.gamecode, "BPEE", 4)) {
		iprintf("Detected Pokemon Emerald.\n(Save Size: 128K)\n");
		saveSize = 128 * 1024;
	} else if (!memcmp(head.gamecode, "BPRE", 4)) {
		iprintf("Detected Pokemon Fire Red.\n(Save Size: 128K)\n");
		saveSize = 128 * 1024;
	} else if (!memcmp(head.gamecode, "BPGE", 4)) {
		iprintf("Detected Pokemon Leaf Green.\n(Save Size: 128K)\n");
		saveSize = 128 * 1024;
	} else {
		iprintf("Don't know this cart!\n(Assuming Save Size: 64K)\n");
		saveSize = 64 * 1024;
	}
	memcpy(file + 6, head.gamecode, 4);
	
	pause();
	
	iprintf("\nGetting Flash Identification...\n");
	sramPtr[0x5555] = 0xAA;
	sramPtr[0x2AAA] = 0x55;
	sramPtr[0x5555] = 0x90;
	iprintf("Device: %02x Manufacturer: %02x\n", sramPtr[0x0001], sramPtr[0x0000]);
	sramPtr[0x5555] = 0xAA;
	sramPtr[0x2AAA] = 0x55;
	sramPtr[0x5555] = 0xF0;
	
	for (i = 0; i < 64 * 1024; i++) {
		memory[i] = sramPtr[i];
	}
	if (saveSize == 128 * 1024) {
		sramPtr[0x5555] = 0xAA;
		sramPtr[0x2AAA] = 0x55;
		sramPtr[0x5555] = 0xB0;
		sramPtr[0x0000] = 0x01;
		for (i = 0; i < 64 * 1024; i++) {
			memory[i + 64 * 1024] = sramPtr[i];
		}
		sramPtr[0x5555] = 0xAA;
		sramPtr[0x2AAA] = 0x55;
		sramPtr[0x5555] = 0xB0;
		sramPtr[0x0000] = 0x00;
	}
	
	iprintf("Initializing FAT access...\n");
	
	if (fatInitDefault()) {
		iprintf("Preparing to dump GBA RAM to '%s'...\n", file);
		
		FILE *fp = fopen(file, "wb");
		
		if (fp != NULL) {
			fwrite(memory, 1, 1, fp);
			/*if (saveSize == 128 * 1024) {
				if (fwrite(memory + 64 * 1024, 64 * 1024, 1, fp) != 64 * 1024) {
					iprintf("Error writing save bank 2.\n");
				}
			}*/
			fclose(fp);
			
			iprintf("Done writing file!\n");
		} else {
			iprintf("fopen() failure; terminating\n");
		}
	} else {
		iprintf("fatInitDefault failure: terminating\n");
	}
	
	while (1) {
		swiWaitForVBlank();
	}
	
	return 0;
}
