mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-24 12:01:53 +01:00
Merge pull request #752 from Ancyker/master
Firmware Updater support, 3.3V Fix, and more
This commit is contained in:
commit
910430623d
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -46,5 +46,5 @@ jobs:
|
||||
run: |
|
||||
cd Cart_Reader/
|
||||
# Select hardware version by uncommenting it (using regular expression)
|
||||
sed -i 's/^\/\/[\t ]*#define ${{ matrix.hwVersion }}/#define ${{ matrix.hwVersion }}/g' Cart_Reader.ino
|
||||
sed -i 's/^\/\/[\t ]*#define ${{ matrix.hwVersion }}/#define ${{ matrix.hwVersion }}/g' Config.h
|
||||
arduino-cli compile --fqbn arduino:avr:mega --warnings all
|
||||
|
@ -94,6 +94,7 @@ void setup_ARC() {
|
||||
}
|
||||
|
||||
void arcMenu() {
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
convertPgm(menuOptionsARC, 4);
|
||||
uint8_t mainMenu = question_box(F("ARCADIA 2001 MENU"), menuOptions, 4, 0);
|
||||
|
||||
|
@ -101,6 +101,7 @@ void setup_ATARI() {
|
||||
}
|
||||
|
||||
void atariMenu() {
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
convertPgm(menuOptionsATARI, 4);
|
||||
uint8_t mainMenu = question_box(F("ATARI 2600 MENU"), menuOptions, 4, 0);
|
||||
|
||||
|
@ -93,7 +93,7 @@ void setup_COL() {
|
||||
}
|
||||
|
||||
void colMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
convertPgm(menuOptionsCOL, 4);
|
||||
uint8_t mainMenu = question_box(F("COLECOVISION MENU"), menuOptions, 4, 0);
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
This project represents a community-driven effort to provide
|
||||
an easy to build and easy to modify cartridge dumper.
|
||||
|
||||
Date: 25.03.2023
|
||||
Version: 12.4
|
||||
Date: 2023-03-29
|
||||
Version: 12.5
|
||||
|
||||
SD lib: https://github.com/greiman/SdFat
|
||||
LCD lib: https://github.com/olikraus/u8g2
|
||||
@ -57,175 +57,11 @@
|
||||
|
||||
**********************************************************************************/
|
||||
|
||||
char ver[5] = "12.4";
|
||||
|
||||
//******************************************
|
||||
// !!! CHOOSE HARDWARE VERSION !!!
|
||||
//******************************************
|
||||
// Remove // in front of the line with your hardware version
|
||||
// #define HW5
|
||||
// #define HW4
|
||||
// #define HW3
|
||||
// #define HW2
|
||||
// #define HW1
|
||||
// #define SERIAL_MONITOR
|
||||
|
||||
#if !(defined(HW1) || defined(HW2) || defined(HW3) || defined(HW4) || defined(HW5) || defined(SERIAL_MONITOR))
|
||||
#error !!! PLEASE CHOOSE HARDWARE VERSION !!!
|
||||
#endif
|
||||
|
||||
//******************************************
|
||||
// ENABLE MODULES
|
||||
//******************************************
|
||||
// add/remove // before #define to disable/enable modules you
|
||||
// don't need/need to save program storage space and dynamic memory
|
||||
// If you only get an empty or "Press Button" screen after flashing
|
||||
// you have enabled too many modules
|
||||
|
||||
// Self test
|
||||
#define enable_selftest
|
||||
|
||||
// Atari 2600
|
||||
//#define enable_ATARI
|
||||
|
||||
// Benesse Pocket Challenge W
|
||||
//#define enable_PCW
|
||||
|
||||
// ColecoVision
|
||||
//#define enable_COLV
|
||||
|
||||
// Emerson Arcadia 2001
|
||||
//#define enable_ARC
|
||||
|
||||
// Fairchild Channel F
|
||||
//#define enable_FAIRCHILD
|
||||
|
||||
// Flashrom Programmer for SNES repros
|
||||
#define enable_FLASH
|
||||
//#define enable_FLASH16
|
||||
|
||||
// Game Boy (Color) and Advance
|
||||
#define enable_GBX
|
||||
|
||||
// Intellivision
|
||||
//#define enable_INTV
|
||||
|
||||
// Neo Geo Pocket
|
||||
//#define enable_NGP
|
||||
|
||||
// Nintendo 64
|
||||
#define enable_N64
|
||||
|
||||
// Nintendo Entertainment System/Family Computer
|
||||
#define enable_NES
|
||||
|
||||
// Magnavox Odyssey 2
|
||||
//#define enable_ODY2
|
||||
|
||||
// PC Engine/TurboGrafx 16
|
||||
//#define enable_PCE
|
||||
|
||||
// Sega Master System/Mark III/Game Gear/SG-1000
|
||||
#define enable_SMS
|
||||
|
||||
// Sega Mega Drive/Genesis
|
||||
#define enable_MD
|
||||
|
||||
// Super Famicom SF Memory Cassette
|
||||
#define enable_SFM
|
||||
|
||||
// Super Famicom Satellaview
|
||||
#define enable_SV
|
||||
|
||||
// Super Nintendo
|
||||
#define enable_SNES
|
||||
|
||||
// Virtual Boy
|
||||
//#define enable_VBOY
|
||||
|
||||
// Watara Supervision
|
||||
//#define enable_WSV
|
||||
|
||||
// WonderSwan and Benesse Pocket Challenge v2
|
||||
//#define enable_WS
|
||||
|
||||
// Super A'can
|
||||
//#define enable_SUPRACAN
|
||||
|
||||
//******************************************
|
||||
// HW CONFIGS
|
||||
//******************************************
|
||||
#if (defined(HW4) || defined(HW5))
|
||||
// #define enable_vselect
|
||||
#define enable_LCD
|
||||
#define enable_neopixel
|
||||
#define background_color 100, 0, 0 //Green, Red, Blue
|
||||
#define enable_rotary
|
||||
// #define rotate_counter_clockwise
|
||||
#define clockgen_installed
|
||||
#define fastcrc
|
||||
#define ws_adapter_v2
|
||||
#endif
|
||||
|
||||
#if (defined(HW2) || defined(HW3))
|
||||
#define enable_OLED
|
||||
#define enable_Button2
|
||||
#define clockgen_installed
|
||||
#define CA_LED
|
||||
#define fastcrc
|
||||
#endif
|
||||
|
||||
#if defined(HW1)
|
||||
#define enable_OLED
|
||||
// #define clockgen_installed
|
||||
// #define fastcrc
|
||||
#endif
|
||||
|
||||
#if defined(SERIAL_MONITOR)
|
||||
#define enable_serial
|
||||
//#define clockgen_installed
|
||||
//#define fastcrc
|
||||
#endif
|
||||
|
||||
//******************************************
|
||||
// OPTIONS
|
||||
//******************************************
|
||||
// Change mainMenu to snsMenu, mdMenu, n64Menu, gbxMenu, pcsMenu,
|
||||
// flashMenu, nesMenu or smsMenu for single slot Cart Readers
|
||||
#define startMenu mainMenu
|
||||
|
||||
// Write all info to OSCR_LOG.txt in root dir
|
||||
#define global_log
|
||||
|
||||
// Renames ROM if found in database
|
||||
#define nointro
|
||||
|
||||
// Setup RTC if installed.
|
||||
// #define RTC_installed
|
||||
|
||||
// Use calibration data from snes_clk.txt
|
||||
// #define clockgen_calibration
|
||||
|
||||
// Use Adafruit Clock Generator
|
||||
// #define clockgen_installed
|
||||
|
||||
// I don't know
|
||||
//#define use_md_conf
|
||||
|
||||
// The CRC for N64 Roms will be calculated during dumping from memory instead of after dumping from SD card, not compatible to all Cart Readers
|
||||
// #define fastcrc
|
||||
|
||||
// saves a n64log.txt file with rom info in /N64/ROM
|
||||
// #define savesummarytotxt
|
||||
#include "OSCR.h"
|
||||
|
||||
/******************************************
|
||||
Libraries
|
||||
*****************************************/
|
||||
// Basic Libs
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/wdt.h>
|
||||
|
||||
// SD Card
|
||||
#include "SdFat.h"
|
||||
@ -2143,14 +1979,18 @@ int32_t initializeClockOffset() {
|
||||
Setup
|
||||
*****************************************/
|
||||
void setup() {
|
||||
#if !defined(enable_serial) && defined(ENABLE_UPDATER)
|
||||
ClockedSerial.begin(UPD_BAUD);
|
||||
#endif
|
||||
|
||||
// Set Button Pin PG2 to Input
|
||||
DDRG &= ~(1 << 2);
|
||||
#if defined(HW5) && !defined(enable_vselect)
|
||||
#if defined(HW5) && !defined(ENABLE_VSELECT)
|
||||
// HW5 has status LED connected to PD7
|
||||
// Set LED Pin PD7 to Output
|
||||
DDRD |= (1 << 7);
|
||||
PORTD |= (1 << 7);
|
||||
#elif defined(enable_vselect)
|
||||
#elif defined(ENABLE_VSELECT)
|
||||
DDRD |= (1 << 7);
|
||||
#else
|
||||
// HW1/2/3 have button connected to PD7
|
||||
@ -2164,6 +2004,7 @@ void setup() {
|
||||
|
||||
// Read current folder number out of eeprom
|
||||
EEPROM_readAnything(0, foldern);
|
||||
if (foldern < 0) foldern = 0;
|
||||
|
||||
#ifdef enable_LCD
|
||||
display.begin();
|
||||
@ -2172,6 +2013,11 @@ void setup() {
|
||||
#endif
|
||||
|
||||
#ifdef enable_neopixel
|
||||
#if defined(ENABLE_3V3FIX)
|
||||
// Set power high for neopixel
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
delay(10);
|
||||
#endif
|
||||
pixels.begin();
|
||||
pixels.clear();
|
||||
pixels.setPixelColor(0, pixels.Color(background_color));
|
||||
@ -2180,24 +2026,27 @@ void setup() {
|
||||
pixels.show();
|
||||
|
||||
// Set TX0 LED Pin(PE1) to Output for status indication during flashing for HW4
|
||||
#if !(defined(enable_serial) || defined(HW5))
|
||||
DDRE |= (1 << 1);
|
||||
#endif
|
||||
#if !(defined(enable_serial) || defined(HW5))
|
||||
DDRE |= (1 << 1);
|
||||
#endif
|
||||
#else
|
||||
#ifndef enable_LCD
|
||||
#ifdef CA_LED
|
||||
// Turn LED off
|
||||
digitalWrite(12, 1);
|
||||
digitalWrite(11, 1);
|
||||
digitalWrite(10, 1);
|
||||
#endif
|
||||
// Configure 4 Pin RGB LED pins as output
|
||||
DDRB |= (1 << DDB6); // Red LED (pin 12)
|
||||
DDRB |= (1 << DDB5); // Green LED (pin 11)
|
||||
DDRB |= (1 << DDB4); // Blue LED (pin 10)
|
||||
#endif
|
||||
#ifndef enable_LCD
|
||||
#ifdef CA_LED
|
||||
// Turn LED off
|
||||
digitalWrite(12, 1);
|
||||
digitalWrite(11, 1);
|
||||
digitalWrite(10, 1);
|
||||
#endif
|
||||
// Configure 4 Pin RGB LED pins as output
|
||||
DDRB |= (1 << DDB6); // Red LED (pin 12)
|
||||
DDRB |= (1 << DDB5); // Green LED (pin 11)
|
||||
DDRB |= (1 << DDB4); // Blue LED (pin 10)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Set power to low to protect carts
|
||||
setVoltage(VOLTS_SET_3V3);
|
||||
|
||||
#ifdef enable_OLED
|
||||
display.begin();
|
||||
//isplay.setContrast(40);
|
||||
@ -2220,6 +2069,11 @@ void setup() {
|
||||
print_FatalError(sd_error_STR);
|
||||
}
|
||||
|
||||
#if !defined(enable_serial) && defined(ENABLE_UPDATER)
|
||||
printVersionToSerial();
|
||||
ClockedSerial.flush();
|
||||
#endif
|
||||
|
||||
#ifdef global_log
|
||||
if (!myLog.open("OSCR_LOG.txt", O_RDWR | O_CREAT | O_APPEND)) {
|
||||
print_FatalError(sd_error_STR);
|
||||
@ -2253,9 +2107,6 @@ void setup() {
|
||||
// status LED ON
|
||||
statusLED(true);
|
||||
|
||||
// Set power to low to protect carts
|
||||
vselect(true);
|
||||
|
||||
// Start menu system
|
||||
startMenu();
|
||||
}
|
||||
@ -2282,6 +2133,9 @@ void dataIn() {
|
||||
// Set RGB color
|
||||
void setColor_RGB(byte r, byte g, byte b) {
|
||||
#if defined(enable_neopixel)
|
||||
#if defined(ENABLE_3V3FIX)
|
||||
if (clock == CS_8MHZ) return;
|
||||
#endif
|
||||
// Dim Neopixel LEDs
|
||||
if (r >= 100) r = 100;
|
||||
if (g >= 100) g = 100;
|
||||
@ -2741,7 +2595,7 @@ void rgbLed(byte Color) {
|
||||
}
|
||||
|
||||
void blinkLED() {
|
||||
#if defined(enable_vselect)
|
||||
#if defined(ENABLE_VSELECT)
|
||||
// Nothing
|
||||
#elif defined(HW5)
|
||||
PORTD ^= (1 << 7);
|
||||
@ -2755,52 +2609,16 @@ void blinkLED() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(HW5) && !defined(enable_vselect)
|
||||
#if defined(HW5) && !defined(ENABLE_VSELECT)
|
||||
void statusLED(boolean on) {
|
||||
if (!on)
|
||||
PORTD |= (1 << 7);
|
||||
else
|
||||
PORTD &= ~(1 << 7);
|
||||
/*
|
||||
#elif defined(enable_OLED)
|
||||
if (!on)
|
||||
PORTB |= (1 << 4);
|
||||
else
|
||||
PORTB &= ~(1 << 4);
|
||||
|
||||
#elif defined(enable_LCD)
|
||||
if (!on)
|
||||
PORTE |= (1 << 1);
|
||||
else
|
||||
PORTE &= ~(1 << 1);
|
||||
|
||||
#elif defined(enable_serial)
|
||||
if (!on) {
|
||||
PORTB |= (1 << 4);
|
||||
PORTB |= (1 << 7);
|
||||
}
|
||||
else {
|
||||
PORTB &= ~(1 << 4);
|
||||
PORTB &= ~(1 << 7);
|
||||
}
|
||||
*/
|
||||
}
|
||||
void vselect(boolean vlow __attribute__((unused))) {
|
||||
}
|
||||
#elif defined(enable_vselect)
|
||||
void statusLED(boolean on __attribute__((unused))) {
|
||||
}
|
||||
void vselect(boolean vlow) {
|
||||
if (vlow)
|
||||
PORTD |= (1 << 7);
|
||||
else
|
||||
PORTD &= ~(1 << 7);
|
||||
}
|
||||
#else
|
||||
void statusLED(boolean on __attribute__((unused))) {
|
||||
}
|
||||
void vselect(boolean vlow __attribute__((unused))) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************
|
||||
@ -3035,6 +2853,8 @@ unsigned char questionBox_Display(const __FlashStringHelper* question, char answ
|
||||
numPages = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
checkUpdater();
|
||||
}
|
||||
|
||||
// pass on user choice
|
||||
@ -3050,6 +2870,39 @@ unsigned char questionBox_Display(const __FlashStringHelper* question, char answ
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(enable_serial) && defined(ENABLE_UPDATER)
|
||||
void checkUpdater() {
|
||||
if (ClockedSerial.available() > 0) {
|
||||
String cmd = ClockedSerial.readStringUntil('\n');
|
||||
cmd.trim();
|
||||
if (cmd == "VERCHK") {
|
||||
delay(500);
|
||||
printVersionToSerial();
|
||||
} else if (cmd == "GETCLOCK") {
|
||||
#if defined(ENABLE_3V3FIX)
|
||||
ClockedSerial.print(F("Clock is running at "));
|
||||
ClockedSerial.print((clock == CS_16MHZ) ? 16UL : 8UL);
|
||||
ClockedSerial.println(F("MHz"));
|
||||
#else
|
||||
ClockedSerial.println(F("Dynamic clock speed (3V3FIX) is not enabled."));
|
||||
#endif
|
||||
} else if (cmd == "GETVOLTS") {
|
||||
#if defined(ENABLE_VSELECT)
|
||||
ClockedSerial.print(F("Voltage is set to "));
|
||||
ClockedSerial.print((voltage == VOLTS_SET_5V) ? 5 : 3.3);
|
||||
ClockedSerial.println(F("V"));
|
||||
#else
|
||||
ClockedSerial.println(F("Automatic voltage selection (VSELECT) is not enabled."));
|
||||
#endif
|
||||
} else {
|
||||
ClockedSerial.println(F("OSCR: Unknown Command"));
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void checkUpdater() {}
|
||||
#endif
|
||||
|
||||
/******************************************
|
||||
User Control
|
||||
*****************************************/
|
||||
@ -3275,6 +3128,8 @@ void wait_btn() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
checkUpdater();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -3353,6 +3208,8 @@ void wait_btn() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
checkUpdater();
|
||||
}
|
||||
}
|
||||
|
||||
|
118
Cart_Reader/ClockedSerial.cpp
Normal file
118
Cart_Reader/ClockedSerial.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/********************************************************************
|
||||
* Open Source Cartridge Reader for Arduino Mega 2560 */
|
||||
/*H******************************************************************
|
||||
* FILENAME : ClockedSerial.cpp
|
||||
*
|
||||
* DESCRIPTION :
|
||||
* Modified HardwareSerial class for using with a dynamic clock speed.
|
||||
*
|
||||
* PUBLIC FUNCTIONS :
|
||||
* void DynamicClockSerial::begin(baud, config, sclock)
|
||||
*
|
||||
* 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"
|
||||
#include "ClockedSerial.h"
|
||||
|
||||
/*
|
||||
* This function is unchanged, including comments, from HardwareSerial. Comments not from
|
||||
* the original function are denoted with a prefix of "(ClockedSerial)".
|
||||
*
|
||||
* The parameter `sclock` is used to let it know the clockspeed. It replaces the usage of
|
||||
* the F_CPU preprocessor variable. Unlike `clock_prescale_set` this parameter is the
|
||||
* speed in MHz, i.e. 16000000 (16MHz).
|
||||
*/
|
||||
void DynamicClockSerial::begin(unsigned long baud, byte config, unsigned long sclock)
|
||||
{
|
||||
// Try u2x mode first
|
||||
uint16_t baud_setting = (sclock / 4 / baud - 1) / 2;
|
||||
*_ucsra = 1 << U2X0;
|
||||
|
||||
// hardcoded exception for 57600 for compatibility with the bootloader
|
||||
// shipped with the Duemilanove and previous boards and the firmware
|
||||
// on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot
|
||||
// be > 4095, so switch back to non-u2x mode if the baud rate is too
|
||||
// low.
|
||||
if (((sclock == 16000000UL) && (baud == 57600)) || (baud_setting > 4095)) /* (ClockedSerial) F_CPU -> sclock variable/parameter */
|
||||
{
|
||||
*_ucsra = 0;
|
||||
baud_setting = (sclock / 8 / baud - 1) / 2; /* (ClockedSerial) This is where we adjust things based on clock speed; F_CPU -> sclock variable/parameter */
|
||||
}
|
||||
|
||||
// assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register)
|
||||
*_ubrrh = baud_setting >> 8;
|
||||
*_ubrrl = baud_setting;
|
||||
|
||||
_written = false;
|
||||
|
||||
//set the data bits, parity, and stop bits
|
||||
#if defined(__AVR_ATmega8__)
|
||||
config |= 0x80; // select UCSRC register (shared with UBRRH)
|
||||
#endif
|
||||
*_ucsrc = config;
|
||||
|
||||
sbi(*_ucsrb, RXEN0);
|
||||
sbi(*_ucsrb, TXEN0);
|
||||
sbi(*_ucsrb, RXCIE0);
|
||||
cbi(*_ucsrb, UDRIE0);
|
||||
}
|
||||
|
||||
// ClockedSerial setup
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) && !defined(enable_serial) && defined(ENABLE_UPDATER)
|
||||
#if defined(UBRRH) && defined(UBRRL)
|
||||
DynamicClockSerial ClockedSerial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR);
|
||||
#else
|
||||
DynamicClockSerial ClockedSerial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0);
|
||||
#endif
|
||||
|
||||
#if defined(USART_RX_vect)
|
||||
ISR(USART_RX_vect)
|
||||
#elif defined(USART0_RX_vect)
|
||||
ISR(USART0_RX_vect)
|
||||
#elif defined(USART_RXC_vect)
|
||||
ISR(USART_RXC_vect) // ATmega8
|
||||
#else
|
||||
#error "Don't know what the Data Received vector is called for Serial"
|
||||
#endif
|
||||
{
|
||||
ClockedSerial._rx_complete_irq();
|
||||
}
|
||||
|
||||
#if defined(UART0_UDRE_vect)
|
||||
ISR(UART0_UDRE_vect)
|
||||
#elif defined(UART_UDRE_vect)
|
||||
ISR(UART_UDRE_vect)
|
||||
#elif defined(USART0_UDRE_vect)
|
||||
ISR(USART0_UDRE_vect)
|
||||
#elif defined(USART_UDRE_vect)
|
||||
ISR(USART_UDRE_vect)
|
||||
#else
|
||||
#error "Don't know what the Data Register Empty vector is called for Serial"
|
||||
#endif
|
||||
{
|
||||
ClockedSerial._tx_udr_empty_irq();
|
||||
}
|
||||
|
||||
bool Serial0_available() {
|
||||
return ClockedSerial.available();
|
||||
}
|
||||
#endif
|
33
Cart_Reader/ClockedSerial.h
Normal file
33
Cart_Reader/ClockedSerial.h
Normal file
@ -0,0 +1,33 @@
|
||||
/********************************************************************
|
||||
* Open Source Cartridge Reader *
|
||||
********************************************************************/
|
||||
#ifndef CLOCKEDSERIAL_H_
|
||||
#define CLOCKEDSERIAL_H_
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
#include <HardwareSerial_private.h>
|
||||
|
||||
/*C******************************************************************
|
||||
* NAME : ClockedSerial
|
||||
*
|
||||
* DESCRIPTION : HardwareSerial wrapper that allows for dynamic clock speed adjustments.
|
||||
*
|
||||
* USAGE : See HardwareSerial
|
||||
*
|
||||
* NOTES : If this class isn't used the compiler will optimize it out, so there is
|
||||
* no harm in leaving it.
|
||||
*C*/
|
||||
class DynamicClockSerial : public HardwareSerial
|
||||
{
|
||||
using HardwareSerial::HardwareSerial;
|
||||
public:
|
||||
// Various functions to allow parameter omission and automatic handling.
|
||||
void begin(unsigned long baud) { begin(baud, SERIAL_8N1, clock); }
|
||||
void begin(unsigned long baud, byte config) { begin(baud, config, clock); }
|
||||
void begin(unsigned long baud, unsigned long sclock) { begin(baud, SERIAL_8N1, sclock); }
|
||||
void begin(unsigned long baud, byte config, unsigned long sclock);
|
||||
};
|
||||
|
||||
extern DynamicClockSerial ClockedSerial;
|
||||
|
||||
#endif /* CLOCKEDSERIAL_H_ */
|
389
Cart_Reader/Config.h
Normal file
389
Cart_Reader/Config.h
Normal file
@ -0,0 +1,389 @@
|
||||
/********************************************************************
|
||||
* Open Source Cartridge Reader *
|
||||
********************************************************************/
|
||||
|
||||
#ifndef CONFIG_H_
|
||||
#define CONFIG_H_
|
||||
|
||||
/***** FIRMWARE CONFIGURATION **************************************
|
||||
*
|
||||
* Add or remove the "//" in front of items to toggle them.
|
||||
*
|
||||
* Disabled:
|
||||
* //#define HW5
|
||||
*
|
||||
* Enabled:
|
||||
* #define HW5
|
||||
*
|
||||
* Things in ** blocks like this are comments. Changing them doesn't
|
||||
* affect the firmware that is flashed to your OSCR.
|
||||
*
|
||||
* If you only get a blank screen or "Press Button" message after
|
||||
* flashing you have enabled too many modules.
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
/*==== HARDWARE VERSION ===========================================*/
|
||||
|
||||
/*
|
||||
* Choose your hardware version:
|
||||
*/
|
||||
|
||||
//#define HW5
|
||||
//#define HW4
|
||||
//#define HW3
|
||||
//#define HW2
|
||||
//#define HW1
|
||||
//#define SERIAL_MONITOR
|
||||
|
||||
/****/
|
||||
|
||||
/*==== HARDWARE MODULES ===========================================*/
|
||||
|
||||
/* [ Automatic Voltage Selection ---------------------------------- ]
|
||||
* Enable this if you have the VSELECT module.
|
||||
*/
|
||||
|
||||
//#define ENABLE_VSELECT
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Clock Generator ---------------------------------------------- ]
|
||||
* Enable this if you have the clock generator module.
|
||||
*/
|
||||
|
||||
//#define clockgen_installed
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Real Time Clock ---------------------------------------------- ]
|
||||
* Enable this if you have the RTC module.
|
||||
*/
|
||||
|
||||
//#define RTC_installed
|
||||
|
||||
/****/
|
||||
|
||||
/*==== GAME SYSTEM CORES ==========================================*/
|
||||
|
||||
/* [ Atari 2600 --------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_ATARI
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Benesse Pocket Challenge W ----------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_PCW
|
||||
|
||||
/****/
|
||||
|
||||
/* [ ColecoVision ------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_COLV
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Emerson Arcadia 2001 ----------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_ARC
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Fairchild Channel F ------------------------------------------ ]
|
||||
*/
|
||||
|
||||
//#define enable_FAIRCHILD
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Flashrom Programmer for SNES repros -------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_FLASH
|
||||
//#define enable_FLASH16
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Game Boy (Color) and Advance --------------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_GBX
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Intellivision ------------------------------------------------ ]
|
||||
*/
|
||||
|
||||
//#define enable_INTV
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Neo Geo Pocket ----------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_NGP
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Nintendo 64 -------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_N64
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Nintendo Entertainment System/Family Computer ---------------- ]
|
||||
*/
|
||||
|
||||
#define enable_NES
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Magnavox Odyssey 2 ------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_ODY2
|
||||
|
||||
/****/
|
||||
|
||||
/* [ PC Engine/TurboGrafx 16 -------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_PCE
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Sega Master System/Mark III/Game Gear/SG-1000 ---------------- ]
|
||||
*/
|
||||
|
||||
#define enable_SMS
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Sega Mega Drive/Genesis -------------------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_MD
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super Famicom SF Memory Cassette ----------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_SFM
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super Famicom Satellaview ------------------------------------ ]
|
||||
*/
|
||||
|
||||
#define enable_SV
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super Nintendo ----------------------------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_SNES
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Virtual Boy -------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_VBOY
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Watara Supervision ------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_WSV
|
||||
|
||||
/****/
|
||||
|
||||
/* [ WonderSwan and Benesse Pocket Challenge v2 ------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_WS
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super A'can -------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_SUPRACAN
|
||||
|
||||
/****/
|
||||
|
||||
/*==== FIRMWARE OPTIONS ===========================================*/
|
||||
|
||||
/* [ LCD: Background Color ---------------------------------------- ]
|
||||
* Set the backlight color of the LCD if you have one.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* Green, Red, Blue
|
||||
*/
|
||||
|
||||
#define background_color 100, 0, 0
|
||||
|
||||
/****/
|
||||
|
||||
/* [ 3.3V Stability Fix (3V3FIX) ---------------------------------- ]
|
||||
* Enable this if you are having stability issues when using 3.3V,
|
||||
* works best with VSELECT.
|
||||
*
|
||||
* If not using VSELECT, always turn the cart reader on with the
|
||||
* voltage switch set to 5V and switch to 5V before selecting a
|
||||
* cartridge from the menu.
|
||||
*/
|
||||
|
||||
//#define ENABLE_3V3FIX
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Updater ------------------------------------------------------ ]
|
||||
* Disable this if you don't plan to/want to use the firmware
|
||||
* updater utility. This setting is ignored on hardware versions
|
||||
* other than HW5 and HW3.
|
||||
*/
|
||||
|
||||
#define ENABLE_UPDATER
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Self Test ---------------------------------------------------- ]
|
||||
* Tests for shorts and other issues in your OSCR build.
|
||||
*/
|
||||
|
||||
#define enable_selftest
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Start Menu --------------------------------------------------- ]
|
||||
* Change this when using a single slot cart reader to always start
|
||||
* in that menu.
|
||||
*
|
||||
* OPTIONS :
|
||||
* mainMenu, snsMenu, mdMenu, n64Menu, gbxMenu, pcsMenu,
|
||||
* flashMenu, nesMenu, smsMenu
|
||||
*/
|
||||
|
||||
#define startMenu mainMenu
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Logging ------------------------------------------------------ ]
|
||||
* Write all info to OSCR_LOG.txt in root dir
|
||||
*/
|
||||
|
||||
#define global_log
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Use No Intro Database ---------------------------------------- ]
|
||||
* Renames ROM if found in database
|
||||
*/
|
||||
|
||||
#define nointro
|
||||
|
||||
/****/
|
||||
|
||||
/* [ SNES Core/CLOCKGEN: Read Clock Generator Calibration Data ---- ]
|
||||
* Toggle to use calibration data from snes_clk.txt
|
||||
*/
|
||||
|
||||
//#define clockgen_calibration
|
||||
|
||||
/****/
|
||||
|
||||
/* [ MegaDrive/Genesis Core: Compatibility Settings --------------- ]
|
||||
* Allows you to create a text file on the SD card called
|
||||
* "mdconf.txt" which you should place the following into:
|
||||
*
|
||||
* [segaSram16bit] N
|
||||
*
|
||||
* Where N is:
|
||||
* 0: Output each byte once. Not supported by emulators. (default)
|
||||
* 1: Duplicate each byte. Usable by Kega Fusion.
|
||||
* 2: Same as 1 + pad with 0xFF so that the file size is 64KB.
|
||||
*/
|
||||
|
||||
//#define use_md_conf
|
||||
|
||||
/*
|
||||
* Alternatively, define it here by uncommenting and changing the
|
||||
* following line. Setting both allows you to change the default.
|
||||
*/
|
||||
|
||||
//#define DEFAULT_VALUE_segaSram16bit 0
|
||||
|
||||
/****/
|
||||
|
||||
/* [ N64 Core: Fast CRC ------------------------------------------- ]
|
||||
* Toggle so the CRC for N64 Roms will be calculated during dumping
|
||||
* from memory instead of after dumping from SD card, not compatible
|
||||
* with all Cart Readers
|
||||
*/
|
||||
|
||||
//#define fastcrc
|
||||
|
||||
/****/
|
||||
|
||||
/* [ N64 Core: Log Summary ---------------------------------------- ]
|
||||
* Enable to save a n64log.txt file with rom info in /N64/ROM
|
||||
*/
|
||||
|
||||
//#define savesummarytotxt
|
||||
|
||||
/****/
|
||||
|
||||
/*==== PROCESSING =================================================*/
|
||||
|
||||
/*
|
||||
* You probably shouldn't change this stuff!
|
||||
*/
|
||||
|
||||
#if (defined(HW4) || defined(HW5))
|
||||
#define enable_LCD
|
||||
#define enable_neopixel
|
||||
#define enable_rotary
|
||||
//#define rotate_counter_clockwise
|
||||
#define clockgen_installed
|
||||
#define fastcrc
|
||||
#define ws_adapter_v2
|
||||
#endif
|
||||
|
||||
#if (defined(HW2) || defined(HW3))
|
||||
#define enable_OLED
|
||||
#define enable_Button2
|
||||
#define clockgen_installed
|
||||
#define CA_LED
|
||||
#define fastcrc
|
||||
#endif
|
||||
|
||||
#if defined(HW1)
|
||||
#define enable_OLED
|
||||
//#define clockgen_installed
|
||||
//#define fastcrc
|
||||
#endif
|
||||
|
||||
#if defined(SERIAL_MONITOR)
|
||||
#define enable_serial
|
||||
//#define clockgen_installed
|
||||
//#define fastcrc
|
||||
#endif
|
||||
|
||||
/* Firmware updater only works with HW3 and HW5 */
|
||||
#if !(defined(HW5) || defined(HW3))
|
||||
#undef ENABLE_UPDATER
|
||||
#endif
|
||||
|
||||
/* End of settings */
|
||||
|
||||
#endif /* CONFIG_H_ */
|
@ -126,6 +126,7 @@ void setup_FAIRCHILD() {
|
||||
}
|
||||
|
||||
void fairchildMenu() {
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
convertPgm(menuOptionsFAIRCHILD, 5);
|
||||
uint8_t mainMenu = question_box(F("CHANNEL F MENU"), menuOptions, 5, 0);
|
||||
|
||||
|
@ -41,7 +41,7 @@ static const char* const menuOptionsGBFlash[] PROGMEM = { GBFlashItem1, GBFlashI
|
||||
|
||||
// Start menu for both GB and GBA
|
||||
void gbxMenu() {
|
||||
vselect(true);
|
||||
setVoltage(VOLTS_SET_3V3);
|
||||
// create menu with title and 4 options to choose from
|
||||
unsigned char gbType;
|
||||
// Copy menuOptions out of progmem
|
||||
@ -51,7 +51,7 @@ void gbxMenu() {
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (gbType) {
|
||||
case 0:
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GB();
|
||||
@ -59,6 +59,7 @@ void gbxMenu() {
|
||||
break;
|
||||
|
||||
case 1:
|
||||
setVoltage(VOLTS_SET_3V3);
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GBA();
|
||||
@ -68,7 +69,7 @@ void gbxMenu() {
|
||||
case 2:
|
||||
// create submenu with title and 7 options to choose from
|
||||
unsigned char gbFlash;
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(menuOptionsGBFlash, 7);
|
||||
gbFlash = question_box(F("Select type"), menuOptions, 7, 0);
|
||||
@ -96,7 +97,7 @@ void gbxMenu() {
|
||||
|
||||
case 1:
|
||||
//Flash MBC5
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GB();
|
||||
|
@ -34,7 +34,7 @@ static const char GBASaveItem6[] PROGMEM = "1M FLASH";
|
||||
static const char* const saveOptionsGBA[] PROGMEM = { GBASaveItem1, GBASaveItem2, GBASaveItem3, GBASaveItem4, GBASaveItem5, GBASaveItem6 };
|
||||
|
||||
void gbaMenu() {
|
||||
vselect(true);
|
||||
setVoltage(VOLTS_SET_3V3);
|
||||
// create menu with title and 4 options to choose from
|
||||
unsigned char mainMenu;
|
||||
// Copy menuOptions out of progmem
|
||||
|
@ -17,7 +17,7 @@ static const char gbmMenuItem7[] PROGMEM = "Write Mapping";
|
||||
static const char* const menuOptionsGBM[] PROGMEM = { gbmMenuItem1, gbmMenuItem2, gbmMenuItem3, gbmMenuItem4, gbmMenuItem5, gbmMenuItem6, gbmMenuItem7 };
|
||||
|
||||
void gbmMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// create menu with title and 7 options to choose from
|
||||
unsigned char mainMenu;
|
||||
// Copy menuOptions out of progmem
|
||||
|
@ -145,7 +145,7 @@ void setup_GBSmart() {
|
||||
}
|
||||
|
||||
void gbSmartMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
uint8_t mainMenu;
|
||||
|
||||
// Copy menuOptions out of progmem
|
||||
|
@ -135,7 +135,7 @@ void setup_INTV() {
|
||||
}
|
||||
|
||||
void intvMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
convertPgm(menuOptionsINTV, 4);
|
||||
uint8_t mainMenu = question_box(F("INTELLIVISION MENU"), menuOptions, 4, 0);
|
||||
|
||||
|
@ -85,7 +85,9 @@ unsigned long bramSize = 0;
|
||||
// REALTEC MAPPER
|
||||
boolean realtec = 0;
|
||||
|
||||
#define DEFAULT_VALUE_segaSram16bit 0
|
||||
#ifndef DEFAULT_VALUE_segaSram16bit
|
||||
#define DEFAULT_VALUE_segaSram16bit 0
|
||||
#endif
|
||||
int segaSram16bit = DEFAULT_VALUE_segaSram16bit;
|
||||
|
||||
//*****************************************
|
||||
@ -209,7 +211,7 @@ static const char* const menuOptionsSCD[] PROGMEM = { SCDMenuItem1, SCDMenuItem2
|
||||
|
||||
// Sega start menu
|
||||
void mdMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// create menu with title and 4 options to choose from
|
||||
unsigned char mdDev;
|
||||
// Copy menuOptions out of progmem
|
||||
|
@ -113,7 +113,7 @@ static const char* const sectorOptionsN64[] PROGMEM = { N64SectorItem1, N64Secto
|
||||
|
||||
// N64 start menu
|
||||
void n64Menu() {
|
||||
vselect(true);
|
||||
setVoltage(VOLTS_SET_3V3);
|
||||
// create menu with title and 5 options to choose from
|
||||
unsigned char n64Dev;
|
||||
// Copy menuOptions out of progmem
|
||||
|
@ -269,7 +269,7 @@ static const char* const menuOptionsNESChips[] PROGMEM = { nesChipsMenuItem1, ne
|
||||
|
||||
// NES start menu
|
||||
void nesMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
unsigned char answer;
|
||||
|
||||
// create menu with title "NES CART READER" and 7 options to choose from
|
||||
@ -2996,7 +2996,7 @@ void readPRG(boolean readrom) {
|
||||
case 59:
|
||||
banks = int_pow(2, prgsize);
|
||||
for (int i = 0; i < banks; i++) {
|
||||
write_prg_byte(0x8000 + (i & 0x07) << 4 | 0x80, 0);
|
||||
write_prg_byte((0x8000 + (i & 0x07)) << 4 | 0x80, 0);
|
||||
for (word address = 0x0; address < 0x4000; address += 512) {
|
||||
dumpPRG(base, address);
|
||||
}
|
||||
@ -4554,7 +4554,7 @@ void readCHR(boolean readrom) {
|
||||
case 228:
|
||||
banks = int_pow(2, chrsize) / 2;
|
||||
for (int i = 0; i < banks; i++) {
|
||||
write_prg_byte(0x8000 + (i & 0x3C) >> 2, (i & 0x03));
|
||||
write_prg_byte((0x8000 + (i & 0x3C)) >> 2, (i & 0x03));
|
||||
for (word address = 0x0; address < 0x2000; address += 512) {
|
||||
dumpCHR(address);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ void setup_NGP() {
|
||||
}
|
||||
|
||||
void ngpMenu() {
|
||||
vselect(true);
|
||||
setVoltage(VOLTS_SET_3V3);
|
||||
uint8_t mainMenu;
|
||||
|
||||
convertPgm(menuOptionsNGP, 4);
|
||||
|
@ -110,6 +110,7 @@ void setup_ODY2() {
|
||||
}
|
||||
|
||||
void ody2Menu() {
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
convertPgm(menuOptionsODY2, 4);
|
||||
uint8_t mainMenu = question_box(F("ODYSSEY 2 MENU"), menuOptions, 4, 0);
|
||||
|
||||
|
238
Cart_Reader/OSCR.cpp
Normal file
238
Cart_Reader/OSCR.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
/********************************************************************
|
||||
* 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.5";
|
||||
|
||||
// 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 (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 volts) {
|
||||
switch(volts) {
|
||||
/* 5V */
|
||||
case VOLTS_SET_5V:
|
||||
if (clock == CS_16MHZ && volts == VOLTS_SET_5V) 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(volts); /*[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 (clock == CS_8MHZ && volts == VOLTS_SET_3V3) 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
|
||||
clock = CS_8MHZ;
|
||||
setClockScale(volts); /*[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
|
||||
VOLTS setVoltage(VOLTS volts __attribute__((unused))) {
|
||||
return VOLTS_NOTENABLED;
|
||||
}
|
||||
#endif
|
57
Cart_Reader/OSCR.h
Normal file
57
Cart_Reader/OSCR.h
Normal file
@ -0,0 +1,57 @@
|
||||
/********************************************************************
|
||||
* Open Source Cartridge Reader *
|
||||
********************************************************************/
|
||||
#ifndef OSCR_H_
|
||||
#define OSCR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/wdt.h>
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
/*==== SANITY CHECKS ==============================================*/
|
||||
#if !(defined(HW1) || defined(HW2) || defined(HW3) || defined(HW4) || defined(HW5) || defined(SERIAL_MONITOR))
|
||||
#error !!! PLEASE CHOOSE HARDWARE VERSION !!!
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_3V3FIX) && !defined(ENABLE_VSELECT)
|
||||
#warning Using 3V3FIX is best with VSELECT.
|
||||
#endif
|
||||
|
||||
/*==== CONSTANTS ==================================================*/
|
||||
// Updater baud rate
|
||||
const uint16_t UPD_BAUD = 9600;
|
||||
// Clock speeds
|
||||
const unsigned long CS_16MHZ = 16000000UL;
|
||||
const unsigned long CS_8MHZ = 8000000UL;
|
||||
|
||||
// ENUM for VSELECT & 3V3FIX
|
||||
enum VOLTS: uint8_t {
|
||||
// Paramters to pass to setVoltage() and setClockScale()
|
||||
VOLTS_SET_5V = 0, // 5V parameter [ClockScale 0 = 16MHz, Voltage = 5V]
|
||||
VOLTS_SET_3V3, // 3.3V parameter [ClockScale 1 = 8MHz, Voltage = 3.3V]
|
||||
// Don't use the following as parameters
|
||||
// Return values:
|
||||
VOLTS_SUCCESS, // Return value for success
|
||||
VOLTS_ERROR, // Return value for error
|
||||
VOLTS_NOTENABLED, // Return value for not being enabled
|
||||
VOLTS_UNKNOWN // Return value for all other states
|
||||
};
|
||||
|
||||
/*==== VARIABLES ==================================================*/
|
||||
extern unsigned long clock;
|
||||
extern char ver[5];
|
||||
extern VOLTS voltage;
|
||||
|
||||
/*==== FUNCTIONS ==================================================*/
|
||||
extern void printVersionToSerial();
|
||||
extern void setClockScale(VOLTS __x);
|
||||
extern VOLTS setVoltage(VOLTS volts);
|
||||
|
||||
#include "ClockedSerial.h"
|
||||
|
||||
#endif /* OSCR_H_ */
|
@ -70,7 +70,7 @@ static const char *const menuOptionspceTC[] PROGMEM = { pceTCMenuItem1, string_r
|
||||
|
||||
// PCE start menu
|
||||
void pcsMenu(void) {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// create menu with title and 3 options to choose from
|
||||
unsigned char pceDev;
|
||||
// Copy menuOptions out of progmem
|
||||
|
@ -141,7 +141,7 @@ static const char pcwmenuItem3[] PROGMEM = "Write SRAM";
|
||||
static const char* const menuOptionsPCW[] PROGMEM = { pcwmenuItem1, pcwmenuItem2, pcwmenuItem3, string_reset2 };
|
||||
|
||||
void pcwMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
convertPgm(menuOptionsPCW, 4);
|
||||
uint8_t mainMenu = question_box(F(" POCKET CHALLENGE W"), menuOptions, 4, 0);
|
||||
|
||||
|
@ -50,7 +50,7 @@ static const char sfmGameMenuItem4[] PROGMEM = "Switch Game";
|
||||
static const char* const menuOptionsSFMGame[] PROGMEM = { sfmGameMenuItem1, sfmGameMenuItem2, sfmGameMenuItem3, sfmGameMenuItem4, string_reset2 };
|
||||
|
||||
void sfmMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// create menu with title and 3 options to choose from
|
||||
unsigned char mainMenu;
|
||||
// Copy menuOptions out of progmem
|
||||
|
@ -40,7 +40,7 @@ static bool retron_mode = false;
|
||||
|
||||
|
||||
void _smsMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// create menu with title and n options to choose from
|
||||
unsigned char mainMenu;
|
||||
|
||||
|
@ -70,7 +70,7 @@ static const char* const menuOptionsRepro[] PROGMEM = { reproMenuItem1, reproMen
|
||||
|
||||
// SNES repro menu
|
||||
void reproMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// create menu with title and 6 options to choose from
|
||||
unsigned char snsRepro;
|
||||
// Copy menuOptions out of progmem
|
||||
@ -133,7 +133,7 @@ void reproMenu() {
|
||||
|
||||
// SNES start menu
|
||||
void snsMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// create menu with title and 6 options to choose from
|
||||
unsigned char snsCart;
|
||||
// Copy menuOptions out of progmem
|
||||
@ -192,7 +192,7 @@ void snsMenu() {
|
||||
|
||||
// SNES Menu
|
||||
void snesMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// create menu with title and 7 options to choose from
|
||||
unsigned char mainMenu;
|
||||
// Copy menuOptions out of progmem
|
||||
|
@ -17,7 +17,7 @@ static const char acanMenuItem6[] PROGMEM = "Flash repro";
|
||||
static const char *const menuOptionsAcan[] PROGMEM = { acanMenuItem1, acanMenuItem2, acanMenuItem3, acanMenuItem4, acanMenuItem5, string_reset2, acanMenuItem6 };
|
||||
|
||||
void setup_SuprAcan() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
|
||||
// addr as output
|
||||
DDRF = 0xff; // A0 - A7
|
||||
|
@ -42,7 +42,7 @@ static const char* const menuOptionsSVFlash[] PROGMEM = { svFlashMenuItem1, svFl
|
||||
|
||||
|
||||
void svMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
// create menu with title and 3 options to choose from
|
||||
unsigned char mainMenu;
|
||||
// Copy menuOptions out of progmem
|
||||
|
@ -101,7 +101,7 @@ static const char vboyMenuItem3[] PROGMEM = "Write SRAM";
|
||||
static const char* const menuOptionsVBOY[] PROGMEM = { vboyMenuItem1, vboyMenuItem2, vboyMenuItem3, string_reset2 };
|
||||
|
||||
void vboyMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
convertPgm(menuOptionsVBOY, 4);
|
||||
uint8_t mainMenu = question_box(F("VIRTUALBOY MENU"), menuOptions, 4, 0);
|
||||
|
||||
|
@ -117,7 +117,7 @@ boolean headerCheck() {
|
||||
}
|
||||
|
||||
void wsMenu() {
|
||||
vselect(true);
|
||||
setVoltage(VOLTS_SET_3V3);
|
||||
uint8_t mainMenu = (wsWitch ? 5 : 4);
|
||||
|
||||
convertPgm(menuOptionsWS, mainMenu);
|
||||
|
@ -106,7 +106,7 @@ static const char wsvMenuItem3[] PROGMEM = "Set Size";
|
||||
static const char* const menuOptionsSV[] PROGMEM = { wsvMenuItem1, wsvMenuItem2, wsvMenuItem3, string_reset2 };
|
||||
|
||||
void wsvMenu() {
|
||||
vselect(false);
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
convertPgm(menuOptionsSV, 4);
|
||||
uint8_t mainMenu = question_box(F("SUPERVISION MENU"), menuOptions, 4, 0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user