diff options
author | sanni <[email protected]> | 2023-07-19 15:13:06 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2023-07-19 15:13:06 +0200 |
commit | 829408c6551e471bd61accc548ab7a427dab06aa (patch) | |
tree | 67b4f8da66c7888ae4303bb822d1677fed10293e | |
parent | b4d6b4e637d3a1e2e75fe50b3e071bc3208fbb40 (diff) | |
download | cartreader-829408c6551e471bd61accc548ab7a427dab06aa.tar.gz cartreader-829408c6551e471bd61accc548ab7a427dab06aa.zip |
Unify HW3 and HW5 menues
-rw-r--r-- | Cart_Reader/Cart_Reader.ino | 740 | ||||
-rw-r--r-- | Cart_Reader/OSCR.cpp | 530 |
2 files changed, 621 insertions, 649 deletions
diff --git a/Cart_Reader/Cart_Reader.ino b/Cart_Reader/Cart_Reader.ino index de38d09..e06e4ff 100644 --- a/Cart_Reader/Cart_Reader.ino +++ b/Cart_Reader/Cart_Reader.ino @@ -4,8 +4,8 @@ This project represents a community-driven effort to provide
an easy to build and easy to modify cartridge dumper.
- Date: 2023-07-13
- Version: 12.7
+ Date: 2023-07-19
+ Version: 12.8
SD lib: https://github.com/greiman/SdFat
LCD lib: https://github.com/olikraus/u8g2
@@ -817,37 +817,362 @@ void print_MissingModule(void) { }
/******************************************
- Main menu optimized for rotary encoder
+ Main menu
*****************************************/
-#if defined(enable_LCD)
-// Main menu
+#ifdef enable_GBX
static const char modeItem1[] PROGMEM = "Game Boy";
+#endif
+#ifdef enable_NES
static const char modeItem2[] PROGMEM = "NES/Famicom";
+#endif
+#ifdef enable_SNES
static const char modeItem3[] PROGMEM = "Super Nintendo/SFC";
+#endif
+#ifdef enable_N64
static const char modeItem4[] PROGMEM = "Nintendo 64 (3V)";
+#endif
+#ifdef enable_MD
static const char modeItem5[] PROGMEM = "Mega Drive/Genesis";
+#endif
+#ifdef enable_SMS
static const char modeItem6[] PROGMEM = "SMS/GG/MIII/SG-1000";
+#endif
+#ifdef enable_PCE
static const char modeItem7[] PROGMEM = "PC Engine/TG16";
+#endif
+#ifdef enable_WS
static const char modeItem8[] PROGMEM = "WonderSwan (3V)";
+#endif
+#ifdef enable_NGP
static const char modeItem9[] PROGMEM = "NeoGeo Pocket (3V)";
+#endif
+#ifdef enable_INTV
static const char modeItem10[] PROGMEM = "Intellivision";
+#endif
+#ifdef enable_COLV
static const char modeItem11[] PROGMEM = "Colecovision";
+#endif
+#ifdef enable_VBOY
static const char modeItem12[] PROGMEM = "Virtual Boy";
+#endif
+#ifdef enable_WSV
static const char modeItem13[] PROGMEM = "Watara Supervision (3V)";
+#endif
+#ifdef enable_PCW
static const char modeItem14[] PROGMEM = "Pocket Challenge W";
+#endif
+#ifdef enable_ATARI
static const char modeItem15[] PROGMEM = "Atari 2600";
+#endif
+#ifdef enable_ODY2
static const char modeItem16[] PROGMEM = "Magnavox Odyssey 2";
+#endif
+#ifdef enable_ARC
static const char modeItem17[] PROGMEM = "Arcadia 2001";
+#endif
+#ifdef enable_FAIRCHILD
static const char modeItem18[] PROGMEM = "Fairchild Channel F";
+#endif
+#ifdef enable_SUPRACAN
static const char modeItem19[] PROGMEM = "Super A'can";
+#endif
+#ifdef enable_MSX
static const char modeItem20[] PROGMEM = "MSX";
+#endif
+#ifdef enable_POKE
static const char modeItem21[] PROGMEM = "Pokemon Mini (3V)";
+#endif
+#ifdef enable_LOOPY
static const char modeItem22[] PROGMEM = "Casio Loopy";
+#endif
+#ifdef enable_FLASH
static const char modeItem23[] PROGMEM = "Flashrom Programmer";
+#endif
static const char modeItem24[] PROGMEM = "Self Test (3V)";
static const char modeItem25[] PROGMEM = "About";
-//static const char modeItem26[] PROGMEM = "Reset"; (stored in common strings array)
-static const char* const modeOptions[] PROGMEM = { modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6, modeItem7, modeItem8, modeItem9, modeItem10, modeItem11, modeItem12, modeItem13, modeItem14, modeItem15, modeItem16, modeItem17, modeItem18, modeItem19, modeItem20, modeItem21, modeItem22, modeItem23, modeItem24, modeItem25, string_reset2 };
+//static const char modeItem25[] PROGMEM = "Reset"; (stored in common strings array)
+static const char* const modeOptions[] PROGMEM = {
+#ifdef enable_GBX
+ modeItem1,
+#endif
+#ifdef enable_NES
+ modeItem2,
+#endif
+#ifdef enable_SNES
+ modeItem3,
+#endif
+#ifdef enable_N64
+ modeItem4,
+#endif
+#ifdef enable_MD
+ modeItem5,
+#endif
+#ifdef enable_SMS
+ modeItem6,
+#endif
+#ifdef enable_PCE
+ modeItem7,
+#endif
+#ifdef enable_WS
+ modeItem8,
+#endif
+#ifdef enable_NGP
+ modeItem9,
+#endif
+#ifdef enable_INTV
+ modeItem10,
+#endif
+#ifdef enable_COLV
+ modeItem11,
+#endif
+#ifdef enable_VBOY
+ modeItem12,
+#endif
+#ifdef enable_WSV
+ modeItem13,
+#endif
+#ifdef enable_PCW
+ modeItem14,
+#endif
+#ifdef enable_ATARI
+ modeItem15,
+#endif
+#ifdef enable_ODY2
+ modeItem16,
+#endif
+#ifdef enable_ARC
+ modeItem17,
+#endif
+#ifdef enable_FAIRCHILD
+ modeItem18,
+#endif
+#ifdef enable_SUPRACAN
+ modeItem19,
+#endif
+#ifdef enable_MSX
+ modeItem20,
+#endif
+#ifdef enable_POKE
+ modeItem21,
+#endif
+#ifdef enable_LOOPY
+ modeItem22,
+#endif
+#ifdef enable_FLASH
+ modeItem23,
+#endif
+ modeItem24, modeItem25, string_reset2
+};
+
+// Count menu entries
+byte countMenuEntries() {
+ byte count = 3;
+#ifdef enable_GBX
+ count++;
+#endif
+#ifdef enable_NES
+ count++;
+#endif
+#ifdef enable_SNES
+ count++;
+#endif
+#ifdef enable_N64
+ count++;
+#endif
+#ifdef enable_MD
+ count++;
+#endif
+#ifdef enable_SMS
+ count++;
+#endif
+#ifdef enable_PCE
+ count++;
+#endif
+#ifdef enable_WS
+ count++;
+#endif
+#ifdef enable_NGP
+ count++;
+#endif
+#ifdef enable_INTV
+ count++;
+#endif
+#ifdef enable_COLV
+ count++;
+#endif
+#ifdef enable_VBOY
+ count++;
+#endif
+#ifdef enable_WSV
+ count++;
+#endif
+#ifdef enable_PCW
+ count++;
+#endif
+#ifdef enable_ATARI
+ count++;
+#endif
+#ifdef enable_ODY2
+ count++;
+#endif
+#ifdef enable_ARC
+ count++;
+#endif
+#ifdef enable_FAIRCHILD
+ count++;
+#endif
+#ifdef enable_SUPRACAN
+ count++;
+#endif
+#ifdef enable_MSX
+ count++;
+#endif
+#ifdef enable_POKE
+ count++;
+#endif
+#ifdef enable_LOOPY
+ count++;
+#endif
+#ifdef enable_FLASH
+ count++;
+#endif
+ return count;
+}
+
+// Account for disabled menue entries
+unsigned char fixMenuOrder(unsigned char modeMenu) {
+ byte translationMatrix[26];
+ byte currentEntry = 0;
+
+#if defined(enable_GBX)
+ translationMatrix[currentEntry] = 0;
+ currentEntry++;
+#endif
+
+#if defined(enable_NES)
+ translationMatrix[currentEntry] = 1;
+ currentEntry++;
+#endif
+
+#if defined(enable_SNES)
+ translationMatrix[currentEntry] = 2;
+ currentEntry++;
+#endif
+
+#if defined(enable_N64)
+ translationMatrix[currentEntry] = 3;
+ currentEntry++;
+#endif
+
+#if defined(enable_MD)
+ translationMatrix[currentEntry] = 4;
+ currentEntry++;
+#endif
+
+#if defined(enable_SMS)
+ translationMatrix[currentEntry] = 5;
+ currentEntry++;
+#endif
+
+#if defined(enable_PCE)
+ translationMatrix[currentEntry] = 6;
+ currentEntry++;
+#endif
+
+#if defined(enable_WS)
+ translationMatrix[currentEntry] = 7;
+ currentEntry++;
+#endif
+
+#if defined(enable_NGP)
+ translationMatrix[currentEntry] = 8;
+ currentEntry++;
+#endif
+
+#if defined(enable_INTV)
+ translationMatrix[currentEntry] = 9;
+ currentEntry++;
+#endif
+
+#if defined(enable_COLV)
+ translationMatrix[currentEntry] = 10;
+ currentEntry++;
+#endif
+
+#if defined(enable_VBOY)
+ translationMatrix[currentEntry] = 11;
+ currentEntry++;
+#endif
+
+#if defined(enable_WSV)
+ translationMatrix[currentEntry] = 12;
+ currentEntry++;
+#endif
+
+#if defined(enable_PCW)
+ translationMatrix[currentEntry] = 13;
+ currentEntry++;
+#endif
+
+#if defined(enable_ATARI)
+ translationMatrix[currentEntry] = 14;
+ currentEntry++;
+#endif
+
+#if defined(enable_ODY2)
+ translationMatrix[currentEntry] = 15;
+ currentEntry++;
+#endif
+
+#if defined(enable_ARC)
+ translationMatrix[currentEntry] = 16;
+ currentEntry++;
+#endif
+
+#if defined(enable_FAIRCHILD)
+ translationMatrix[currentEntry] = 17;
+ currentEntry++;
+#endif
+
+#if defined(enable_SUPRACAN)
+ translationMatrix[currentEntry] = 18;
+ currentEntry++;
+#endif
+
+#if defined(enable_MSX)
+ translationMatrix[currentEntry] = 19;
+ currentEntry++;
+#endif
+
+#if defined(enable_POKE)
+ translationMatrix[currentEntry] = 20;
+ currentEntry++;
+#endif
+
+#if defined(enable_LOOPY)
+ translationMatrix[currentEntry] = 21;
+ currentEntry++;
+#endif
+
+#if defined(enable_FLASH)
+ translationMatrix[currentEntry] = 22;
+ currentEntry++;
+#endif
+
+ // Self Test
+ translationMatrix[currentEntry] = 23;
+ currentEntry++;
+
+ // About
+ translationMatrix[currentEntry] = 24;
+ currentEntry++;
+
+ // Reset
+ translationMatrix[currentEntry] = 25;
+ currentEntry++;
+
+ return translationMatrix[modeMenu];
+}
// All included slots
void mainMenu() {
@@ -856,24 +1181,39 @@ void mainMenu() { byte num_answers;
byte option_offset;
+ // Count menu entries
+ byte menuCount = countMenuEntries();
+
// Main menu spans across three pages
currPage = 1;
lastPage = 1;
- numPages = 4;
+ if ((menuCount % 7) == 0)
+ numPages = menuCount / 7;
+ else
+ numPages = (byte)(menuCount / 7) + 1;
while (1) {
if (currPage == 1) {
option_offset = 0;
- num_answers = 7;
+ if (menuCount < 7)
+ num_answers = menuCount;
+ else
+ num_answers = 7;
} else if (currPage == 2) {
option_offset = 7;
- num_answers = 7;
+ if (menuCount < 14)
+ num_answers = menuCount - 7;
+ else
+ num_answers = 7;
} else if (currPage == 3) {
option_offset = 14;
- num_answers = 7;
+ if (menuCount < 21)
+ num_answers = menuCount - 14;
+ else
+ num_answers = 7;
} else { // currPage == 4
option_offset = 21;
- num_answers = 4;
+ num_answers = menuCount - 21;
}
// Copy menuOptions out of progmem
convertPgm(modeOptions + option_offset, num_answers);
@@ -888,8 +1228,11 @@ void mainMenu() { // Reset page number
currPage = 1;
+ modeMenu = fixMenuOrder(modeMenu);
+
// wait for user choice to come back from the question box menu
switch (modeMenu) {
+
#ifdef enable_GBX
case 0:
gbxMenu();
@@ -1074,377 +1417,6 @@ void mainMenu() { }
}
-/******************************************
- Main menu optimized for buttons
-*****************************************/
-#else
-// Main menu
-static const char modeItem1[] PROGMEM = "Add-ons";
-#if defined(clockgen_installed)
-static const char modeItem2[] PROGMEM = "SNES/SFC (CLK0+1)";
-#else
-static const char modeItem2[] PROGMEM = "Super Nintendo/SFC";
-#endif
-static const char modeItem3[] PROGMEM = "Mega Drive/Genesis";
-static const char modeItem4[] PROGMEM = "N64 (3V EEP CLK1)";
-static const char modeItem5[] PROGMEM = "Game Boy";
-static const char modeItem6[] PROGMEM = "About";
-// static const char modeItem7[] PROGMEM = "Reset"; (stored in common strings array)
-static const char* const modeOptions[] PROGMEM = { modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6, string_reset2 };
-
-// Add-ons submenu
-static const char addonsItem1[] PROGMEM = "70s Consoles";
-static const char addonsItem2[] PROGMEM = "80s Consoles";
-static const char addonsItem3[] PROGMEM = "90s Consoles";
-static const char addonsItem4[] PROGMEM = "Handhelds";
-static const char addonsItem5[] PROGMEM = "Flashrom Programmer";
-static const char addonsItem6[] PROGMEM = "Self Test (EEP)";
-//static const char addonsItem7[] PROGMEM = "Reset"; (stored in common strings array)
-static const char* const addonsOptions[] PROGMEM = { addonsItem1, addonsItem2, addonsItem3, addonsItem4, addonsItem5, addonsItem6, string_reset2 };
-
-// 70s Consoles submenu
-static const char consoles70Item1[] PROGMEM = "Atari 2600";
-static const char consoles70Item2[] PROGMEM = "Magnavox Odyssey 2";
-static const char consoles70Item3[] PROGMEM = "Arcadia 2001";
-static const char consoles70Item4[] PROGMEM = "Fairchild Channel F";
-static const char consoles70Item5[] PROGMEM = "Intellivision";
-static const char consoles70Item6[] PROGMEM = "Colecovision";
-//static const char consoles70Item7[] PROGMEM = "Reset"; (stored in common strings array)
-static const char* const consoles70Options[] PROGMEM = { consoles70Item1, consoles70Item2, consoles70Item3, consoles70Item4, consoles70Item5, consoles70Item6, string_reset2 };
-
-// 80s Consoles submenu
-static const char consoles80Item1[] PROGMEM = "NES/Famicom";
-static const char consoles80Item2[] PROGMEM = "PC Engine/TG16";
-static const char consoles80Item3[] PROGMEM = "SMS/GG/MIII/SG-1000";
-static const char consoles80Item4[] PROGMEM = "MSX";
-//static const char consoles80Item5[] PROGMEM = "Reset"; (stored in common strings array)
-static const char* const consoles80Options[] PROGMEM = { consoles80Item1, consoles80Item2, consoles80Item3, consoles80Item4, string_reset2 };
-
-// 90s Consoles submenu
-static const char consoles90Item1[] PROGMEM = "Super A'can";
-static const char consoles90Item2[] PROGMEM = "Casio Loopy";
-static const char* const consoles90Options[] PROGMEM = { consoles90Item1, consoles90Item2, string_reset2 };
-
-// Handhelds submenu
-static const char handheldsItem1[] PROGMEM = "Virtual Boy";
-static const char handheldsItem2[] PROGMEM = "WonderSwan (3V)";
-static const char handheldsItem3[] PROGMEM = "NeoGeo Pocket (3V)";
-static const char handheldsItem4[] PROGMEM = "Watara Supervision (3V)";
-static const char handheldsItem5[] PROGMEM = "Pocket Challenge W";
-static const char handheldsItem6[] PROGMEM = "Pokemon Mini (3V)";
-//static const char handheldsItem6[] PROGMEM = "Reset"; (stored in common strings array)
-static const char* const handheldsOptions[] PROGMEM = { handheldsItem1, handheldsItem2, handheldsItem3, handheldsItem4, handheldsItem5, handheldsItem6, string_reset2 };
-
-// All included slots
-void mainMenu() {
- // create menu with title and 6 options to choose from
- unsigned char modeMenu;
- // Copy menuOptions out of progmem
- convertPgm(modeOptions, 7);
- modeMenu = question_box(F("OPENSOURCE CARTREADER"), menuOptions, 7, 0);
-
- // wait for user choice to come back from the question box menu
- switch (modeMenu) {
- case 0:
- addonMenu();
- break;
-
-#ifdef enable_SNES
- case 1:
- snsMenu();
- break;
-#endif
-
-#ifdef enable_MD
- case 2:
- mdMenu();
- break;
-#endif
-
-#ifdef enable_N64
- case 3:
- n64Menu();
- break;
-#endif
-
-#ifdef enable_GBX
- case 4:
- gbxMenu();
- break;
-#endif
-
- case 5:
- aboutScreen();
- break;
-
- case 6:
- resetArduino();
- break;
-
- default:
- print_MissingModule(); // does not return
- }
-}
-
-// Everything that needs an adapter
-void addonMenu() {
- // create menu with title and 5 options to choose from
- unsigned char addonsMenu;
- // Copy menuOptions out of progmem
- convertPgm(addonsOptions, 7);
- addonsMenu = question_box(F("Type"), menuOptions, 7, 0);
-
- // wait for user choice to come back from the question box menu
- switch (addonsMenu) {
- // 70s Consoles
- case 0:
- consoles70Menu();
- break;
-
- // 80s Consoles
- case 1:
- consoles80Menu();
- break;
-
- case 2:
- consoles90Menu();
- break;
-
- // Handhelds
- case 3:
- handheldMenu();
- break;
-
-#ifdef enable_FLASH
- case 4:
-#ifdef ENABLE_VSELECT
- setup_FlashVoltage();
-#endif
- flashMenu();
- break;
-#endif
-
-#ifdef enable_selftest
- case 5:
- selfTest();
- break;
-#endif
-
- case 6:
- resetArduino();
- break;
-
- default:
- print_MissingModule(); // does not return
- }
-}
-
-// Everything that needs an adapter
-void consoles70Menu() {
- // create menu with title and 7 options to choose from
- unsigned char consoles70Menu;
- // Copy menuOptions out of progmem
- convertPgm(consoles70Options, 7);
- consoles70Menu = question_box(F("Choose Adapter"), menuOptions, 7, 0);
- // wait for user choice to come back from the question box menu
- switch (consoles70Menu) {
-#ifdef enable_ATARI
- case 0:
- setup_ATARI();
- atariMenu();
- break;
-#endif
-
-#ifdef enable_ODY2
- case 1:
- setup_ODY2();
- ody2Menu();
- break;
-#endif
-
-#ifdef enable_ARC
- case 2:
- setup_ARC();
- arcMenu();
- break;
-#endif
-
-#ifdef enable_FAIRCHILD
- case 3:
- setup_FAIRCHILD();
- fairchildMenu();
- break;
-#endif
-
-#ifdef enable_INTV
- case 4:
- setup_INTV();
- intvMenu();
- break;
-#endif
-
-#ifdef enable_COLV
- case 5:
- setup_COL();
- colMenu();
- break;
-#endif
-
- case 6:
- resetArduino();
- break;
-
- default:
- print_MissingModule(); // does not return
- }
-}
-
-// Everything that needs an adapter
-void consoles80Menu() {
- // create menu with title and 6 options to choose from
- unsigned char consoles80Menu;
- // Copy menuOptions out of progmem
- convertPgm(consoles80Options, 5);
- consoles80Menu = question_box(F("Choose Adapter"), menuOptions, 5, 0);
-
- // wait for user choice to come back from the question box menu
- switch (consoles80Menu) {
-#ifdef enable_NES
- case 0:
- mode = mode_NES;
- display_Clear();
- display_Update();
- setup_NES();
- getMapping();
- checkStatus_NES();
- nesMenu();
- break;
-#endif
-
-#ifdef enable_PCE
- case 1:
- pcsMenu();
- break;
-#endif
-
-#ifdef enable_SMS
- case 2:
- smsMenu();
- break;
-#endif
-
-#ifdef enable_MSX
- case 3:
- setup_MSX();
- msxMenu();
- break;
-#endif
-
- case 4:
- resetArduino();
- break;
-
- default:
- print_MissingModule(); // does not return
- }
-}
-
-// Everything that needs an adapter
-void consoles90Menu() {
- unsigned char consoles90Menu;
- // Copy menuOptions out of progmem
- convertPgm(consoles90Options, 2);
- consoles90Menu = question_box(F("Choose Adapter"), menuOptions, 2, 0);
-
- // wait for user choice to come back from the question box menu
- switch (consoles90Menu) {
-#ifdef enable_SUPRACAN
- case 0:
- setup_SuprAcan();
- break;
-#endif
-
-#ifdef enable_LOOPY
- case 1:
- loopyMenu();
- break;
-#endif
-
- case 2:
- resetArduino();
- break;
-
- default:
- print_MissingModule(); // does not return
- break;
- }
-}
-
-// Everything that needs an adapter
-void handheldMenu() {
- // create menu with title and 6 options to choose from
- unsigned char handheldsMenu;
- // Copy menuOptions out of progmem
- convertPgm(handheldsOptions, 7);
- handheldsMenu = question_box(F("Choose Adapter"), menuOptions, 7, 0);
-
- // wait for user choice to come back from the question box menu
- switch (handheldsMenu) {
-#ifdef enable_VBOY
- case 0:
- setup_VBOY();
- vboyMenu();
- break;
-#endif
-
-#ifdef enable_WS
- case 1:
- display_Clear();
- display_Update();
- setup_WS();
- mode = mode_WS;
- break;
-#endif
-
-#ifdef enable_NGP
- case 2:
- display_Clear();
- display_Update();
- setup_NGP();
- mode = mode_NGP;
- break;
-#endif
-
-#ifdef enable_WSV
- case 3:
- setup_WSV();
- wsvMenu();
- break;
-#endif
-
-#ifdef enable_PCW
- case 4:
- setup_PCW();
- pcwMenu();
- break;
-#endif
-
-#ifdef enable_POKE
- case 5:
- setup_POKE();
- pokeMenu();
- break;
-#endif
-
- case 6:
- resetArduino();
- break;
-
- default:
- print_MissingModule(); // does not return
- }
-}
-#endif
/******************************************
Self Test
@@ -2947,7 +2919,7 @@ void checkUpdater() { #else
ClockedSerial.println(F("RTC not installed"));
#endif
- } else if (cmd.substring(0,7) == "SETTIME") {
+ } else if (cmd.substring(0, 7) == "SETTIME") {
#if defined(RTC_installed)
ClockedSerial.println(F("Setting Time..."));
rtc.adjust(DateTime(cmd.substring(8).toInt()));
diff --git a/Cart_Reader/OSCR.cpp b/Cart_Reader/OSCR.cpp index 4f34e93..707dd66 100644 --- a/Cart_Reader/OSCR.cpp +++ b/Cart_Reader/OSCR.cpp @@ -1,265 +1,265 @@ -/******************************************************************** -* Open Source Cartridge Reader */ -/*H****************************************************************** -* FILENAME : OSCR.cpp -* -* DESCRIPTION : -* Contains various enums, variables, etc, for the main program. -* -* PUBLIC FUNCTIONS : -* void setClockScale( VOLTS ) -* -* NOTES : -* This file is a WIP, I've been moving things into it on my local working -* copy, but they are not ready yet. Rather than put this in the main file -* only to move them back again, I decided to commit it early. If you need -* to add new globals, enums, defines, etc, please use this file! -* -* LICENSE : -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see <https://www.gnu.org/licenses/>. -* -* CHANGES : -* -* REF NO VERSION DATE WHO DETAIL -* 12.5 2023-03-29 Ancyker Initial version -* -*H*/ - -#include "OSCR.h" - -/*==== VARIABLES ==================================================*/ - -// Firmware Version -char ver[5] = "12.7"; - -// Clock speed -unsigned long clock = CS_16MHZ; - -// Voltage -VOLTS voltage = VOLTS_SET_5V; - -/*==== /VARIABLES =================================================*/ - -/*F****************************************************************** -* NAME : void printVersionToSerial() -* -* DESCRIPTION : Prints the version & feature string to serial -* -*F*/ -#if !defined(enable_serial) && defined(ENABLE_UPDATER) -void printVersionToSerial() { - ClockedSerial.print(F("OSCR")); - ClockedSerial.print(F("::")); - ClockedSerial.print(ver); - ClockedSerial.print(F("//")); - #if defined(HW1) - ClockedSerial.print(F("HW1")); - #elif defined(HW2) - ClockedSerial.print(F("HW2")); - #elif defined(HW3) - ClockedSerial.print(F("HW3")); - #elif defined(HW4) - ClockedSerial.print(F("HW4")); - #elif defined(HW5) - ClockedSerial.print(F("HW5")); - #elif defined(SERIAL_MONITOR) - ClockedSerial.print(F("Serial")); - #else - ClockedSerial.print(F("HW?")); - #endif - #if defined (ENABLE_VSELECT) - ClockedSerial.print(F("|VSELECT")); - #endif - #if defined (RTC_installed) - ClockedSerial.print(F("|RTC")); - #endif - #if defined (clockgen_installed) - ClockedSerial.print(F("|CLOCKGEN")); - #endif - #if defined (fastcrc) - ClockedSerial.print(F("|FASTCRC")); - #endif - #if defined (ENABLE_3V3FIX) - ClockedSerial.print(F("|3V3FIX")); - #endif - - ClockedSerial.println(F("")); -} -#else -void printVersionToSerial() {} -#endif - -/*F****************************************************************** -* NAME : void setClockScale( ClockScale ) -* -* DESCRIPTION : Set ATMEGA2560 clock prescaler -* -* INPUTS : -* PARAMETERS: -* VOLTS ClockScale Clock scale -* -* PROCESS : -* [1] Enable clock prescaler change -* [2] Apply clock prescaler -* -* NOTES : -* Changing the clock prescaler to a value other than F_CPU (1 by default) -* can/will result in some clock-based functions not working, including -* timers and most communication protocols. -* -* FURTHER READING : -* ATmega640/V-1280/V-1281/V-2560/V-2561/V § 10.13.2 [PDF: https://rmy.pw/atmega2560] -* -*F*/ -void setClockScale(VOLTS __x) -{ - uint8_t __tmp = _BV(CLKPCE); /*[1]*/ - __asm__ __volatile__ ( - "in __tmp_reg__,__SREG__" "\n\t" - "cli" "\n\t" - "sts %1, %0" "\n\t" - "sts %1, %2" "\n\t" - "out __SREG__, __tmp_reg__" - : /* no outputs */ - : "d" (__tmp), - "M" (_SFR_MEM_ADDR(CLKPR)), - "d" (__x) - : "r0" - ); /*[2]*/ -} - -/*F****************************************************************** -* NAME : VOLTS setVoltage( Voltage ) -* -* DESCRIPTION : Adjust voltage (and clock prescaler, if enabled) -* -* INPUTS : -* PARAMETERS: -* VOLTS Voltage Voltage -* -* OUTPUTS : -* RETURN : -* Type: VOLTS Result: -* Values: VOLTS_SUCCESS Successfully set the voltage/clock -* VOLTS_ERROR Something went wrong -* VOLTS_NOTENABLED VSELECT and 3V3FIX are both disabled -* -* PROCESS : -* [1] Apply voltage -* [2] Apply clock prescaler -* -* NOTES : -* When changing to 5V the voltage is set first so that the MPU -* will be stable at 16MHz. When going down to 3.3V the clock -* is changed to 8MHz first so that the MPU will be stable when -* the voltage is changed to 3.3V. -* -* This works best with VSELECT as the firmware controls the -* timing of all of this. If you are doing this manually, then -* you'll need to start the OSCR with 5V set and only switch to -* 3.3V once on the main menu. -* -*F*/ -#if defined(ENABLE_VSELECT) || defined(ENABLE_3V3FIX) -VOLTS setVoltage(VOLTS newVoltage) { - switch(newVoltage) { - /* 5V */ - case VOLTS_SET_5V: - if ( - #if defined(ENABLE_3V3FIX) - clock == CS_16MHZ - #endif - #if defined(ENABLE_VSELECT) && defined(ENABLE_3V3FIX) - && - #endif - #if defined(ENABLE_VSELECT) - VOLTS_SET_5V == voltage - #endif - ) return VOLTS_SUCCESS; // Just return if already as requested - - // Adjust voltage high if VSELECT is available - #if defined(ENABLE_VSELECT) - PORTD &= ~(1 << 7); /*[1]*/ - voltage = VOLTS_SET_5V; - #endif - - // Adjust clock speed when 3V3FIX is enabled - #if defined(ENABLE_3V3FIX) - // Stop serial if running - #if !defined(enable_serial) && defined(ENABLE_UPDATER) - ClockedSerial.end(); - #endif - // Set clock speed - clock = CS_16MHZ; - setClockScale(newVoltage); /*[2]*/ - // Restart serial - #if !defined(enable_serial) && defined(ENABLE_UPDATER) - ClockedSerial.begin(UPD_BAUD); - #endif - #else - clock = CS_16MHZ; - #endif - - // Done - return VOLTS_SUCCESS; - - /* 3.3V */ - case VOLTS_SET_3V3: - if ( - #if defined(ENABLE_3V3FIX) - clock == CS_8MHZ - #endif - #if defined(ENABLE_VSELECT) && defined(ENABLE_3V3FIX) - && - #endif - #if defined(ENABLE_VSELECT) - VOLTS_SET_3V3 == voltage - #endif - ) return VOLTS_SUCCESS; // Just return if already as requested - - // Adjust clock speed when 3V3FIX is enabled - #if defined(ENABLE_3V3FIX) - #if !defined(enable_serial) && defined(ENABLE_UPDATER) - ClockedSerial.end(); - #endif - // Set clock speed - clock = CS_8MHZ; - setClockScale(newVoltage); /*[2]*/ - #if !defined(enable_serial) && defined(ENABLE_UPDATER) - ClockedSerial.begin(UPD_BAUD); - #endif - #endif - - // Adjust voltage high if VSELECT is available - #if defined(ENABLE_VSELECT) - PORTD |= (1 << 7); /*[1]*/ - voltage = VOLTS_SET_3V3; - #endif - - // Done - return VOLTS_SUCCESS; - - /* ??? */ - default: - return VOLTS_ERROR; - } -} -#else -// The compiler will optimize this out when this condition is met. -// Yes, even though it has a return value it will only be compiled -// if something reads that value. Currently nothing does. -VOLTS setVoltage(VOLTS newVoltage __attribute__((unused))) { - return VOLTS_NOTENABLED; -} -#endif +/********************************************************************
+* Open Source Cartridge Reader */
+/*H******************************************************************
+* FILENAME : OSCR.cpp
+*
+* DESCRIPTION :
+* Contains various enums, variables, etc, for the main program.
+*
+* PUBLIC FUNCTIONS :
+* void setClockScale( VOLTS )
+*
+* NOTES :
+* This file is a WIP, I've been moving things into it on my local working
+* copy, but they are not ready yet. Rather than put this in the main file
+* only to move them back again, I decided to commit it early. If you need
+* to add new globals, enums, defines, etc, please use this file!
+*
+* LICENSE :
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <https://www.gnu.org/licenses/>.
+*
+* CHANGES :
+*
+* REF NO VERSION DATE WHO DETAIL
+* 12.5 2023-03-29 Ancyker Initial version
+*
+*H*/
+
+#include "OSCR.h"
+
+/*==== VARIABLES ==================================================*/
+
+// Firmware Version
+char ver[5] = "12.8";
+
+// Clock speed
+unsigned long clock = CS_16MHZ;
+
+// Voltage
+VOLTS voltage = VOLTS_SET_5V;
+
+/*==== /VARIABLES =================================================*/
+
+/*F******************************************************************
+* NAME : void printVersionToSerial()
+*
+* DESCRIPTION : Prints the version & feature string to serial
+*
+*F*/
+#if !defined(enable_serial) && defined(ENABLE_UPDATER)
+void printVersionToSerial() {
+ ClockedSerial.print(F("OSCR"));
+ ClockedSerial.print(F("::"));
+ ClockedSerial.print(ver);
+ ClockedSerial.print(F("//"));
+ #if defined(HW1)
+ ClockedSerial.print(F("HW1"));
+ #elif defined(HW2)
+ ClockedSerial.print(F("HW2"));
+ #elif defined(HW3)
+ ClockedSerial.print(F("HW3"));
+ #elif defined(HW4)
+ ClockedSerial.print(F("HW4"));
+ #elif defined(HW5)
+ ClockedSerial.print(F("HW5"));
+ #elif defined(SERIAL_MONITOR)
+ ClockedSerial.print(F("Serial"));
+ #else
+ ClockedSerial.print(F("HW?"));
+ #endif
+ #if defined (ENABLE_VSELECT)
+ ClockedSerial.print(F("|VSELECT"));
+ #endif
+ #if defined (RTC_installed)
+ ClockedSerial.print(F("|RTC"));
+ #endif
+ #if defined (clockgen_installed)
+ ClockedSerial.print(F("|CLOCKGEN"));
+ #endif
+ #if defined (fastcrc)
+ ClockedSerial.print(F("|FASTCRC"));
+ #endif
+ #if defined (ENABLE_3V3FIX)
+ ClockedSerial.print(F("|3V3FIX"));
+ #endif
+
+ ClockedSerial.println(F(""));
+}
+#else
+void printVersionToSerial() {}
+#endif
+
+/*F******************************************************************
+* NAME : void setClockScale( ClockScale )
+*
+* DESCRIPTION : Set ATMEGA2560 clock prescaler
+*
+* INPUTS :
+* PARAMETERS:
+* VOLTS ClockScale Clock scale
+*
+* PROCESS :
+* [1] Enable clock prescaler change
+* [2] Apply clock prescaler
+*
+* NOTES :
+* Changing the clock prescaler to a value other than F_CPU (1 by default)
+* can/will result in some clock-based functions not working, including
+* timers and most communication protocols.
+*
+* FURTHER READING :
+* ATmega640/V-1280/V-1281/V-2560/V-2561/V § 10.13.2 [PDF: https://rmy.pw/atmega2560]
+*
+*F*/
+void setClockScale(VOLTS __x)
+{
+ uint8_t __tmp = _BV(CLKPCE); /*[1]*/
+ __asm__ __volatile__ (
+ "in __tmp_reg__,__SREG__" "\n\t"
+ "cli" "\n\t"
+ "sts %1, %0" "\n\t"
+ "sts %1, %2" "\n\t"
+ "out __SREG__, __tmp_reg__"
+ : /* no outputs */
+ : "d" (__tmp),
+ "M" (_SFR_MEM_ADDR(CLKPR)),
+ "d" (__x)
+ : "r0"
+ ); /*[2]*/
+}
+
+/*F******************************************************************
+* NAME : VOLTS setVoltage( Voltage )
+*
+* DESCRIPTION : Adjust voltage (and clock prescaler, if enabled)
+*
+* INPUTS :
+* PARAMETERS:
+* VOLTS Voltage Voltage
+*
+* OUTPUTS :
+* RETURN :
+* Type: VOLTS Result:
+* Values: VOLTS_SUCCESS Successfully set the voltage/clock
+* VOLTS_ERROR Something went wrong
+* VOLTS_NOTENABLED VSELECT and 3V3FIX are both disabled
+*
+* PROCESS :
+* [1] Apply voltage
+* [2] Apply clock prescaler
+*
+* NOTES :
+* When changing to 5V the voltage is set first so that the MPU
+* will be stable at 16MHz. When going down to 3.3V the clock
+* is changed to 8MHz first so that the MPU will be stable when
+* the voltage is changed to 3.3V.
+*
+* This works best with VSELECT as the firmware controls the
+* timing of all of this. If you are doing this manually, then
+* you'll need to start the OSCR with 5V set and only switch to
+* 3.3V once on the main menu.
+*
+*F*/
+#if defined(ENABLE_VSELECT) || defined(ENABLE_3V3FIX)
+VOLTS setVoltage(VOLTS newVoltage) {
+ switch(newVoltage) {
+ /* 5V */
+ case VOLTS_SET_5V:
+ if (
+ #if defined(ENABLE_3V3FIX)
+ clock == CS_16MHZ
+ #endif
+ #if defined(ENABLE_VSELECT) && defined(ENABLE_3V3FIX)
+ &&
+ #endif
+ #if defined(ENABLE_VSELECT)
+ VOLTS_SET_5V == voltage
+ #endif
+ ) return VOLTS_SUCCESS; // Just return if already as requested
+
+ // Adjust voltage high if VSELECT is available
+ #if defined(ENABLE_VSELECT)
+ PORTD &= ~(1 << 7); /*[1]*/
+ voltage = VOLTS_SET_5V;
+ #endif
+
+ // Adjust clock speed when 3V3FIX is enabled
+ #if defined(ENABLE_3V3FIX)
+ // Stop serial if running
+ #if !defined(enable_serial) && defined(ENABLE_UPDATER)
+ ClockedSerial.end();
+ #endif
+ // Set clock speed
+ clock = CS_16MHZ;
+ setClockScale(newVoltage); /*[2]*/
+ // Restart serial
+ #if !defined(enable_serial) && defined(ENABLE_UPDATER)
+ ClockedSerial.begin(UPD_BAUD);
+ #endif
+ #else
+ clock = CS_16MHZ;
+ #endif
+
+ // Done
+ return VOLTS_SUCCESS;
+
+ /* 3.3V */
+ case VOLTS_SET_3V3:
+ if (
+ #if defined(ENABLE_3V3FIX)
+ clock == CS_8MHZ
+ #endif
+ #if defined(ENABLE_VSELECT) && defined(ENABLE_3V3FIX)
+ &&
+ #endif
+ #if defined(ENABLE_VSELECT)
+ VOLTS_SET_3V3 == voltage
+ #endif
+ ) return VOLTS_SUCCESS; // Just return if already as requested
+
+ // Adjust clock speed when 3V3FIX is enabled
+ #if defined(ENABLE_3V3FIX)
+ #if !defined(enable_serial) && defined(ENABLE_UPDATER)
+ ClockedSerial.end();
+ #endif
+ // Set clock speed
+ clock = CS_8MHZ;
+ setClockScale(newVoltage); /*[2]*/
+ #if !defined(enable_serial) && defined(ENABLE_UPDATER)
+ ClockedSerial.begin(UPD_BAUD);
+ #endif
+ #endif
+
+ // Adjust voltage high if VSELECT is available
+ #if defined(ENABLE_VSELECT)
+ PORTD |= (1 << 7); /*[1]*/
+ voltage = VOLTS_SET_3V3;
+ #endif
+
+ // Done
+ return VOLTS_SUCCESS;
+
+ /* ??? */
+ default:
+ return VOLTS_ERROR;
+ }
+}
+#else
+// The compiler will optimize this out when this condition is met.
+// Yes, even though it has a return value it will only be compiled
+// if something reads that value. Currently nothing does.
+VOLTS setVoltage(VOLTS newVoltage __attribute__((unused))) {
+ return VOLTS_NOTENABLED;
+}
+#endif
|