Various cleanups and UI improvements (hopefully...)
This commit is contained in:
parent
843095109f
commit
ce21c68e8c
@ -184,9 +184,8 @@ void Cart_Secure_Init(u32 *buf, u32 *out)
|
|||||||
const u32 C5_cmd[4] = { 0xC5000000, 0x00000000, rand1, rand2 };
|
const u32 C5_cmd[4] = { 0xC5000000, 0x00000000, rand1, rand2 };
|
||||||
CTR_SendCommand(C5_cmd, 0, 1, 0x100822C, NULL);
|
CTR_SendCommand(C5_cmd, 0, 1, 0x100822C, NULL);
|
||||||
|
|
||||||
CTR_SendCommand(A2_cmd, 4, 1, 0x100822C, &test);
|
for (int i = 0; i < 5; ++i) {
|
||||||
CTR_SendCommand(A2_cmd, 4, 1, 0x100822C, &test);
|
CTR_SendCommand(A2_cmd, 4, 1, 0x100822C, &test);
|
||||||
CTR_SendCommand(A2_cmd, 4, 1, 0x100822C, &test);
|
ioDelay(0xF0000);
|
||||||
CTR_SendCommand(A2_cmd, 4, 1, 0x100822C, &test);
|
}
|
||||||
CTR_SendCommand(A2_cmd, 4, 1, 0x100822C, &test);
|
|
||||||
}
|
}
|
||||||
|
@ -22,29 +22,24 @@ static void ClearTop(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void wait_key(void) {
|
static void wait_key(void) {
|
||||||
Debug("");
|
Debug("Press key to continue...");
|
||||||
Debug("Press key to continue");
|
|
||||||
InputWait();
|
InputWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
|
restart_program:
|
||||||
// Setup boring stuff - clear the screen, initialize SD output, etc...
|
// Setup boring stuff - clear the screen, initialize SD output, etc...
|
||||||
ClearTop();
|
ClearTop();
|
||||||
Debug("");
|
Debug("ROM dump tool v0.2");
|
||||||
Debug("Hello world from ARM9!");
|
Debug("Insert your game cart and SD card now.");
|
||||||
Debug("ROM dump tool v0.2", 1, 1, 0xFF);
|
|
||||||
wait_key();
|
wait_key();
|
||||||
|
|
||||||
char filename_buf[21];
|
|
||||||
unsigned int bytes_written = 0;
|
|
||||||
|
|
||||||
// Arbitrary target buffer
|
// Arbitrary target buffer
|
||||||
// TODO: This should be done in a nicer way ;)
|
// TODO: This should be done in a nicer way ;)
|
||||||
u8* target = (u8*)0x22000000;
|
u8* target = (u8*)0x22000000;
|
||||||
u8* header = (u8*)0x23000000;
|
u8* header = (u8*)0x23000000;
|
||||||
|
|
||||||
Debug("ROM dump tool v0.2", 1, 1, 0xFF);
|
|
||||||
memset(target, 0x00, 0x100000); // Clear our 1 MB buffer
|
memset(target, 0x00, 0x100000); // Clear our 1 MB buffer
|
||||||
// clear_screens(0x00);
|
// clear_screens(0x00);
|
||||||
|
|
||||||
@ -56,18 +51,11 @@ int main() {
|
|||||||
wait_key();
|
wait_key();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Debug("Successfully f_mounted");
|
|
||||||
Debug("cleared stuff! Initializing game card...", 1, 1, 0xFF);
|
|
||||||
|
|
||||||
// ROM DUMPING CODE STARTS HERE
|
// ROM DUMPING CODE STARTS HERE
|
||||||
|
|
||||||
Cart_Init();
|
Cart_Init();
|
||||||
|
Debug("Cart id is %08x, press A...", Cart_GetID());
|
||||||
Debug("Done! Cart id is %08x, press A...", (u32)Cart_GetID());
|
|
||||||
|
|
||||||
InputWait();
|
|
||||||
Debug("Done waiting :)...", 1, 1, 0xFF);
|
|
||||||
|
|
||||||
CTR_CmdReadHeader(header);
|
CTR_CmdReadHeader(header);
|
||||||
Debug("Done reading header: %08X :)...", *(u32*)&header[0x100]);
|
Debug("Done reading header: %08X :)...", *(u32*)&header[0x100]);
|
||||||
|
|
||||||
@ -75,7 +63,7 @@ int main() {
|
|||||||
u32 sec_keys[4];
|
u32 sec_keys[4];
|
||||||
Cart_Secure_Init((u32*)header,sec_keys);
|
Cart_Secure_Init((u32*)header,sec_keys);
|
||||||
|
|
||||||
u32 mediaUnit = 0x200;
|
u32 mediaUnit = 0x200; // TODO: Read from cart
|
||||||
u32 ramCache = 0xC000; //24MB/s - 0x1000000
|
u32 ramCache = 0xC000; //24MB/s - 0x1000000
|
||||||
|
|
||||||
u32 dumpSize = 0x100000; //1MB
|
u32 dumpSize = 0x100000; //1MB
|
||||||
@ -84,64 +72,74 @@ int main() {
|
|||||||
// Read out the header 0x0000-0x1000
|
// Read out the header 0x0000-0x1000
|
||||||
CTR_CmdReadData(0, mediaUnit, 8, target);
|
CTR_CmdReadData(0, mediaUnit, 8, target);
|
||||||
|
|
||||||
// Create output file - TODO: Put actual information in the file name (game id/name/..?), to have a standardized naming scheme
|
u32 NCSD_magic = *(u32*)(&target[0x100]);
|
||||||
snprintf(filename_buf, sizeof(filename_buf), "%s", "/dump.3ds");
|
u32 cartSize = *(u32*)(&target[0x104]);
|
||||||
|
Debug("Cart size: %llu MB", (u64)cartSize * (u64)mediaUnit / 1024ull / 1024ull);
|
||||||
|
if (NCSD_magic != 0x4453434E) {
|
||||||
|
Debug("NCSD magic not found in header!!!");
|
||||||
|
Debug("Press A to continue anyway.");
|
||||||
|
if (!(InputWait() & 1))
|
||||||
|
goto cleanup_mount;
|
||||||
|
}
|
||||||
|
|
||||||
wait_key();
|
// Create output file
|
||||||
Debug("File name: \"%s\"", filename_buf);
|
char filename_buf[32];
|
||||||
|
snprintf(filename_buf, sizeof(filename_buf), "/%.16s.3ds", &header[0x150]);
|
||||||
|
Debug("Outputting to file: \"%s\"", filename_buf);
|
||||||
|
|
||||||
unsigned flags = FA_READ | FA_WRITE | FA_CREATE_ALWAYS;
|
unsigned flags = FA_READ | FA_WRITE | FA_CREATE_ALWAYS;
|
||||||
if (f_open(&file, filename_buf, flags) != FR_OK) {
|
if (f_open(&file, filename_buf, flags) != FR_OK) {
|
||||||
Debug("Failed to create file...");
|
Debug("Failed to create file...");
|
||||||
wait_key();
|
wait_key();
|
||||||
return 0;
|
goto cleanup_mount;
|
||||||
}
|
}
|
||||||
|
|
||||||
f_lseek(&file, 0);
|
f_lseek(&file, 0);
|
||||||
f_sync(&file);
|
f_sync(&file);
|
||||||
Debug("Successfully created file");
|
|
||||||
wait_key();
|
|
||||||
|
|
||||||
// Write header to file
|
// Write header to file
|
||||||
unsigned int written = 0;
|
unsigned int written = 0;
|
||||||
f_write(&file, target, 0x4000, &written);
|
f_write(&file, target, 0x4000, &written);
|
||||||
f_sync(&file);
|
f_sync(&file);
|
||||||
Debug("Wrote header");
|
|
||||||
wait_key();
|
|
||||||
|
|
||||||
u32 cartSize = *(u32*)(&target[0x104]);
|
Debug("Ready to dump. (SELECT to skip)");
|
||||||
Debug("Cart size: %llu MB", (u64)cartSize * 0x200ull / 1024ull / 1024ull);
|
if (InputWait() & 4) // Select
|
||||||
wait_key();
|
goto skip_dumping;
|
||||||
|
|
||||||
// Dump remaining data
|
// Dump remaining data
|
||||||
for(u32 adr=0x20; adr<cartSize; adr+=ramCache) {
|
for (u32 adr = 0x20; adr < cartSize; adr += ramCache) {
|
||||||
ClearTop();
|
|
||||||
Debug("Wrote 0x%x bytes, e.g. %08x", bytes_written, *(u32*)target);
|
|
||||||
u32 dumped = cartSize - adr;
|
u32 dumped = cartSize - adr;
|
||||||
if(dumped > ramCache) dumped = ramCache;
|
if (dumped > ramCache) dumped = ramCache;
|
||||||
|
|
||||||
for(u32 adr2=0; (adr2 < dumped); adr2+=blocks) {
|
for (u32 adr2 = 0; adr2 < dumped; adr2 += blocks) {
|
||||||
u32 currentSector = (adr+adr2);
|
u32 currentSector = adr + adr2;
|
||||||
u32 percent = ((currentSector*100)/cartSize);
|
u32 percent = (currentSector * 100) / cartSize;
|
||||||
if ((adr2 % (blocks*3)) == blocks*2)
|
if ((adr2 % (blocks*3)) == blocks*2)
|
||||||
Debug("Dumping %08X / %08X - %03d%%",currentSector,cartSize,percent);
|
Debug("Dumping %08X / %08X - %03d%%",currentSector,cartSize,percent);
|
||||||
|
|
||||||
CTR_CmdReadData(currentSector, mediaUnit, blocks, (void*)(target + (adr2 * mediaUnit)));
|
CTR_CmdReadData(currentSector, mediaUnit, blocks, (void*)(target + (adr2 * mediaUnit)));
|
||||||
}
|
}
|
||||||
f_write(&file, target, dumped * mediaUnit, &bytes_written);
|
|
||||||
f_sync(&file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
unsigned int bytes_written = 0;
|
||||||
|
f_write(&file, target, dumped * mediaUnit, &bytes_written);
|
||||||
|
Debug("Wrote 0x%x bytes, e.g. %08x", bytes_written, *(u32*)target);
|
||||||
|
}
|
||||||
|
Debug("Done!");
|
||||||
|
|
||||||
|
skip_dumping:
|
||||||
// Write header - TODO: Not sure why this is done at the very end..
|
// Write header - TODO: Not sure why this is done at the very end..
|
||||||
f_lseek(&file, 0x1000);
|
f_lseek(&file, 0x1000);
|
||||||
f_write(&file, header, 0x200, &written);
|
f_write(&file, header, 0x200, &written);
|
||||||
f_sync(&file);
|
f_sync(&file);
|
||||||
Debug("Wrote 0x%X header bytes", written);
|
|
||||||
wait_key();
|
|
||||||
|
|
||||||
// Done, clean up...
|
// Done, clean up...
|
||||||
f_close(&file);
|
f_close(&file);
|
||||||
|
cleanup_mount:
|
||||||
f_mount(NULL, "0:", 0);
|
f_mount(NULL, "0:", 0);
|
||||||
|
|
||||||
|
Debug("Press B to exit, any other key to restart.");
|
||||||
|
if (!(InputWait() & 2))
|
||||||
|
goto restart_program;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user