Clean up
@ -1 +0,0 @@
|
|||||||
Here you will find the gerber files for the PCB, the stl files for 3d printing and some additional stuff for your Cart Reader shield.
|
|
@ -1,2 +0,0 @@
|
|||||||
You can use this little program to split a 4MB Nintendo Power dump into the individual roms.
|
|
||||||
Get the Java Runtimes from here in case you need them: http://www.java.com/en/download/manual.jsp
|
|
@ -1,149 +0,0 @@
|
|||||||
/**********************************************************************************
|
|
||||||
Nintendo Power Splitter
|
|
||||||
|
|
||||||
Author: sanni
|
|
||||||
Date: 2016-05-02
|
|
||||||
Version: V1
|
|
||||||
|
|
||||||
Compiled with Processing 3.0.2
|
|
||||||
**********************************************************************************/
|
|
||||||
|
|
||||||
/******************************************
|
|
||||||
Variables
|
|
||||||
*****************************************/
|
|
||||||
// Define 4MB byte array that stores the file
|
|
||||||
byte[] NP = new byte[4194303];
|
|
||||||
|
|
||||||
// Define 12 byte array to store menu string
|
|
||||||
byte menuString[] = {0x4D, 0x45, 0x4E, 0x55, 0x20, 0x50, 0x52, 0x4F, 0x47, 0x52, 0x41, 0x4D};
|
|
||||||
|
|
||||||
// Menu variables
|
|
||||||
boolean npMenu = true;
|
|
||||||
byte numGames = 0;
|
|
||||||
|
|
||||||
// rom info arrays
|
|
||||||
char[][] romName = new char[8][21];
|
|
||||||
int[] romAddress = new int[8];
|
|
||||||
int[] romSize = new int[8];
|
|
||||||
char[][] romCode = new char[8][12];
|
|
||||||
boolean[] hirom = new boolean[8];
|
|
||||||
|
|
||||||
/******************************************
|
|
||||||
Setup
|
|
||||||
*****************************************/
|
|
||||||
void setup() {
|
|
||||||
// Make 500x300 pixel window with black background
|
|
||||||
size(500, 300);
|
|
||||||
background(0);
|
|
||||||
|
|
||||||
NP[4194302] = 0x66;
|
|
||||||
|
|
||||||
// Write title
|
|
||||||
text("Nintendo Power Splitter V1", 20, 20);
|
|
||||||
|
|
||||||
// File open dialog
|
|
||||||
selectInput("Select 4MB NP dump:", "fileSelected");
|
|
||||||
noLoop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************
|
|
||||||
Helper Functions
|
|
||||||
*****************************************/
|
|
||||||
// Loads selected file into byte array
|
|
||||||
void fileSelected(File selection) {
|
|
||||||
if (selection != null)
|
|
||||||
NP = loadBytes(selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************
|
|
||||||
Main function
|
|
||||||
*****************************************/
|
|
||||||
void draw() {
|
|
||||||
// Wait until array is filled with the 4MB file
|
|
||||||
while (NP[4194302] == 0x66) {
|
|
||||||
delay(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if menu is present
|
|
||||||
for (int i = 0; i < 12; i++) {
|
|
||||||
if (menuString[i] != NP[0x7FC0+i]) {
|
|
||||||
npMenu = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (npMenu) {
|
|
||||||
// Count number of games
|
|
||||||
for (int i = 0x60000; i < 0x6E000; i += 0x2000) {
|
|
||||||
if (NP[i] == numGames )
|
|
||||||
numGames++;
|
|
||||||
}
|
|
||||||
text("Number of games: " + (numGames), 20, 60);
|
|
||||||
|
|
||||||
// Get game info
|
|
||||||
for (int i = 0; i < numGames; i++) {
|
|
||||||
|
|
||||||
// Read starting address and size
|
|
||||||
romAddress[i] = NP[0x60000 + i*0x2000 + 0x01] * 0x80000;
|
|
||||||
romSize[i] = NP[0x60000 + i*0x2000 + 0x03] * 131072;
|
|
||||||
|
|
||||||
// Read game code
|
|
||||||
for (int j = 0; j < 12; j++) {
|
|
||||||
romCode[i][j] = char(NP[0x60000 + i*0x2000 + 0x07 + j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//check if hirom
|
|
||||||
if (NP[romAddress[i]+0xFFD5] == 0x31) {
|
|
||||||
hirom[i] = true;
|
|
||||||
} else {
|
|
||||||
hirom[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read rom name
|
|
||||||
for (int j = 0; j < 21; j++) {
|
|
||||||
if (hirom[i]) {
|
|
||||||
romName[i][j] = char(NP[romAddress[i]+0xFFC0+j]);
|
|
||||||
} else {
|
|
||||||
romName[i][j] = char(NP[romAddress[i]+0x7FC0+j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Convert char array to String to be printed
|
|
||||||
String tempStr1 = new String(romName[i]);
|
|
||||||
|
|
||||||
// Convert char array to String to be printed
|
|
||||||
String tempStr2 = new String(romCode[i]);
|
|
||||||
|
|
||||||
// Clean the Strings
|
|
||||||
tempStr1 = tempStr1.trim();
|
|
||||||
tempStr1 = tempStr1.replaceAll("-$", "");
|
|
||||||
tempStr1 = tempStr1.trim();
|
|
||||||
tempStr2 = tempStr2.trim();
|
|
||||||
tempStr2 = tempStr2.replaceAll("-$", "");
|
|
||||||
tempStr2 = tempStr2.trim();
|
|
||||||
|
|
||||||
// Print all info
|
|
||||||
text("Game" + i + ": " + tempStr1 + " " + tempStr2 + " Addr: 0x" + hex(romAddress[i]) + " Size: " + romSize[i]/1024 + "KB", 20, 80+i*20);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split the rom
|
|
||||||
for (int i = 0; i < numGames; i++) {
|
|
||||||
byte[] OUT = new byte[romSize[i]];
|
|
||||||
String fileName = new String(romCode[i]);
|
|
||||||
|
|
||||||
// Clean the String
|
|
||||||
fileName = fileName.trim();
|
|
||||||
fileName = fileName.replaceAll("-$", "");
|
|
||||||
fileName = fileName.trim();
|
|
||||||
|
|
||||||
// Create the array to be written to a file
|
|
||||||
for (int j = 0; j < romSize[i]; j++) {
|
|
||||||
OUT[j] = NP[romAddress[i] + j];
|
|
||||||
}
|
|
||||||
// Write the file
|
|
||||||
saveBytes(fileName + ".bin", OUT);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
text("NP menu not found.", 20, 60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//******************************************
|
|
||||||
// End of File
|
|
||||||
//******************************************
|
|
@ -1,48 +0,0 @@
|
|||||||
This Arduino sketch can read and write Nintendo Power SF Memory cartridges without an external clock source like the Adafruit Clock Generator. It also uses the Arduino Serial Monitor instead of the OLED display and buttons.
|
|
||||||
|
|
||||||
Copy the rom and map file to the root directory of your SD card and make sure that the filenames are below 8 characters in length.
|
|
||||||
|
|
||||||
Configure the switches like so and use the USB port that is connected directly to the Arduino Mega:
|
|
||||||
|
|
||||||
![image](https://dl.dropboxusercontent.com/s/yzewnnx5mb2ajk0/flash_firmware.jpg?dl=1)
|
|
||||||
|
|
||||||
In the Arduino IDE select the correct Serial Port under Tools then open the Serial Monitor, make sure the baud is set to "9600" and in the box in front of the baudrate there should be "No line ending" selected.
|
|
||||||
|
|
||||||
First send "8" via the text box and "Send" button at the top of the Serial Monitor windows. This will switch the cart to "hirom all" mode. It should give you the following feedback somewhere in the text box. Check that it did succeed:
|
|
||||||
```
|
|
||||||
(8)HIROM ALL 0x04
|
|
||||||
Success
|
|
||||||
2A 4 2A 2A FE 61 A5 0
|
|
||||||
```
|
|
||||||
In case it failed close the Serial Monitor and switch the Arduino Mega off and on again and start from the beginning.
|
|
||||||
|
|
||||||
Next send "q" to unlock the write protection:
|
|
||||||
```
|
|
||||||
(Q)Unlock WP
|
|
||||||
Success.
|
|
||||||
2A 4 2A 2A FE 61 A5 0
|
|
||||||
```
|
|
||||||
|
|
||||||
Before you write anything you should always do a backup of your rom and mapping.
|
|
||||||
So next send "h" and then send a filename like "mapping.map" to save your carts original mapping.
|
|
||||||
```
|
|
||||||
Reading mapping into file mapping.map
|
|
||||||
Done.
|
|
||||||
```
|
|
||||||
|
|
||||||
Now save the flash by sending "d" and again choosing a filename like "flash.bin", it should now beginn to print dots to indicate progress.
|
|
||||||
```
|
|
||||||
Reading flash into file flash.bin
|
|
||||||
................................................................
|
|
||||||
```
|
|
||||||
|
|
||||||
Finally you can split the flash.bin file into the individual roms and the menu using the NP Split program:
|
|
||||||
https://github.com/sanni/cartreader/tree/master/extras/npsplit
|
|
||||||
|
|
||||||
To flash something new you need to provide a mapping.map and a flash.bin file either from your backup, from another NP cart or you can create those files with the SF Memory Binary Maker: https://github.com/moldov/SF-Memory-Binary-Maker
|
|
||||||
In the second case rename SHVC-MENU.bin you got from NP Split into menu.sfc and copy it next to the .exe. You can also use a Hex Editor to cut-out the first 512KB of your original flash dump and rename it to menu.sfc instead.
|
|
||||||
In SF Memory Binary Maker you got two options: either create a standalone map file from a single rom up to 4MB or you can add multiple roms and create a combined .bin and .map file. The sum of all the roms together can't exceed 3.5MB however since you still need 512KB for the menu. Roms need to be unheadered and have a valid checksum.
|
|
||||||
|
|
||||||
In any case you should end up with a 512B map and 4MB bin file, rename both so their filename is very short and without any special characters and copy them to the root of the SD card. Switch the NP cart into HIROM ALL, unlock WP, erase the mapping, erase the flash and then write the mapping and write the flash.
|
|
||||||
|
|
||||||
![](https://dl.dropboxusercontent.com/s/7ptv5hdf4iwi0lb/npwriter10.jpg?dl=1)
|
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |