mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-26 04:51:52 +01:00
V3.6: Code Clean-up and NES integration(untested)
Copy&pasted all the functions from "Famicom Dumper" by skaman into NES.ino and modified them to fit the enviroment. Not tested yet.
This commit is contained in:
parent
e5e4750255
commit
bbdff75a6f
@ -2,8 +2,8 @@
|
||||
Cartridge Reader for Arduino Mega2560
|
||||
|
||||
Author: sanni
|
||||
Date: 01-09-2019
|
||||
Version: 3.5
|
||||
Date: 05-09-2019
|
||||
Version: 3.6
|
||||
|
||||
SD lib: https://github.com/greiman/SdFat
|
||||
LCD lib: https://github.com/adafruit/Adafruit_SSD1306
|
||||
@ -39,46 +39,28 @@
|
||||
Gens-gs - Megadrive checksum
|
||||
|
||||
**********************************************************************************/
|
||||
|
||||
#include <SdFat.h>
|
||||
|
||||
char ver[5] = "3.5";
|
||||
|
||||
/******************************************
|
||||
Define Starting Point
|
||||
******************************************/
|
||||
// mainMenu, n64Menu, snsMenu, gbxMenu, nesMenu, mdMenu, flashMenu, pceMenu
|
||||
#define startMenu mainMenu
|
||||
|
||||
/******************************************
|
||||
Define Output
|
||||
******************************************/
|
||||
// To use the Serial Monitor change
|
||||
// enable_OLED to 0 and enable_Serial to 1
|
||||
#define enable_OLED 1
|
||||
#define enable_Serial 0
|
||||
|
||||
/******************************************
|
||||
Define Input
|
||||
******************************************/
|
||||
// If you are using the old version with only one button add // in front of the next line
|
||||
#define enable_Button2
|
||||
|
||||
/******************************************
|
||||
Define SD Speed
|
||||
******************************************/
|
||||
// Change to half speed if you get an sd error or it hangs when writing
|
||||
#define sdSpeed SPI_FULL_SPEED
|
||||
//#define sdSpeed SPI_HALF_SPEED
|
||||
char ver[5] = "3.6";
|
||||
|
||||
/******************************************
|
||||
Options
|
||||
******************************************/
|
||||
// Enable 16bit flash adapter menu
|
||||
//#define enable_flash16
|
||||
// Disable splash screen
|
||||
// Change mainMenu to snsMenu, mdMenu, n64Menu, gbxMenu, pcsMenu,
|
||||
// flashMenu, nesMenu or smsMenu for single slot Cart Readers
|
||||
#define startMenu mainMenu
|
||||
|
||||
// Comment out to change to Serial Ouput
|
||||
// be sure to change the Arduino Serial Monitor to no line ending
|
||||
#define enable_OLED
|
||||
|
||||
// Skip OLED start-up animation
|
||||
#define fast_start
|
||||
|
||||
// Enable the second button
|
||||
#define enable_Button2
|
||||
|
||||
// Enable old 16-bit flash adapter menu
|
||||
//#define enable_flash16
|
||||
|
||||
/******************************************
|
||||
Libraries
|
||||
*****************************************/
|
||||
@ -88,14 +70,21 @@ char ver[5] = "3.5";
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/wdt.h>
|
||||
|
||||
// SD Card
|
||||
#include <SdFat.h>
|
||||
#define sdSpeed SPI_FULL_SPEED
|
||||
// SD Card (Pin 50 = MISO, Pin 51 = MOSI, Pin 52 = SCK, Pin 53 = SS)
|
||||
#define chipSelectPin 53
|
||||
SdFat sd;
|
||||
SdFile myFile;
|
||||
|
||||
// AVR Eeprom
|
||||
#include <EEPROM.h>
|
||||
// forward declarations for "T" (for non Arduino IDE)
|
||||
template <class T> int EEPROM_writeAnything(int ee, const T& value);
|
||||
template <class T> int EEPROM_readAnything(int ee, T& value);
|
||||
|
||||
template <class T> int EEPROM_writeAnything(int ee, const T& value)
|
||||
{
|
||||
template <class T> int EEPROM_writeAnything(int ee, const T& value) {
|
||||
const byte* p = (const byte*)(const void*)&value;
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(value); i++)
|
||||
@ -103,8 +92,7 @@ template <class T> int EEPROM_writeAnything(int ee, const T& value)
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class T> int EEPROM_readAnything(int ee, T& value)
|
||||
{
|
||||
template <class T> int EEPROM_readAnything(int ee, T& value) {
|
||||
byte* p = (byte*)(void*)&value;
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(value); i++)
|
||||
@ -141,11 +129,6 @@ typedef enum COLOR_T {
|
||||
white_color,
|
||||
} color_t;
|
||||
|
||||
// SD Card (Pin 50 = MISO, Pin 51 = MOSI, Pin 52 = SCK, Pin 53 = SS)
|
||||
#define chipSelectPin 53
|
||||
SdFat sd;
|
||||
SdFile myFile;
|
||||
|
||||
/******************************************
|
||||
Defines
|
||||
*****************************************/
|
||||
@ -169,20 +152,20 @@ SdFile myFile;
|
||||
#define mode_SMS 16
|
||||
#define mode_SEGA_CD 17
|
||||
|
||||
/******************************************
|
||||
optimization-safe nop delay
|
||||
*****************************************/
|
||||
// optimization-safe nop delay
|
||||
#define NOP __asm__ __volatile__ ("nop\n\t")
|
||||
|
||||
// Button timing
|
||||
#define debounce 20 // ms debounce period to prevent flickering when pressing or releasing the button
|
||||
#define DCgap 250 // max ms between clicks for a double click event
|
||||
#define holdTime 2000 // ms hold period: how long to wait for press+hold event
|
||||
#define longHoldTime 5000 // ms long hold period: how long to wait for press+hold event
|
||||
|
||||
/******************************************
|
||||
Variables
|
||||
*****************************************/
|
||||
// Button timing
|
||||
static int debounce = 20; // ms debounce period to prevent flickering when pressing or releasing the button
|
||||
static int DCgap = 250; // max ms between clicks for a double click event
|
||||
static int holdTime = 2000; // ms hold period: how long to wait for press+hold event
|
||||
static int longHoldTime = 5000; // ms long hold period: how long to wait for press+hold event
|
||||
// Variables for button 1
|
||||
#ifdef enable_OLED
|
||||
// Button 1
|
||||
boolean buttonVal1 = HIGH; // value read from button
|
||||
boolean buttonLast1 = HIGH; // buffered value of the button's previous state
|
||||
boolean DCwaiting1 = false; // whether we're waiting for a double click (down)
|
||||
@ -194,7 +177,7 @@ boolean ignoreUp1 = false; // whether to ignore the button release because the c
|
||||
boolean waitForUp1 = false; // when held, whether to wait for the up event
|
||||
boolean holdEventPast1 = false; // whether or not the hold event happened already
|
||||
boolean longholdEventPast1 = false;// whether or not the long hold event happened already
|
||||
// Variables for button 2
|
||||
// Button 2
|
||||
boolean buttonVal2 = HIGH; // value read from button
|
||||
boolean buttonLast2 = HIGH; // buffered value of the button's previous state
|
||||
boolean DCwaiting2 = false; // whether we're waiting for a double click (down)
|
||||
@ -206,9 +189,10 @@ boolean ignoreUp2 = false; // whether to ignore the button release because the c
|
||||
boolean waitForUp2 = false; // when held, whether to wait for the up event
|
||||
boolean holdEventPast2 = false; // whether or not the hold event happened already
|
||||
boolean longholdEventPast2 = false;// whether or not the long hold event happened already
|
||||
|
||||
#else
|
||||
// For incoming serial data
|
||||
int incomingByte;
|
||||
#endif
|
||||
|
||||
// Variables for the menu
|
||||
int choice = 0;
|
||||
@ -260,7 +244,7 @@ byte sdBuffer[512];
|
||||
// using the watchdog timer would be more elegant but some Mega2560 bootloaders are buggy with it
|
||||
void(*resetArduino) (void) = 0;
|
||||
|
||||
/* Hoping that sanni will use this progressbar function */
|
||||
// Progressbar
|
||||
void draw_progressbar(uint32_t processedsize, uint32_t totalsize);
|
||||
|
||||
//******************************************
|
||||
@ -393,6 +377,7 @@ static const char addonsItem4[] PROGMEM = "Sega Master System";
|
||||
static const char addonsItem5[] PROGMEM = "Reset";
|
||||
static const char* const addonsOptions[] PROGMEM = {addonsItem1, addonsItem2, addonsItem3, addonsItem4, addonsItem5};
|
||||
|
||||
// Info Screen
|
||||
void aboutScreen() {
|
||||
display_Clear();
|
||||
// Draw the Logo
|
||||
@ -409,7 +394,7 @@ void aboutScreen() {
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
if (enable_OLED) {
|
||||
#ifdef enable_OLED
|
||||
// get input button
|
||||
int b = checkButton();
|
||||
|
||||
@ -433,16 +418,16 @@ void aboutScreen() {
|
||||
EEPROM_writeAnything(10, foldern);
|
||||
resetArduino();
|
||||
}
|
||||
}
|
||||
if (enable_Serial) {
|
||||
#else
|
||||
wait_serial();
|
||||
resetArduino();
|
||||
}
|
||||
#endif
|
||||
rgb.setColor(random(0, 255), random(0, 255), random(0, 255));
|
||||
delay(random(50, 100));
|
||||
}
|
||||
}
|
||||
|
||||
// All included slots
|
||||
void mainMenu() {
|
||||
// create menu with title and 6 options to choose from
|
||||
unsigned char modeMenu;
|
||||
@ -483,12 +468,13 @@ void mainMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
// Everything that needs an adapter
|
||||
void addonsMenu() {
|
||||
// create menu with title and 5 options to choose from
|
||||
unsigned char addonsMenu;
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(addonsOptions, 2);
|
||||
addonsMenu = question_box(F("Choose Adapter"), menuOptions, 2, 0);
|
||||
convertPgm(addonsOptions, 5);
|
||||
addonsMenu = question_box(F("Choose Adapter"), menuOptions, 5, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (addonsMenu)
|
||||
@ -567,7 +553,7 @@ void setup() {
|
||||
// Read current folder number out of eeprom
|
||||
EEPROM_readAnything(10, foldern);
|
||||
|
||||
if (enable_OLED) {
|
||||
#ifdef enable_OLED
|
||||
// GLCD
|
||||
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
|
||||
display.setTextSize(1);
|
||||
@ -617,9 +603,8 @@ void setup() {
|
||||
display_Update();
|
||||
delay(200);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (enable_Serial) {
|
||||
#else
|
||||
// Serial Begin
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("Cartridge Reader"));
|
||||
@ -627,11 +612,7 @@ void setup() {
|
||||
Serial.println("");
|
||||
// LED Error
|
||||
rgb.setColor(0, 0, 255);
|
||||
}
|
||||
else {
|
||||
// LED Off
|
||||
rgb.setColor(0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Init SD card
|
||||
if (!sd.begin(chipSelectPin, sdSpeed)) {
|
||||
@ -639,13 +620,13 @@ void setup() {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
|
||||
if (enable_Serial) {
|
||||
#ifndef enable_OLED
|
||||
// Print SD Info
|
||||
Serial.print(F("SD Card: "));
|
||||
Serial.print(sd.card()->cardSize() * 512E-9);
|
||||
Serial.print(F("GB FAT"));
|
||||
Serial.println(int(sd.vol()->fatType()));
|
||||
}
|
||||
#endif
|
||||
|
||||
startMenu();
|
||||
}
|
||||
@ -683,11 +664,7 @@ void print_Error(const __FlashStringHelper *errorMessage, boolean forceReset) {
|
||||
display_Update();
|
||||
|
||||
if (forceReset) {
|
||||
if (enable_Serial) {
|
||||
println_Msg(F("Fatal Error, please reset"));
|
||||
while (1);
|
||||
}
|
||||
else {
|
||||
#ifdef enable_OLED
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("Press Button..."));
|
||||
display_Update();
|
||||
@ -705,115 +682,128 @@ void print_Error(const __FlashStringHelper *errorMessage, boolean forceReset) {
|
||||
display_Update();
|
||||
delay(2000);
|
||||
}
|
||||
}
|
||||
#else
|
||||
println_Msg(F("Fatal Error, please reset"));
|
||||
while (1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void wait() {
|
||||
if (enable_OLED) {
|
||||
#ifdef enable_OLED
|
||||
wait_btn();
|
||||
}
|
||||
if (enable_Serial) {
|
||||
#else
|
||||
wait_serial();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_Msg(const __FlashStringHelper *string) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.print(string);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.print(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_Msg(const char string[]) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.print(string);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.print(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_Msg(long unsigned int message) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.print(message);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.print(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_Msg(byte message, int outputFormat) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.print(message, outputFormat);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.print(message, outputFormat);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_Msg(String string) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.print(string);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.print(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
void println_Msg(String string) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.println(string);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.println(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
void println_Msg(byte message, int outputFormat) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.println(message, outputFormat);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.println(message, outputFormat);
|
||||
#endif
|
||||
}
|
||||
|
||||
void println_Msg(const char message[]) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.println(message);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.println(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void println_Msg(const __FlashStringHelper *string) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.println(string);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.println(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
void println_Msg(long unsigned int message) {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.println(message);
|
||||
if (enable_Serial)
|
||||
#else
|
||||
Serial.println(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void display_Update() {
|
||||
if (enable_OLED)
|
||||
#ifdef enable_OLED
|
||||
display.display();
|
||||
if (enable_Serial)
|
||||
#else
|
||||
delay(100);
|
||||
#endif
|
||||
}
|
||||
|
||||
void display_Clear() {
|
||||
if (enable_OLED) {
|
||||
#ifdef enable_OLED
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned char question_box(const __FlashStringHelper* question, char answers[7][20], int num_answers, int default_choice) {
|
||||
if (enable_OLED) {
|
||||
#ifdef enable_OLED
|
||||
return questionBox_OLED(question, answers, num_answers, default_choice);
|
||||
}
|
||||
else if (enable_Serial) {
|
||||
#else
|
||||
return questionBox_Serial(question, answers, num_answers, default_choice);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************
|
||||
Serial Out
|
||||
*****************************************/
|
||||
#ifndef enable_OLED
|
||||
void wait_serial() {
|
||||
while (Serial.available() == 0) {
|
||||
}
|
||||
@ -931,6 +921,7 @@ byte questionBox_Serial(const __FlashStringHelper* question, char answers[7][20]
|
||||
//Serial.println("");
|
||||
return incomingByte;
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************
|
||||
RGB LED
|
||||
@ -964,6 +955,7 @@ void rgbLed(byte Color) {
|
||||
/******************************************
|
||||
OLED Menu Module
|
||||
*****************************************/
|
||||
#ifdef enable_OLED
|
||||
// Read button state
|
||||
int checkButton() {
|
||||
#ifdef enable_Button2
|
||||
@ -979,6 +971,7 @@ int checkButton() {
|
||||
// Read button 1
|
||||
int checkButton1() {
|
||||
int event = 0;
|
||||
|
||||
// Read the state of the button (PD7)
|
||||
buttonVal1 = (PIND & (1 << 7));
|
||||
// Button pressed down
|
||||
@ -1038,6 +1031,7 @@ int checkButton1() {
|
||||
// Read button 2
|
||||
int checkButton2() {
|
||||
int event = 0;
|
||||
|
||||
// Read the state of the button (PD7)
|
||||
buttonVal2 = (PING & (1 << 2));
|
||||
// Button pressed down
|
||||
@ -1129,7 +1123,6 @@ void wait_btn() {
|
||||
|
||||
// Display a question box with selectable answers. Make sure default choice is in (0, num_answers]
|
||||
unsigned char questionBox_OLED(const __FlashStringHelper* question, char answers[7][20], int num_answers, int default_choice) {
|
||||
|
||||
//clear the screen
|
||||
display.clearDisplay();
|
||||
display.display();
|
||||
@ -1251,6 +1244,7 @@ unsigned char questionBox_OLED(const __FlashStringHelper* question, char answers
|
||||
rgb.setColor(0, 0, 0);
|
||||
return choice;
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************
|
||||
Filebrowser Module
|
||||
|
@ -702,11 +702,11 @@ void getCartInfo_MD() {
|
||||
println_Msg(F(" "));
|
||||
|
||||
// Wait for user input
|
||||
if (enable_OLED) {
|
||||
#ifdef enable_OLED
|
||||
println_Msg(F("Press Button..."));
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void writeSSF2Map(unsigned long myAddress, word myData) {
|
||||
|
2787
Cart_Reader/NES.ino
2787
Cart_Reader/NES.ino
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
//******************************************
|
||||
// NINTENDO POWER MODULE
|
||||
// (GB Memory starts at around line 1460)
|
||||
//******************************************
|
||||
// (GB Memory starts at around line 1460)
|
||||
|
||||
/******************************************
|
||||
SF Memory Cassette
|
||||
|
@ -196,11 +196,11 @@ void getCartInfo_SMS() {
|
||||
println_Msg(F(" "));
|
||||
|
||||
// Wait for user input
|
||||
if (enable_OLED) {
|
||||
#ifdef enable_OLED
|
||||
println_Msg(F("Press Button..."));
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Read rom and save to the SD card
|
||||
|
@ -626,17 +626,15 @@ void getCartInfo_SNES() {
|
||||
display_Update();
|
||||
|
||||
// Wait for user input
|
||||
if (enable_OLED) {
|
||||
#ifdef enable_OLED
|
||||
println_Msg(F(" "));
|
||||
println_Msg(F(" "));
|
||||
println_Msg(F("Press Button..."));
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
|
||||
else if (enable_Serial) {
|
||||
#else
|
||||
println_Msg(F(" "));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Start manual config
|
||||
if (manualConfig == 1) {
|
||||
|
Loading…
Reference in New Issue
Block a user