mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-27 15:04:15 +01:00
Stubs out Loopy menu item
This commit is contained in:
parent
3ad3ee0637
commit
d74ad957d8
@ -250,6 +250,7 @@ void print_STR(byte string_number, boolean newline) {
|
|||||||
#define mode_SUPRACAN 32
|
#define mode_SUPRACAN 32
|
||||||
#define mode_MSX 33
|
#define mode_MSX 33
|
||||||
#define mode_POKE 34
|
#define mode_POKE 34
|
||||||
|
#define mode_LOOPY 35
|
||||||
|
|
||||||
// optimization-safe nop delay
|
// optimization-safe nop delay
|
||||||
#define NOP __asm__ __volatile__("nop\n\t")
|
#define NOP __asm__ __volatile__("nop\n\t")
|
||||||
@ -840,11 +841,12 @@ static const char modeItem18[] PROGMEM = "Fairchild Channel F";
|
|||||||
static const char modeItem19[] PROGMEM = "Super A'can";
|
static const char modeItem19[] PROGMEM = "Super A'can";
|
||||||
static const char modeItem20[] PROGMEM = "MSX";
|
static const char modeItem20[] PROGMEM = "MSX";
|
||||||
static const char modeItem21[] PROGMEM = "Pokemon Mini (3V)";
|
static const char modeItem21[] PROGMEM = "Pokemon Mini (3V)";
|
||||||
static const char modeItem22[] PROGMEM = "Flashrom Programmer";
|
static const char modeItem22[] PROGMEM = "Casio Loopy";
|
||||||
static const char modeItem23[] PROGMEM = "Self Test (3V)";
|
static const char modeItem23[] PROGMEM = "Flashrom Programmer";
|
||||||
static const char modeItem24[] PROGMEM = "About";
|
static const char modeItem24[] PROGMEM = "Self Test (3V)";
|
||||||
|
static const char modeItem25[] PROGMEM = "About";
|
||||||
//static const char modeItem25[] PROGMEM = "Reset"; (stored in common strings array)
|
//static const char modeItem25[] 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, string_reset2 };
|
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 };
|
||||||
|
|
||||||
// All included slots
|
// All included slots
|
||||||
void mainMenu() {
|
void mainMenu() {
|
||||||
@ -1036,8 +1038,14 @@ void mainMenu() {
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef enable_FLASH
|
#ifdef enable_LOOPY
|
||||||
case 21:
|
case 21:
|
||||||
|
loopyMenu();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef enable_FLASH
|
||||||
|
case 22:
|
||||||
#ifdef ENABLE_VSELECT
|
#ifdef ENABLE_VSELECT
|
||||||
setup_FlashVoltage();
|
setup_FlashVoltage();
|
||||||
#endif
|
#endif
|
||||||
@ -1046,16 +1054,16 @@ void mainMenu() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef enable_selftest
|
#ifdef enable_selftest
|
||||||
case 22:
|
case 23:
|
||||||
selfTest();
|
selfTest();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 23:
|
case 24:
|
||||||
aboutScreen();
|
aboutScreen();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 24:
|
case 25:
|
||||||
resetArduino();
|
resetArduino();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1112,7 +1120,8 @@ static const char* const consoles80Options[] PROGMEM = { consoles80Item1, consol
|
|||||||
|
|
||||||
// 90s Consoles submenu
|
// 90s Consoles submenu
|
||||||
static const char consoles90Item1[] PROGMEM = "Super A'can";
|
static const char consoles90Item1[] PROGMEM = "Super A'can";
|
||||||
static const char* const consoles90Options[] PROGMEM = { consoles90Item1, string_reset2 };
|
static const char consoles90Item2[] PROGMEM = "Casio Loopy";
|
||||||
|
static const char* const consoles90Options[] PROGMEM = { consoles90Item1, consoles90Item2, string_reset2 };
|
||||||
|
|
||||||
// Handhelds submenu
|
// Handhelds submenu
|
||||||
static const char handheldsItem1[] PROGMEM = "Virtual Boy";
|
static const char handheldsItem1[] PROGMEM = "Virtual Boy";
|
||||||
@ -1353,7 +1362,13 @@ void consoles90Menu() {
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef enable_LOOPY
|
||||||
case 1:
|
case 1:
|
||||||
|
loopyMenu();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case 2:
|
||||||
resetArduino();
|
resetArduino();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
* Choose your hardware version:
|
* Choose your hardware version:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define HW5
|
#define HW5
|
||||||
//#define HW4
|
//#define HW4
|
||||||
//#define HW3
|
//#define HW3
|
||||||
//#define HW2
|
//#define HW2
|
||||||
@ -104,7 +104,7 @@
|
|||||||
/* [ Flashrom Programmer for SNES repros -------------------------- ]
|
/* [ Flashrom Programmer for SNES repros -------------------------- ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define enable_FLASH
|
//#define enable_FLASH
|
||||||
//#define enable_FLASH16
|
//#define enable_FLASH16
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
@ -133,14 +133,14 @@
|
|||||||
/* [ Nintendo 64 -------------------------------------------------- ]
|
/* [ Nintendo 64 -------------------------------------------------- ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define enable_N64
|
//#define enable_N64
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
/* [ Nintendo Entertainment System/Family Computer ---------------- ]
|
/* [ Nintendo Entertainment System/Family Computer ---------------- ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define enable_NES
|
//#define enable_NES
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
@ -175,35 +175,35 @@
|
|||||||
/* [ Sega Master System/Mark III/Game Gear/SG-1000 ---------------- ]
|
/* [ Sega Master System/Mark III/Game Gear/SG-1000 ---------------- ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define enable_SMS
|
//#define enable_SMS
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
/* [ Sega Mega Drive/Genesis -------------------------------------- ]
|
/* [ Sega Mega Drive/Genesis -------------------------------------- ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define enable_MD
|
//#define enable_MD
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
/* [ Super Famicom SF Memory Cassette ----------------------------- ]
|
/* [ Super Famicom SF Memory Cassette ----------------------------- ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define enable_SFM
|
//#define enable_SFM
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
/* [ Super Famicom Satellaview ------------------------------------ ]
|
/* [ Super Famicom Satellaview ------------------------------------ ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define enable_SV
|
//#define enable_SV
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
/* [ Super Nintendo ----------------------------------------------- ]
|
/* [ Super Nintendo ----------------------------------------------- ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define enable_SNES
|
//#define enable_SNES
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
@ -235,6 +235,13 @@
|
|||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
|
/* [ Casio Loopy -------------------------------------------------- ]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define enable_LOOPY
|
||||||
|
|
||||||
|
/****/
|
||||||
|
|
||||||
/*==== FIRMWARE OPTIONS ===========================================*/
|
/*==== FIRMWARE OPTIONS ===========================================*/
|
||||||
|
|
||||||
/* [ LCD: Background Color ---------------------------------------- ]
|
/* [ LCD: Background Color ---------------------------------------- ]
|
||||||
@ -244,7 +251,7 @@
|
|||||||
* Green, Red, Blue
|
* Green, Red, Blue
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define background_color 100, 0, 0
|
#define background_color 20, 100, 60
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
|
576
Cart_Reader/LOOPY.ino
Normal file
576
Cart_Reader/LOOPY.ino
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
//******************************************
|
||||||
|
// CASIO LOOPY MODULE
|
||||||
|
//******************************************
|
||||||
|
#ifdef enable_LOOPY
|
||||||
|
// TODO EVERYTHING
|
||||||
|
|
||||||
|
// Nintendo VirtualBoy
|
||||||
|
// Cartridge Pinout
|
||||||
|
// 60P 2.00mm pitch connector
|
||||||
|
//
|
||||||
|
// TOP SIDE BOTTOM SIDE
|
||||||
|
// +-------+
|
||||||
|
// GND -| 1 2 |- GND
|
||||||
|
// /WE0 (SRAM WRITE ENABLE) -| 3 4 |- nc
|
||||||
|
// nc -| 5 6 |- /CS1 (SRAM ENABLE)
|
||||||
|
// CS2 (SRAM) -| 7 8 |- VCC(+5V)
|
||||||
|
// nc -| 9 10 |- A23
|
||||||
|
// A19 -| 11 12 |- A22
|
||||||
|
// A18 -| 13 14 |- A21
|
||||||
|
// A8 -| 15 16 |- A20
|
||||||
|
// A7 -| 17 18 |- A9
|
||||||
|
// A6 -| 19 20 |- A10
|
||||||
|
// A5 -| 21 22 |- A11
|
||||||
|
// A4 -| 23 24 |- A12
|
||||||
|
// A3 -| 25 26 |- A13
|
||||||
|
// A2 -| 27 28 |- A14
|
||||||
|
// A1 -| 29 30 |- A15
|
||||||
|
// /CE (ROM) -| 31 32 |- A16
|
||||||
|
// GND -| 33 34 |- A17
|
||||||
|
// /OE -| 35 36 |- VCC(+5V)
|
||||||
|
// D8 -| 37 38 |- D7
|
||||||
|
// D0 -| 39 40 |- D15
|
||||||
|
// D9 -| 41 42 |- D6
|
||||||
|
// D1 -| 43 44 |- D14
|
||||||
|
// D10 -| 45 46 |- D5
|
||||||
|
// D2 -| 47 48 |- D13
|
||||||
|
// D11 -| 49 50 |- D4
|
||||||
|
// D3 -| 51 52 |- D12
|
||||||
|
// VCC(+5V) -| 53 54 |- VCC(+5V)
|
||||||
|
// nc -| 55 56 |- nc
|
||||||
|
// nc -| 57 58 |- nc
|
||||||
|
// GND -| 59 60 |- GND
|
||||||
|
// +-------+
|
||||||
|
//
|
||||||
|
|
||||||
|
// CONTROL PINS:
|
||||||
|
// CS2(SRAM) - (PH0) - VBOY PIN 7 - SNES RST
|
||||||
|
// /CE(ROM) - (PH3) - VBOY PIN 31 - SNES /CS
|
||||||
|
// /CS1(SRAM ENABLE) - (PH4) - VBOY PIN 6 - SNES /IRQ
|
||||||
|
// /WE0(SRAM WRITE ENABLE) - (PH5) - VBOY PIN 3 - SNES /WR
|
||||||
|
// /OE - (PH6) - VBOY PIN 35 - SNES /RD
|
||||||
|
|
||||||
|
// NOT CONNECTED:
|
||||||
|
// CLK(PH1) - N/C
|
||||||
|
|
||||||
|
//******************************************
|
||||||
|
// SETUP
|
||||||
|
//******************************************
|
||||||
|
|
||||||
|
void setup_LOOPY() {
|
||||||
|
// Request 5V
|
||||||
|
setVoltage(VOLTS_SET_5V);
|
||||||
|
|
||||||
|
// Set Address Pins to Output
|
||||||
|
//A0-A7
|
||||||
|
DDRF = 0xFF;
|
||||||
|
//A8-A15
|
||||||
|
DDRK = 0xFF;
|
||||||
|
//A16-A23
|
||||||
|
DDRL = 0xFF;
|
||||||
|
|
||||||
|
// Set Control Pins to Output
|
||||||
|
// CS2(PH0) ---(PH1) /CE(PH3) /CS1(PH4) /WE0(PH5) /OE(PH6)
|
||||||
|
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||||
|
|
||||||
|
// Set TIME(PJ0) to Output (UNUSED)
|
||||||
|
DDRJ |= (1 << 0);
|
||||||
|
|
||||||
|
// Set Pins (D0-D15) to Input
|
||||||
|
DDRC = 0x00;
|
||||||
|
DDRA = 0x00;
|
||||||
|
|
||||||
|
// Setting Control Pins to HIGH
|
||||||
|
// ---(PH1) /CE(PH3) /CS1(PH4) /WE0(PH5) /OE(PH6)
|
||||||
|
PORTH |= (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||||
|
// Set CS2(PH0) to LOW
|
||||||
|
PORTH &= ~(1 << 0);
|
||||||
|
|
||||||
|
// Set Unused Pins HIGH
|
||||||
|
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||||
|
|
||||||
|
getCartInfo_LOOPY();
|
||||||
|
|
||||||
|
mode = mode_LOOPY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************
|
||||||
|
// MENU
|
||||||
|
//******************************************
|
||||||
|
|
||||||
|
// Base Menu
|
||||||
|
static const char loopyMenuItem1[] PROGMEM = "Read ROM";
|
||||||
|
static const char loopyMenuItem2[] PROGMEM = "Read SRAM";
|
||||||
|
static const char loopyMenuItem3[] PROGMEM = "Write SRAM";
|
||||||
|
//static const char loopyMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
|
||||||
|
static const char* const menuOptionsLOOPY[] PROGMEM = { loopyMenuItem1, loopyMenuItem2, loopyMenuItem3, string_reset2 };
|
||||||
|
|
||||||
|
void loopyMenu() {
|
||||||
|
convertPgm(menuOptionsLOOPY, 4);
|
||||||
|
uint8_t mainMenu = question_box(F("CASIO LOOPY MENU"), menuOptions, 4, 0);
|
||||||
|
|
||||||
|
switch (mainMenu) {
|
||||||
|
case 0:
|
||||||
|
// Read ROM
|
||||||
|
sd.chdir("/");
|
||||||
|
readROM_LOOPY();
|
||||||
|
sd.chdir("/");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// Read SRAM
|
||||||
|
if (sramSize) {
|
||||||
|
sd.chdir("/");
|
||||||
|
display_Clear();
|
||||||
|
println_Msg(F("Reading SRAM..."));
|
||||||
|
display_Update();
|
||||||
|
readSRAM_LOOPY();
|
||||||
|
sd.chdir("/");
|
||||||
|
} else {
|
||||||
|
print_Error(F("Cart has no SRAM"));
|
||||||
|
}
|
||||||
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
|
// Wait for user input
|
||||||
|
// Prints string out of the common strings array either with or without newline
|
||||||
|
print_STR(press_button_STR, 1);
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
// Write SRAM
|
||||||
|
if (sramSize) {
|
||||||
|
// Change working dir to root
|
||||||
|
sd.chdir("/");
|
||||||
|
fileBrowser(F("Select SAV file"));
|
||||||
|
display_Clear();
|
||||||
|
writeSRAM_LOOPY();
|
||||||
|
writeErrors = verifySRAM_LOOPY();
|
||||||
|
if (writeErrors == 0) {
|
||||||
|
println_Msg(F("SRAM verified OK"));
|
||||||
|
display_Update();
|
||||||
|
} else {
|
||||||
|
print_STR(error_STR, 0);
|
||||||
|
print_Msg(writeErrors);
|
||||||
|
print_STR(_bytes_STR, 1);
|
||||||
|
print_Error(did_not_verify_STR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print_Error(F("Cart has no SRAM"));
|
||||||
|
}
|
||||||
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
|
// Wait for user input
|
||||||
|
// Prints string out of the common strings array either with or without newline
|
||||||
|
print_STR(press_button_STR, 1);
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
// reset
|
||||||
|
resetArduino();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************
|
||||||
|
// LOW LEVEL FUNCTIONS
|
||||||
|
//******************************************
|
||||||
|
|
||||||
|
void writeByte_LOOPY(unsigned long myAddress, byte myData) {
|
||||||
|
PORTF = myAddress & 0xFF;
|
||||||
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
|
PORTL = (myAddress >> 16) & 0xFF;
|
||||||
|
|
||||||
|
__asm__("nop\n\t");
|
||||||
|
|
||||||
|
PORTA = myData;
|
||||||
|
|
||||||
|
// Set CS2(PH0), /CE(PH3), /OE(PH6) to HIGH
|
||||||
|
PORTH |= (1 << 0) | (1 << 3) | (1 << 6);
|
||||||
|
// Set /CS1(PH4), /WE0(PH5) to LOW
|
||||||
|
PORTH &= ~(1 << 4) & ~(1 << 5);
|
||||||
|
|
||||||
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
|
// Set CS2(PH0), /CS1(PH4), /WE0(PH5) to HIGH
|
||||||
|
PORTH |= (1 << 0) | (1 << 4) | (1 << 5);
|
||||||
|
|
||||||
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
}
|
||||||
|
|
||||||
|
word readWord_LOOPY(unsigned long myAddress) {
|
||||||
|
PORTF = myAddress & 0xFF;
|
||||||
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
|
PORTL = (myAddress >> 16) & 0xFF;
|
||||||
|
|
||||||
|
__asm__("nop\n\t");
|
||||||
|
|
||||||
|
// Set CS2(PH0), /CS1(PH4), /WE0(PH5) to HIGH
|
||||||
|
PORTH |= (1 << 0) | (1 << 4) | (1 << 5);
|
||||||
|
// Set /CE(PH3), /OE(PH6) to LOW
|
||||||
|
PORTH &= ~(1 << 3) & ~(1 << 6);
|
||||||
|
|
||||||
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
|
word tempWord = ((PINA & 0xFF) << 8) | (PINC & 0xFF);
|
||||||
|
|
||||||
|
// Set /CE(PH3), /OE(PH6) to HIGH
|
||||||
|
PORTH |= (1 << 3) | (1 << 6);
|
||||||
|
// Setting CS2(PH0) LOW
|
||||||
|
PORTH &= ~(1 << 0);
|
||||||
|
|
||||||
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
|
return tempWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte readByte_LOOPY(unsigned long myAddress) { // SRAM BYTE
|
||||||
|
PORTF = myAddress & 0xFF;
|
||||||
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
|
PORTL = (myAddress >> 16) & 0xFF;
|
||||||
|
|
||||||
|
__asm__("nop\n\t");
|
||||||
|
|
||||||
|
// Set CS2(PH0), /CE(PH3), /WE0(PH5) to HIGH
|
||||||
|
PORTH |= (1 << 0) | (1 << 3) | (1 << 5);
|
||||||
|
// Set /CS1(PH4), /OE(PH6) to LOW
|
||||||
|
PORTH &= ~(1 << 4) & ~(1 << 6);
|
||||||
|
|
||||||
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
|
byte tempByte = PINA;
|
||||||
|
|
||||||
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
|
// Set /CS1(PH4), /OE(PH6) to HIGH
|
||||||
|
PORTH |= (1 << 3) | (1 << 6);
|
||||||
|
// Setting CS2(PH0) LOW
|
||||||
|
PORTH &= ~(1 << 0);
|
||||||
|
|
||||||
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
|
return tempByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch data pins to write
|
||||||
|
void dataOut_LOOPY() {
|
||||||
|
DDRC = 0xFF;
|
||||||
|
DDRA = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch data pins to read
|
||||||
|
void dataIn_LOOPY() {
|
||||||
|
DDRC = 0x00;
|
||||||
|
DDRA = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************
|
||||||
|
// CART INFO
|
||||||
|
//******************************************
|
||||||
|
|
||||||
|
void getCartInfo_LOOPY() {
|
||||||
|
// Set control
|
||||||
|
dataIn_LOOPY();
|
||||||
|
|
||||||
|
cartSize = 0;
|
||||||
|
for (unsigned long address = 0x80000; address <= 0x400000; address *= 2) {
|
||||||
|
// Get Serial
|
||||||
|
word vbSerial = readWord_LOOPY((address - 0x204) / 2); // Cart Serial
|
||||||
|
|
||||||
|
switch (vbSerial) {
|
||||||
|
case 0x4D54: // MT = Mario's Tennis
|
||||||
|
case 0x4832: // H2 = Panic Bomber/Tobidase! Panibomb
|
||||||
|
case 0x5350: // SP = Space Invaders
|
||||||
|
case 0x5353: // SS = Space Squash
|
||||||
|
case 0x5452: // TR = V-Tetris
|
||||||
|
cartSize = 0x80000; // 512KB
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x494D: // IM = Insmouse no Yakata
|
||||||
|
case 0x4A42: // JB = Jack Bros.
|
||||||
|
case 0x4D43: // MC = Mario Clash
|
||||||
|
case 0x5245: // RE = Red Alarm
|
||||||
|
case 0x4833: // H3 = Vertical Force
|
||||||
|
case 0x5642: // VB = Virtual Bowling
|
||||||
|
case 0x4A56: // JV = Virtual Lab
|
||||||
|
case 0x5650: // VP = Virtual League Baseball/Virtual Pro Yakyuu '95
|
||||||
|
cartSize = 0x100000; // 1MB
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5042: // PB = 3-D Tetris
|
||||||
|
case 0x4750: // GP = Galactic Pinball
|
||||||
|
case 0x5344: // SD = SD Gundam Dimension War
|
||||||
|
case 0x5442: // TB = Teleroboxer
|
||||||
|
case 0x5646: // VF = Virtual Fishing
|
||||||
|
cartSize = 0x100000; // 1MB
|
||||||
|
sramSize = 0x2000; // 8KB
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5647: // VG = Golf/T&E Virtual Golf
|
||||||
|
case 0x4E46: // NF = Nester's Funky Bowling
|
||||||
|
case 0x5745: // WE = Waterworld
|
||||||
|
cartSize = 0x200000; // 2MB
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5743: // WC = Virtual Boy Wario Land
|
||||||
|
cartSize = 0x200000; // 2MB
|
||||||
|
sramSize = 0x2000; // 8KB
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4644: // FD = Hyper Fighting
|
||||||
|
cartSize = 0x400000; // 4MB
|
||||||
|
sramSize = 0x2000; // 8KB
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cartSize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get name
|
||||||
|
for (byte c = 0; c < 20; c += 2) {
|
||||||
|
// split word
|
||||||
|
word myWord = readWord_LOOPY((cartSize - 0x220 + c) / 2);
|
||||||
|
byte loByte = myWord & 0xFF;
|
||||||
|
byte hiByte = myWord >> 8;
|
||||||
|
|
||||||
|
// write to buffer
|
||||||
|
sdBuffer[c] = hiByte;
|
||||||
|
sdBuffer[c + 1] = loByte;
|
||||||
|
}
|
||||||
|
byte myLength = 0;
|
||||||
|
for (unsigned int i = 0; i < 20; i++) {
|
||||||
|
if (((char(sdBuffer[i]) >= 48 && char(sdBuffer[i]) <= 57) || (char(sdBuffer[i]) >= 65 && char(sdBuffer[i]) <= 122)) && myLength < 15) {
|
||||||
|
romName[myLength] = char(sdBuffer[i]);
|
||||||
|
myLength++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display_Clear();
|
||||||
|
println_Msg(F("Cart Info"));
|
||||||
|
println_Msg(F(" "));
|
||||||
|
print_Msg(F("Name: "));
|
||||||
|
println_Msg(romName);
|
||||||
|
print_Msg(F("Size: "));
|
||||||
|
print_Msg(cartSize * 8 / 1024 / 1024);
|
||||||
|
println_Msg(F(" MBit"));
|
||||||
|
print_Msg(F("Sram: "));
|
||||||
|
if (sramSize > 0) {
|
||||||
|
print_Msg(sramSize * 8 / 1024);
|
||||||
|
println_Msg(F(" KBit"));
|
||||||
|
} else
|
||||||
|
println_Msg(F("None"));
|
||||||
|
println_Msg(F(" "));
|
||||||
|
|
||||||
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
|
// Wait for user input
|
||||||
|
// Prints string out of the common strings array either with or without newline
|
||||||
|
print_STR(press_button_STR, 1);
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************
|
||||||
|
// READ CODE
|
||||||
|
//******************************************
|
||||||
|
|
||||||
|
void readROM_LOOPY() {
|
||||||
|
dataIn_LOOPY();
|
||||||
|
|
||||||
|
strcpy(fileName, romName);
|
||||||
|
strcat(fileName, ".vb");
|
||||||
|
|
||||||
|
EEPROM_readAnything(0, foldern);
|
||||||
|
sprintf(folder, "LOOPY/ROM/%s/%d", romName, foldern);
|
||||||
|
sd.mkdir(folder, true);
|
||||||
|
sd.chdir(folder);
|
||||||
|
|
||||||
|
display_Clear();
|
||||||
|
print_STR(saving_to_STR, 0);
|
||||||
|
print_Msg(folder);
|
||||||
|
println_Msg(F("/..."));
|
||||||
|
display_Update();
|
||||||
|
|
||||||
|
foldern = foldern + 1;
|
||||||
|
EEPROM_writeAnything(0, foldern);
|
||||||
|
|
||||||
|
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||||
|
print_FatalError(sd_error_STR);
|
||||||
|
}
|
||||||
|
|
||||||
|
word d = 0;
|
||||||
|
uint32_t progress = 0;
|
||||||
|
draw_progressbar(0, cartSize);
|
||||||
|
// HYPER FIGHTING FIX
|
||||||
|
// VIRTUAL BOY ADDRESSING IS TOP DOWN
|
||||||
|
// ONLY FOR HYPER FIGHTING PLUGIN WITH ALL ADDRESS LINES CONNECTED
|
||||||
|
// NORMAL PLUGIN DOES NOT HAVE THE UPPER ADDRESS LINES CONNECTED
|
||||||
|
if (cartSize == 0x400000) {
|
||||||
|
unsigned long romData = 0x1000000 - (cartSize / 2);
|
||||||
|
for (unsigned long currBuffer = romData; currBuffer < 0x1000000; currBuffer += 256) {
|
||||||
|
for (int currWord = 0; currWord < 256; currWord++) {
|
||||||
|
word myWord = readWord_LOOPY(currBuffer + currWord);
|
||||||
|
// Split word into two bytes
|
||||||
|
sdBuffer[d] = ((myWord >> 8) & 0xFF);
|
||||||
|
sdBuffer[d + 1] = (myWord & 0xFF);
|
||||||
|
d += 2;
|
||||||
|
}
|
||||||
|
myFile.write(sdBuffer, 512);
|
||||||
|
d = 0;
|
||||||
|
progress += 512;
|
||||||
|
draw_progressbar(progress, cartSize);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (unsigned long currBuffer = 0; currBuffer < cartSize / 2; currBuffer += 256) {
|
||||||
|
for (int currWord = 0; currWord < 256; currWord++) {
|
||||||
|
word myWord = readWord_LOOPY(currBuffer + currWord);
|
||||||
|
// Split word into two bytes
|
||||||
|
sdBuffer[d] = ((myWord >> 8) & 0xFF);
|
||||||
|
sdBuffer[d + 1] = (myWord & 0xFF);
|
||||||
|
d += 2;
|
||||||
|
}
|
||||||
|
myFile.write(sdBuffer, 512);
|
||||||
|
d = 0;
|
||||||
|
progress += 512;
|
||||||
|
draw_progressbar(progress, cartSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myFile.close();
|
||||||
|
|
||||||
|
// Compare CRC32 to database and rename ROM if found
|
||||||
|
// Arguments: database name, precalculated crc string or 0 to calculate, rename rom or not, starting offset
|
||||||
|
compareCRC("vb.txt", 0, 1, 0);
|
||||||
|
|
||||||
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
|
// Wait for user input
|
||||||
|
println_Msg(F(""));
|
||||||
|
// Prints string out of the common strings array either with or without newline
|
||||||
|
print_STR(press_button_STR, 1);
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************
|
||||||
|
// SRAM
|
||||||
|
//******************************************
|
||||||
|
|
||||||
|
void writeSRAM_LOOPY() {
|
||||||
|
dataOut_LOOPY();
|
||||||
|
|
||||||
|
sprintf(filePath, "%s/%s", filePath, fileName);
|
||||||
|
println_Msg(F("Writing..."));
|
||||||
|
println_Msg(filePath);
|
||||||
|
display_Update();
|
||||||
|
|
||||||
|
if (myFile.open(filePath, O_READ)) {
|
||||||
|
for (unsigned long currByte = 0; currByte < sramSize; currByte++) {
|
||||||
|
// writeWord_LOOPY(currByte, ((myFile.read() << 8 ) & 0xFF));
|
||||||
|
writeByte_LOOPY(currByte, (myFile.read()));
|
||||||
|
}
|
||||||
|
myFile.close();
|
||||||
|
print_STR(done_STR, 1);
|
||||||
|
display_Update();
|
||||||
|
} else {
|
||||||
|
print_FatalError(sd_error_STR);
|
||||||
|
}
|
||||||
|
dataIn_LOOPY();
|
||||||
|
}
|
||||||
|
|
||||||
|
void readSRAM_LOOPY() {
|
||||||
|
dataIn_LOOPY();
|
||||||
|
|
||||||
|
strcpy(fileName, romName);
|
||||||
|
strcat(fileName, ".sav");
|
||||||
|
|
||||||
|
EEPROM_readAnything(0, foldern);
|
||||||
|
sprintf(folder, "LOOPY/SAVE/%s/%d", romName, foldern);
|
||||||
|
sd.mkdir(folder, true);
|
||||||
|
sd.chdir(folder);
|
||||||
|
|
||||||
|
foldern = foldern + 1;
|
||||||
|
EEPROM_writeAnything(0, foldern);
|
||||||
|
|
||||||
|
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||||
|
print_FatalError(sd_error_STR);
|
||||||
|
}
|
||||||
|
for (unsigned long currBuffer = 0; currBuffer < sramSize; currBuffer += 512) {
|
||||||
|
for (int currByte = 0; currByte < 512; currByte++) {
|
||||||
|
byte myByte = readByte_LOOPY(currBuffer + currByte);
|
||||||
|
sdBuffer[currByte] = myByte;
|
||||||
|
}
|
||||||
|
myFile.write(sdBuffer, 512);
|
||||||
|
}
|
||||||
|
myFile.close();
|
||||||
|
print_Msg(F("Saved to "));
|
||||||
|
print_Msg(folder);
|
||||||
|
println_Msg(F("/"));
|
||||||
|
display_Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long verifySRAM_LOOPY() {
|
||||||
|
dataIn_LOOPY();
|
||||||
|
writeErrors = 0;
|
||||||
|
|
||||||
|
if (myFile.open(filePath, O_READ)) {
|
||||||
|
for (unsigned long currBuffer = 0; currBuffer < sramSize; currBuffer += 512) {
|
||||||
|
for (int currByte = 0; currByte < 512; currByte++) {
|
||||||
|
byte myByte = readByte_LOOPY(currBuffer + currByte);
|
||||||
|
sdBuffer[currByte] = myByte;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 512; i++) {
|
||||||
|
if (myFile.read() != sdBuffer[i]) {
|
||||||
|
writeErrors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myFile.close();
|
||||||
|
} else {
|
||||||
|
print_FatalError(sd_error_STR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeErrors;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//******************************************
|
||||||
|
// End of File
|
||||||
|
//******************************************
|
Loading…
Reference in New Issue
Block a user