mirror of
https://github.com/sanni/cartreader.git
synced 2024-06-03 02:48:43 +02:00
Compare commits
138 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2b01f7fc4d | ||
|
740c2698bc | ||
|
ad69abdf57 | ||
|
22e06d8ec1 | ||
|
fb78a1fce5 | ||
|
86059ae070 | ||
|
5b43a162b8 | ||
|
d039c590cc | ||
|
0d9596eb70 | ||
|
cb111077f8 | ||
|
363d18b542 | ||
|
78bf1462d0 | ||
|
41182a7eb0 | ||
|
6abe29fcd9 | ||
|
d1d83bbd10 | ||
|
73700e2886 | ||
|
1aaa90af97 | ||
|
4d000418a8 | ||
|
aaaa6ea3cd | ||
|
a32c6b3bff | ||
|
f82be2d5db | ||
|
d7e795fbed | ||
|
ea0b47de57 | ||
|
9f0aa09197 | ||
|
38b2b2476b | ||
|
dc47202c4d | ||
|
a8cd9c52a6 | ||
|
32f6b4151b | ||
|
c09e772299 | ||
|
7ba32d24fc | ||
|
74352c6e31 | ||
|
ab03ab879c | ||
|
90fa37c491 | ||
|
9e2ef3580c | ||
|
94c6bd460a | ||
|
40238b18a1 | ||
|
8bd6d7dfdc | ||
|
53b71f9108 | ||
|
825a5fe7b6 | ||
|
2c72652671 | ||
|
f4ba8d7af8 | ||
|
2134c9f58b | ||
|
4b70766094 | ||
|
5f3d63a123 | ||
|
990b61ca3a | ||
|
e8e6d15a72 | ||
|
6c05709871 | ||
|
330e615b8c | ||
|
2826ded431 | ||
|
d233387acc | ||
|
254982cbe7 | ||
|
ccc06ef4e4 | ||
|
d7c1afd57c | ||
|
bb12c99fac | ||
|
ecc937bab3 | ||
|
14c3ca2a83 | ||
|
9909fdafb3 | ||
|
06d5f28d0c | ||
|
38f3ebdc8d | ||
|
c3c701cd93 | ||
|
c5c82d4902 | ||
|
fa90691f89 | ||
|
82173ab775 | ||
|
394dcdcf1f | ||
|
254c824292 | ||
|
9f51bb1af7 | ||
|
43e18fce80 | ||
|
a539f9b7de | ||
|
57bf121c06 | ||
|
d2fbb30b95 | ||
|
15c94c110b | ||
|
3ff99bfe48 | ||
|
4502d1e56e | ||
|
d8809b198d | ||
|
3ce23a57ad | ||
|
3441cedfd4 | ||
|
50a147bad7 | ||
|
e7e0da80b0 | ||
|
5d0ae986c9 | ||
|
5a79277a27 | ||
|
ea3adb09bc | ||
|
8b617851a1 | ||
|
dc1e776b19 | ||
|
4c8f8266a1 | ||
|
7fc0f9b154 | ||
|
8458fe6bf7 | ||
|
017da53f42 | ||
|
083182b5fb | ||
|
e1716d48bb | ||
|
cf1d01855d | ||
|
8afd2a580e | ||
|
8fbab1e760 | ||
|
980208e18f | ||
|
229b1ba544 | ||
|
baa7dce0c1 | ||
|
9ad338a821 | ||
|
316f8ef2fd | ||
|
a2924e4f58 | ||
|
385b6b03f4 | ||
|
281639370f | ||
|
d79357d963 | ||
|
44b26960f5 | ||
|
a455b10019 | ||
|
6d89a279f2 | ||
|
4de1c52798 | ||
|
a86f140198 | ||
|
e61ac414d8 | ||
|
3468703a51 | ||
|
35eca2a9f4 | ||
|
f947fb4e3f | ||
|
5f3983b36c | ||
|
ddd8b94bd7 | ||
|
d007c455e7 | ||
|
417e88d7d1 | ||
|
7e2e2a6bf2 | ||
|
f762f29ee4 | ||
|
bbe37d9839 | ||
|
e4e4c7f1f5 | ||
|
24b7c2f2e1 | ||
|
d556e5a4af | ||
|
a8b493026e | ||
|
a9bccaf8f7 | ||
|
2bdba9c8bd | ||
|
c06f1c4e95 | ||
|
5e7861be1c | ||
|
1b70d71518 | ||
|
8ee28d55f4 | ||
|
272c2935e5 | ||
|
319d110339 | ||
|
107dd9f1d7 | ||
|
3a965600cc | ||
|
7078adcd22 | ||
|
dece32c130 | ||
|
3d810823e1 | ||
|
d0fe5c8ca1 | ||
|
70d52636d7 | ||
|
0287ea8ed2 | ||
|
f86a861628 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -47,4 +47,4 @@ jobs:
|
|||
cd Cart_Reader/
|
||||
# Select hardware version by uncommenting it (using regular expression)
|
||||
sed -i 's/^\/\/[\t ]*#define ${{ matrix.hwVersion }}/#define ${{ matrix.hwVersion }}/g' Config.h
|
||||
arduino-cli compile --fqbn arduino:avr:mega --warnings all
|
||||
arduino-cli compile --fqbn arduino:avr:mega --warnings all --build-property compiler.cpp.extra_flags="-DGITHUB_CI"
|
||||
|
|
729
Cart_Reader/2600.ino
Normal file
729
Cart_Reader/2600.ino
Normal file
|
@ -0,0 +1,729 @@
|
|||
//******************************************
|
||||
// ATARI 2600 MODULE
|
||||
//******************************************
|
||||
#if defined(ENABLE_2600)
|
||||
// Atari 2600
|
||||
// Cartridge Pinout
|
||||
// 24P 2.54mm pitch connector
|
||||
//
|
||||
// LABEL SIDE
|
||||
//
|
||||
// GND +5V A8 A9 A11 A10 A12 D7 D6 D5 D4 D3
|
||||
// +--------------------------------------------------+
|
||||
// | 24 23 22 21 20 19 18 17 16 15 14 13 |
|
||||
// LEFT | | RIGHT
|
||||
// | 1 2 3 4 5 6 7 8 9 10 11 12 |
|
||||
// +--------------------------------------------------+
|
||||
// A7 A6 A5 A4 A3 A2 A1 A0 D0 D1 D2 GND
|
||||
//
|
||||
// BOTTOM SIDE
|
||||
|
||||
// Cart Configurations
|
||||
// Format = {mapper,romsize}
|
||||
static const byte PROGMEM a2600mapsize[] = {
|
||||
0x04, 5, // Atari 32K with RAM (F4SC)
|
||||
0x06, 4, // Atari 16K with RAM (F6SC)
|
||||
0x08, 2, // Atari 8K with RAM (F8SC)
|
||||
0x20, 0, // 2K
|
||||
0x3F, 2, // Tigervision 8K
|
||||
0x40, 1, // 4K [DEFAULT]
|
||||
0xC0, 0, // "CV" Commavid 2K
|
||||
0xD0, 2, // "DPC" Pitfall II 10K
|
||||
0xE0, 2, // Parker Bros 8K
|
||||
0xE7, 4, // M-Network 16K
|
||||
0xF0, 6, // Megaboy 64K
|
||||
0xF4, 5, // Atari 32K
|
||||
0xF6, 4, // Atari 16K
|
||||
0xF8, 2, // Atari 8K
|
||||
0xFA, 3, // CBS RAM Plus 12K
|
||||
0xFE, 2, // Activision 8K
|
||||
0xF9, 2, // "TP" Time Pilot 8K
|
||||
0x0A, 2, // "UA" UA Ltd 8K
|
||||
0x3E, 5, // Tigervision 32K with 32K RAM
|
||||
0x07, 6, // X07 64K ROM
|
||||
};
|
||||
|
||||
byte a2600mapcount = (sizeof(a2600mapsize) / sizeof(a2600mapsize[0])) / 2;
|
||||
byte a2600mapselect;
|
||||
int a2600index;
|
||||
|
||||
byte a2600[] = { 2, 4, 8, 12, 16, 32, 64 };
|
||||
byte a2600mapper = 0;
|
||||
byte a2600size;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 07 MAPPER
|
||||
// 08 ROM SIZE
|
||||
|
||||
//******************************************
|
||||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char a2600MenuItem3[] PROGMEM = "Set Mapper";
|
||||
static const char* const menuOptions2600[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, a2600MenuItem3, FSTRING_RESET };
|
||||
|
||||
void setup_2600() {
|
||||
// Request 5V
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
|
||||
// Set Address Pins to Output
|
||||
// Atari 2600 uses A0-A12 [A13-A23 UNUSED]
|
||||
//A0-A7
|
||||
DDRF = 0xFF;
|
||||
//A8-A15
|
||||
DDRK = 0xFF;
|
||||
//A16-A23
|
||||
DDRL = 0xFF;
|
||||
|
||||
// Set Control Pins to Output [UNUSED]
|
||||
// ---(PH0) ---(PH1) ---(PH3) ---(PH4) ---(PH5) ---(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-D7) to Input
|
||||
DDRC = 0x00;
|
||||
|
||||
// Setting Control Pins to HIGH [UNUSED]
|
||||
// ---(PH0) ---(PH1) ---(PH3) ---(PH4) ---(PH5) ---(PH6)
|
||||
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set Unused Data Pins (PA0-PA7) to Output
|
||||
DDRA = 0xFF;
|
||||
|
||||
// Set Unused Pins HIGH
|
||||
PORTA = 0xFF;
|
||||
PORTL = 0xFF; // A16-A23
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
|
||||
checkStatus_2600();
|
||||
strcpy(romName, "ATARI");
|
||||
|
||||
mode = CORE_2600;
|
||||
}
|
||||
|
||||
void a2600Menu() {
|
||||
convertPgm(menuOptions2600, 4);
|
||||
uint8_t mainMenu = question_box(F("ATARI 2600 MENU"), menuOptions, 4, 0);
|
||||
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
// Select Cart
|
||||
setCart_2600();
|
||||
setup_2600();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Read ROM
|
||||
sd.chdir("/");
|
||||
readROM_2600();
|
||||
sd.chdir("/");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Set Mapper
|
||||
setMapper_2600();
|
||||
checkStatus_2600();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// reset
|
||||
resetArduino();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// READ CODE
|
||||
//******************************************
|
||||
|
||||
uint8_t readData_2600(uint16_t addr) // Add Input Pullup
|
||||
{
|
||||
PORTF = addr & 0xFF; // A0-A7
|
||||
PORTK = (addr >> 8) & 0xFF; // A8-A12
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
DDRC = 0x00; // Set to Input
|
||||
PORTC = 0xFF; // Input Pullup
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
uint8_t ret = PINC;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void readSegment_2600(uint16_t startaddr, uint16_t endaddr) {
|
||||
for (uint16_t addr = startaddr; addr < endaddr; addr += 512) {
|
||||
readDataArray_2600(addr, 512);
|
||||
}
|
||||
}
|
||||
|
||||
void readDataArray_2600(uint16_t addr, uint16_t size) {
|
||||
for (uint16_t w = 0; w < size; w++) {
|
||||
sdBuffer[w] = readData_2600(addr + w);
|
||||
}
|
||||
myFile.write(sdBuffer, size);
|
||||
}
|
||||
|
||||
void readSegmentF8_2600(uint16_t startaddr, uint16_t endaddr, uint16_t bankaddr) {
|
||||
for (uint16_t addr = startaddr; addr < endaddr; addr += 512) {
|
||||
for (uint16_t w = 0; w < 512; w++) {
|
||||
if (addr > 0x1FF9) // SET BANK ADDRESS FOR 0x1FFA-0x1FFF
|
||||
readData_2600(bankaddr);
|
||||
uint8_t temp = readData_2600(addr + w);
|
||||
sdBuffer[w] = temp;
|
||||
}
|
||||
myFile.write(sdBuffer, 512);
|
||||
}
|
||||
}
|
||||
|
||||
void readSegmentE7_2600(uint8_t start, uint8_t end) {
|
||||
for (uint8_t x = start; x <= end; x++) {
|
||||
readData_2600(0x1FE0 + x);
|
||||
readSegment_2600(0x1000, 0x1800);
|
||||
}
|
||||
}
|
||||
|
||||
void readSegmentFx_2600(bool hasRAM, uint16_t size) {
|
||||
if(hasRAM) {
|
||||
outputFF_2600(0x100); // Skip 0x1000-0x10FF RAM
|
||||
readDataArray_2600(0x1100, 0x100);
|
||||
} else {
|
||||
readSegment_2600(0x1000, 0x1200);
|
||||
}
|
||||
readSegment_2600(0x1200, 0x1E00);
|
||||
// Split Read of Last 0x200 bytes
|
||||
readDataArray_2600(0x1E00, size);
|
||||
}
|
||||
|
||||
void readSegmentTigervision_2600(uint8_t banks) {
|
||||
for (uint8_t x = 0; x < banks; x++) {
|
||||
writeData3F_2600(0x3F, x);
|
||||
readSegment_2600(0x1000, 0x1800);
|
||||
}
|
||||
readSegment_2600(0x1800, 0x2000);
|
||||
}
|
||||
|
||||
void outputFF_2600(uint16_t size) {
|
||||
memset(sdBuffer, 0xFF, size * sizeof(sdBuffer[0]));
|
||||
myFile.write(sdBuffer, size);
|
||||
}
|
||||
|
||||
void writeData_2600(uint16_t addr, uint8_t data) {
|
||||
PORTF = addr & 0xFF; // A0-A7
|
||||
PORTK = (addr >> 8) & 0xFF; // A8-A12
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
DDRC = 0xFF; // Set to Output
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
PORTC = data;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
DDRC = 0x00; // Reset to Input
|
||||
}
|
||||
|
||||
void writeData3F_2600(uint16_t addr, uint8_t data) {
|
||||
PORTF = addr & 0xFF; // A0-A7
|
||||
PORTK = (addr >> 8) & 0xFF; // A8-A12
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
DDRC = 0xFF; // Set to Output
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
PORTC = data;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
// Address (0x1000);
|
||||
PORTF = 0x00; // A0-A7
|
||||
PORTK = 0x10; // A8-A12
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
DDRC = 0x00; // Reset to Input
|
||||
}
|
||||
|
||||
// E7 Mapper Check - Check Bank for FFs
|
||||
boolean checkE7(uint16_t bank) {
|
||||
writeData_2600(0x1800, 0xFF);
|
||||
readData_2600(0x1FE0 + bank);
|
||||
uint32_t testdata = (readData_2600(0x1000) << 24) | (readData_2600(0x1001) << 16) | (readData_2600(0x1002) << 8) | (readData_2600(0x1003));
|
||||
return (testdata == 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void readROM_2600() {
|
||||
createFolderAndOpenFile("ATARI", "ROM", romName, "a26");
|
||||
|
||||
// ROM Start 0xF000
|
||||
// Address A12-A0 = 0x1000 = 1 0000 0000 0000 = 4KB
|
||||
// Read Start 0x1000
|
||||
|
||||
switch (a2600mapper) {
|
||||
case 0x20: // 2K Standard 2KB
|
||||
readSegment_2600(0x1000, 0x1800);
|
||||
break;
|
||||
|
||||
case 0x3F: // 3F Mapper 8KB
|
||||
readSegmentTigervision_2600(3);
|
||||
break;
|
||||
|
||||
case 0x3E: // 3E Mapper 32KB ROM 32K RAM
|
||||
readSegmentTigervision_2600(15);
|
||||
break;
|
||||
|
||||
case 0x40: // 4K Default 4KB
|
||||
readSegment_2600(0x1000, 0x2000);
|
||||
break;
|
||||
|
||||
case 0xC0: // CV Mapper 2KB
|
||||
readSegment_2600(0x1800, 0x2000);
|
||||
break;
|
||||
|
||||
case 0xD0: // DPC Mapper 10KB
|
||||
// 8K ROM
|
||||
for (int x = 0; x < 0x2; x++) {
|
||||
readData_2600(0x1FF8 + x);
|
||||
// Split Read of 1st 0x200 bytes
|
||||
// 0x0000-0x0080 are DPC Registers (Random on boot)
|
||||
outputFF_2600(0x80); // Output 0xFFs for Registers
|
||||
readDataArray_2600(0x1080, 0x180);
|
||||
// Read Segment
|
||||
readSegment_2600(0x1200, 0x1800);
|
||||
// 0x1000-0x1080 are DPC Registers (Random on boot)
|
||||
outputFF_2600(0x80); // Output 0xFFs for Registers
|
||||
readDataArray_2600(0x1880, 0x180);
|
||||
// Read Segment
|
||||
readSegment_2600(0x1A00, 0x1E00);
|
||||
// Split Read of Last 0x200 bytes
|
||||
readDataArray_2600(0x1E00, 0x1F8);
|
||||
for (int z = 0; z < 8; z++) {
|
||||
// Set Bank to ensure 0x1FFA-0x1FFF is correct
|
||||
readData_2600(0x1FF8 + x);
|
||||
sdBuffer[z] = readData_2600(0x1FF8 + z);
|
||||
}
|
||||
myFile.write(sdBuffer, 8);
|
||||
}
|
||||
|
||||
// 2K DPC Internal Graphics ROM
|
||||
// Read Registers 0x1008-0x100F (Graphics 0x1008-0x100C)
|
||||
// Write Registers LSB 0x1050-0x1057 AND MSB 0x1058-0x105F
|
||||
|
||||
// Set Data Fetcher 0 Limits
|
||||
writeData_2600(0x1040, 0xFF); // MAX for Data Fetcher 0
|
||||
writeData_2600(0x1048, 0x00); // MIN for Data Fetcher 0
|
||||
// Set Data Fetcher 0 Counter (0x7FF)
|
||||
writeData_2600(0x1050, 0xFF); // LSB for Data Fetcher 0
|
||||
writeData_2600(0x1058, 0x07); // MSB for Data Fetcher 0
|
||||
// Set Data Fetcher 1 Counter (0x7FF)
|
||||
writeData_2600(0x1051, 0xFF); // LSB for Data Fetcher 1
|
||||
writeData_2600(0x1059, 0x07); // MSB for Data Fetcher 1
|
||||
for (int x = 0; x < 0x800; x += 512) {
|
||||
for (int y = 0; y < 512; y++) {
|
||||
sdBuffer[y] = readData_2600(0x1008); // Data Fetcher 0
|
||||
readData_2600(0x1009); // Data Fetcher 1
|
||||
}
|
||||
myFile.write(sdBuffer, 512);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE0: // E0 Mapper 8KB
|
||||
for (int x = 0; x < 0x7; x++) {
|
||||
readData_2600(0x1FE0 + x);
|
||||
readSegment_2600(0x1000, 0x1400);
|
||||
}
|
||||
readSegment_2600(0x1C00, 0x2000);
|
||||
break;
|
||||
|
||||
case 0xE7: // E7 Mapper 8KB/12KB/16KB
|
||||
writeData_2600(0x1800, 0xFF);
|
||||
// Check Bank 0 - If 0xFFs then Bump 'n' Jump
|
||||
if (checkE7(0)) { // Bump 'n' Jump 8K
|
||||
readSegmentE7_2600(4, 6); // Banks 4-6
|
||||
}
|
||||
// Check Bank 3 - If 0xFFs then BurgerTime
|
||||
else if (checkE7(3)) { // BurgerTime 12K
|
||||
readSegmentE7_2600(0, 1); // Banks 0+1
|
||||
readSegmentE7_2600(4, 6); // Banks 4-6
|
||||
}
|
||||
else { // Masters of the Universe (or Unknown Cart) 16K
|
||||
readSegmentE7_2600(0, 6); // Banks 0-6
|
||||
}
|
||||
readSegment_2600(0x1800, 0x2000); // Bank 7
|
||||
break;
|
||||
|
||||
case 0xF0: // F0 Mapper 64KB
|
||||
for (int x = 0; x < 0x10; x++) {
|
||||
readData_2600(0x1FF0);
|
||||
readSegment_2600(0x1000, 0x2000);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x04: // F4SC Mapper 32KB \w RAM
|
||||
case 0xF4: // F4 Mapper 32KB
|
||||
for (int x = 0; x < 8; x++) {
|
||||
readData_2600(0x1FF4 + x);
|
||||
readSegmentFx_2600(a2600mapper == 0x04, 0x1F4);
|
||||
for (int z = 0; z < 12; z++) {
|
||||
// Set Bank to ensure 0x1FFC-0x1FFF is correct
|
||||
readData_2600(0x1FF4 + x);
|
||||
sdBuffer[z] = readData_2600(0x1FF4 + z);
|
||||
}
|
||||
myFile.write(sdBuffer, 12);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06: // F6SC Mapper 16KB \w RAM
|
||||
case 0xF6: // F6 Mapper 16KB
|
||||
for (int w = 0; w < 4; w++) {
|
||||
readData_2600(0x1FF6 + w);
|
||||
readSegmentFx_2600(a2600mapper == 0x06, 0x1F6);
|
||||
// Bank Registers 0x1FF6-0x1FF9
|
||||
for (int y = 0; y < 4; y++){
|
||||
readData_2600(0x1FFF); // Reset Bank
|
||||
sdBuffer[y] = readData_2600(0x1FF6 + y);
|
||||
}
|
||||
// End of Bank 0x1FFA-0x1FFF
|
||||
readData_2600(0x1FFF); // Reset Bank
|
||||
readData_2600(0x1FF6 + w); // Set Bank
|
||||
for (int z = 4; z < 10; z++) {
|
||||
sdBuffer[z] = readData_2600(0x1FF6 + z); // 0x1FFA-0x1FFF
|
||||
}
|
||||
myFile.write(sdBuffer, 10);
|
||||
}
|
||||
readData_2600(0x1FFF); // Reset Bank
|
||||
break;
|
||||
|
||||
case 0x08: // F8SC Mapper 8KB \w RAM
|
||||
case 0xF8: // F8 Mapper 8KB
|
||||
for (int w = 0; w < 2; w++) {
|
||||
readData_2600(0x1FF8 + w);
|
||||
readSegmentFx_2600(a2600mapper == 0x08, 0x1F8);
|
||||
// Bank Registers 0x1FF8-0x1FF9
|
||||
for (int y = 0; y < 2; y++){
|
||||
readData_2600(0x1FFF); // Reset Bank
|
||||
sdBuffer[y] = readData_2600(0x1FF8 + y);
|
||||
}
|
||||
// End of Bank 0x1FFA-0x1FFF
|
||||
readData_2600(0x1FFF); // Reset Bank
|
||||
readData_2600(0x1FF8 + w); // Set Bank
|
||||
for (int z = 2; z < 8; z++) {
|
||||
sdBuffer[z] = readData_2600(0x1FF8 + z); // 0x1FFA-0x1FFF
|
||||
}
|
||||
myFile.write(sdBuffer, 8);
|
||||
}
|
||||
readData_2600(0x1FFF); // Reset Bank
|
||||
break;
|
||||
|
||||
case 0xF9: // Time Pilot Mapper 8KB
|
||||
// Bad implementation of the F8 Mapper
|
||||
// kevtris swapped the bank order - swapped banks may not match physical ROM data
|
||||
// Bankswitch code uses 0x1FFC and 0x1FF9
|
||||
for (int w = 3; w >= 0; w -= 3) {
|
||||
readData_2600(0x1FF9 + w);
|
||||
readSegment_2600(0x1000, 0x1E00);
|
||||
// Split Read of Last 0x200 bytes
|
||||
readDataArray_2600(0x1E00, 0x1F9);
|
||||
readData_2600(0x1FFF); // Reset Bank
|
||||
sdBuffer[0] = readData_2600(0x1FF9);
|
||||
// End of Bank 0x1FFA-0x1FFF
|
||||
readData_2600(0x1FFF); // Reset Bank
|
||||
readData_2600(0x1FF9 + w); // Set Bank
|
||||
for (int z = 1; z < 7; z++) {
|
||||
sdBuffer[z] = readData_2600(0x1FF9 + z); // 0x1FFA-0x1FFF
|
||||
}
|
||||
myFile.write(sdBuffer, 7);
|
||||
}
|
||||
// Reset Bank
|
||||
readData_2600(0x1FF9);
|
||||
readData_2600(0x1FFF);
|
||||
readData_2600(0x1FFC);
|
||||
break;
|
||||
|
||||
case 0xFA: // FA Mapper 12KB
|
||||
for (int x = 0; x < 0x3; x++) {
|
||||
writeData_2600(0x1FF8 + x, 0x1); // Set Bank with D0 HIGH
|
||||
readSegment_2600(0x1000, 0x1E00);
|
||||
// Split Read of Last 0x200 bytes
|
||||
readDataArray_2600(0x1E00, 0x1F8);
|
||||
for (int z = 0; z < 8; z++) {
|
||||
// Set Bank to ensure 0x1FFB-0x1FFF is correct
|
||||
writeData_2600(0x1FF8 + x, 0x1); // Set Bank with D0 HIGH
|
||||
sdBuffer[z] = readData_2600(0x1FF8 + z);
|
||||
}
|
||||
myFile.write(sdBuffer, 8);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xFE: // FE Mapper 8KB
|
||||
for (int x = 0; x < 0x2; x++) {
|
||||
writeData_2600(0x01FE, 0xF0 ^ (x << 5));
|
||||
writeData_2600(0x01FF, 0xF0 ^ (x << 5));
|
||||
readSegment_2600(0x1000, 0x2000);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0A: // UA Mapper 8KB
|
||||
readData_2600(0x220);
|
||||
readSegment_2600(0x1000, 0x2000);
|
||||
readData_2600(0x240);
|
||||
readSegment_2600(0x1000, 0x2000);
|
||||
break;
|
||||
|
||||
case 0x07: // X07 Mapper 64K
|
||||
for (int x = 0; x < 16; x++) {
|
||||
readData_2600(0x080D | (x << 4));
|
||||
readSegment_2600(0x1000, 0x2000);
|
||||
}
|
||||
}
|
||||
myFile.close();
|
||||
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
void println_Mapper2600(byte mapper) {
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
if (mapper == 0x04)
|
||||
println_Msg(F("F4SC"));
|
||||
else if (mapper == 0x06)
|
||||
println_Msg(F("F6SC"));
|
||||
else if (mapper == 0x08)
|
||||
println_Msg(F("F8SC"));
|
||||
else if (mapper == 0x20)
|
||||
println_Msg(F("2K"));
|
||||
else if (mapper == 0x40)
|
||||
println_Msg(F("4K"));
|
||||
else if (mapper == 0x0A)
|
||||
println_Msg(F("UA"));
|
||||
else if (mapper == 0xC0)
|
||||
println_Msg(F("CV"));
|
||||
else if (mapper == 0xD0)
|
||||
println_Msg(F("DPC"));
|
||||
else if (mapper == 0xF9)
|
||||
println_Msg(F("TP"));
|
||||
else if (mapper == 0x07)
|
||||
println_Msg(F("X07"));
|
||||
else
|
||||
println_Msg(mapper, HEX);
|
||||
#else
|
||||
if (mapper == 0x04)
|
||||
Serial.println(F("F4SC"));
|
||||
else if (mapper == 0x06)
|
||||
Serial.println(F("F6SC"));
|
||||
else if (mapper == 0x08)
|
||||
Serial.println(F("F8SC"));
|
||||
else if (mapper == 0x20)
|
||||
Serial.println(F("2K"));
|
||||
else if (mapper == 0x40)
|
||||
Serial.println(F("4K"));
|
||||
else if (mapper == 0x0A)
|
||||
Serial.println(F("UA"));
|
||||
else if (mapper == 0xC0)
|
||||
Serial.println(F("CV"));
|
||||
else if (mapper == 0xD0)
|
||||
Serial.println(F("DPC"));
|
||||
else if (mapper == 0xF9)
|
||||
Serial.println(F("TP"));
|
||||
else if (mapper == 0x07)
|
||||
Serial.println(F("X07"));
|
||||
else
|
||||
Serial.println(mapper, HEX);
|
||||
#endif
|
||||
}
|
||||
|
||||
void checkStatus_2600() {
|
||||
EEPROM_readAnything(7, a2600mapper);
|
||||
EEPROM_readAnything(8, a2600size);
|
||||
if (a2600size > 6) {
|
||||
a2600size = 1; // default 4KB
|
||||
EEPROM_writeAnything(8, a2600size);
|
||||
}
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("ATARI 2600 READER"));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(F("MAPPER: "));
|
||||
println_Mapper2600(a2600mapper);
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
if (a2600mapper == 0xD0)
|
||||
print_Msg(F("10"));
|
||||
else
|
||||
print_Msg(a2600[a2600size]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
wait();
|
||||
#else
|
||||
Serial.print(F("MAPPER: "));
|
||||
println_Mapper2600(a2600mapper);
|
||||
|
||||
Serial.print(FS(FSTRING_ROM_SIZE));
|
||||
if (a2600mapper == 0xD0)
|
||||
Serial.print(F("10"));
|
||||
else
|
||||
Serial.print(a2600[a2600size]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// SET MAPPER
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printMapperSelection_2600(int index) {
|
||||
display_Clear();
|
||||
print_Msg(FS(FSTRING_MAPPER));
|
||||
a2600index = index * 2;
|
||||
a2600mapselect = pgm_read_byte(a2600mapsize + a2600index);
|
||||
println_Mapper2600(a2600mapselect);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setMapper_2600() {
|
||||
byte new2600mapper;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
navigateMenu(0, a2600mapcount - 1, &printMapperSelection_2600);
|
||||
new2600mapper = a2600mapselect;
|
||||
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("MAPPER "));
|
||||
println_Mapper2600(new2600mapper);
|
||||
println_Msg(F(" SELECTED"));
|
||||
display_Update();
|
||||
delay(1000);
|
||||
#else
|
||||
setmapper:
|
||||
String newmap;
|
||||
Serial.println(F("SUPPORTED MAPPERS:"));
|
||||
Serial.println(F("0 = F4SC [Atari 32K \w RAM]"));
|
||||
Serial.println(F("1 = F6SC [Atari 16K \w RAM]"));
|
||||
Serial.println(F("2 = F8SC [Atari 8K \w RAM]"));
|
||||
Serial.println(F("3 = 2K [Standard 2K]"));
|
||||
Serial.println(F("4 = 3F [Tigervision 8K]"));
|
||||
Serial.println(F("5 = 4K [Standard 4K]"));
|
||||
Serial.println(F("6 = CV [Commavid]"));
|
||||
Serial.println(F("7 = DPC [Pitfall II]"));
|
||||
Serial.println(F("8 = E0 [Parker Bros]"));
|
||||
Serial.println(F("9 = E7 [M-Network]"));
|
||||
Serial.println(F("10 = F0 [Megaboy]"));
|
||||
Serial.println(F("11 = F4 [Atari 32K]"));
|
||||
Serial.println(F("12 = F6 [Atari 16K]"));
|
||||
Serial.println(F("13 = F8 [Atari 8K]"));
|
||||
Serial.println(F("14 = FA [CBS RAM Plus]"));
|
||||
Serial.println(F("15 = FE [Activision]"));
|
||||
Serial.println(F("16 = TP [Time Pilot 8K]"));
|
||||
Serial.println(F("17 = UA [UA Ltd]"));
|
||||
Serial.println(F("18 = 3E [Tigervision 32K \w RAM]"));
|
||||
Serial.println(F("19 = 07 [X07 64K]"));
|
||||
Serial.print(F("Enter Mapper [0-19]: "));
|
||||
while (Serial.available() == 0) {}
|
||||
newmap = Serial.readStringUntil('\n');
|
||||
Serial.println(newmap);
|
||||
a2600index = newmap.toInt() * 2;
|
||||
new2600mapper = pgm_read_byte(a2600mapsize + a2600index);
|
||||
#endif
|
||||
EEPROM_writeAnything(7, new2600mapper);
|
||||
a2600mapper = new2600mapper;
|
||||
|
||||
a2600size = pgm_read_byte(a2600mapsize + a2600index + 1);
|
||||
EEPROM_writeAnything(8, a2600size);
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
void readDataLine_2600(FsFile& database, void* gameMapper) {
|
||||
// Read mapper with three ascii character and subtract 48 to convert to decimal
|
||||
(*(byte*)gameMapper) = ((database.read() - 48) * 100) + ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void setCart_2600() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
byte gameMapper;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("2600.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
if(checkCartSelection(myFile, &readDataLine_2600, &gameMapper)) {
|
||||
EEPROM_writeAnything(7, gameMapper);
|
||||
for (int i = 0; i < a2600mapcount; i++) {
|
||||
a2600index = i * 2;
|
||||
if (gameMapper == pgm_read_byte(a2600mapsize + a2600index)) {
|
||||
a2600size = pgm_read_byte(a2600mapsize + a2600index + 1);
|
||||
EEPROM_writeAnything(8, a2600size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//******************************************
|
||||
// End of File
|
||||
//******************************************
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// ATARI 5200 MODULE
|
||||
//******************************************
|
||||
#ifdef enable_5200
|
||||
#ifdef ENABLE_5200
|
||||
// Atari 5200
|
||||
// Cartridge Pinout
|
||||
// 36P 2.54mm pitch connector
|
||||
|
@ -73,9 +73,7 @@ byte a5200[] = { 4, 8, 16, 32, 40 };
|
|||
byte a5200lo = 0; // Lowest Entry
|
||||
byte a5200hi = 4; // Highest Entry
|
||||
byte a5200mapper = 0;
|
||||
byte new5200mapper;
|
||||
byte a5200size;
|
||||
byte new5200size;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 07 MAPPER
|
||||
|
@ -85,10 +83,7 @@ byte new5200size;
|
|||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char a5200MenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char a5200MenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char a5200MenuItem3[] PROGMEM = "Set Mapper + Size";
|
||||
static const char* const menuOptions5200[] PROGMEM = { a5200MenuItem1, a5200MenuItem2, a5200MenuItem3, string_reset2 };
|
||||
static const char* const menuOptions5200[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, FSTRING_SET_SIZE, FSTRING_RESET };
|
||||
|
||||
void setup_5200() {
|
||||
// Request 5V
|
||||
|
@ -128,7 +123,7 @@ void setup_5200() {
|
|||
checkStatus_5200();
|
||||
strcpy(romName, "ATARI");
|
||||
|
||||
mode = mode_5200;
|
||||
mode = CORE_5200;
|
||||
}
|
||||
|
||||
void a5200Menu() {
|
||||
|
@ -139,7 +134,6 @@ void a5200Menu() {
|
|||
case 0:
|
||||
// Select Cart
|
||||
setCart_5200();
|
||||
wait();
|
||||
setup_5200();
|
||||
break;
|
||||
|
||||
|
@ -222,31 +216,9 @@ void readSegment_5200(uint16_t startaddr, uint16_t endaddr) {
|
|||
//******************************************
|
||||
|
||||
void readROM_5200() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".a52");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "5200/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(sd_error_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("5200", "ROM", romName, "a52");
|
||||
|
||||
// 5200 A13-A0 = 10 0000 0000 0000
|
||||
|
||||
switch (a5200mapper) {
|
||||
case 0: // Standard 4KB/8KB/16KB/32KB
|
||||
// Lower Half of 32K is at 0x4000
|
||||
|
@ -331,10 +303,9 @@ void readROM_5200() {
|
|||
}
|
||||
myFile.close();
|
||||
|
||||
unsigned long crcsize = a5200[a5200size] * 0x400;
|
||||
calcCRC(fileName, crcsize, NULL, 0);
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -345,6 +316,24 @@ void readROM_5200() {
|
|||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
void println_Mapper5200(byte mapper) {
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
if (mapper == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (mapper == 1)
|
||||
println_Msg(F("TWO CHIP"));
|
||||
else if (mapper == 2)
|
||||
println_Msg(F("BOUNTY BOB"));
|
||||
#else
|
||||
if (mapper == 0)
|
||||
Serial.println(F("STANDARD"));
|
||||
else if (mapper == 1)
|
||||
Serial.println(F("TWO CHIP"));
|
||||
else if (mapper == 2)
|
||||
Serial.println(F("BOUNTY BOB"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void checkMapperSize_5200() {
|
||||
for (int i = 0; i < a5200mapcount; i++) {
|
||||
a5200index = i * 3;
|
||||
|
@ -357,78 +346,26 @@ void checkMapperSize_5200() {
|
|||
}
|
||||
}
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRomSize_5200(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(a5200[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_5200() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte new5200size;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (a5200lo == a5200hi)
|
||||
new5200size = a5200lo;
|
||||
else {
|
||||
int b = 0;
|
||||
int i = a5200lo;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(a5200[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == a5200lo)
|
||||
i = a5200hi;
|
||||
else
|
||||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(a5200[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == a5200hi)
|
||||
i = a5200lo;
|
||||
else
|
||||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(a5200[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
new5200size = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
new5200size = navigateMenu(a5200lo, a5200hi, &printRomSize_5200);
|
||||
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(a5200[new5200size]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -453,7 +390,7 @@ setrom:
|
|||
new5200size = sizeROM.toInt() + a5200lo;
|
||||
if (new5200size > a5200hi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
|
@ -477,20 +414,15 @@ void checkStatus_5200() {
|
|||
EEPROM_writeAnything(8, a5200size);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("ATARI 5200 READER"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(F("MAPPER: "));
|
||||
println_Msg(a5200mapper);
|
||||
if (a5200mapper == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a5200mapper == 1)
|
||||
println_Msg(F("TWO CHIP"));
|
||||
else if (a5200mapper == 2)
|
||||
println_Msg(F("BOUNTY BOB"));
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
println_Mapper5200(a5200mapper);
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(a5200[a5200size]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -498,16 +430,11 @@ void checkStatus_5200() {
|
|||
#else
|
||||
Serial.print(F("MAPPER: "));
|
||||
Serial.println(a5200mapper);
|
||||
if (a5200mapper == 0)
|
||||
Serial.println(F("STANDARD"));
|
||||
else if (a5200mapper == 1)
|
||||
Serial.println(F("TWO CHIP"));
|
||||
else if (a5200mapper == 2)
|
||||
Serial.println(F("BOUNTY BOB"));
|
||||
Serial.print(F("ROM SIZE: "));
|
||||
println_Mapper5200(a5200mapper);
|
||||
Serial.print(FS(FSTRING_ROM_SIZE));
|
||||
Serial.print(a5200[a5200size]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -515,136 +442,23 @@ void checkStatus_5200() {
|
|||
// SET MAPPER
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printMapperSelection_5200(int index) {
|
||||
display_Clear();
|
||||
print_Msg(FS(FSTRING_MAPPER));
|
||||
a5200index = index * 3;
|
||||
a5200mapselect = pgm_read_byte(a5200mapsize + a5200index);
|
||||
println_Msg(a5200mapselect);
|
||||
println_Mapper5200(a5200mapselect);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setMapper_5200() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
int b = 0;
|
||||
int i = 0;
|
||||
// Check Button Status
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Pressed
|
||||
while (1) { // Scroll Mapper List
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
// Correct Overshoot
|
||||
if (i == 0)
|
||||
i = a5200mapcount - 1;
|
||||
else
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
a5200index = i * 3;
|
||||
a5200mapselect = pgm_read_byte(a5200mapsize + a5200index);
|
||||
println_Msg(a5200mapselect);
|
||||
if (a5200mapselect == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a5200mapselect == 1)
|
||||
println_Msg(F("TWO CHIP"));
|
||||
else if (a5200mapselect == 2)
|
||||
println_Msg(F("BOUNTY BOB"));
|
||||
display_Update();
|
||||
if (i == (a5200mapcount - 1))
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
delay(250);
|
||||
}
|
||||
}
|
||||
byte new5200mapper;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
navigateMenu(0, a5200mapcount - 1, &printMapperSelection_5200);
|
||||
new5200mapper = a5200mapselect;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
a5200index = i * 3;
|
||||
a5200mapselect = pgm_read_byte(a5200mapsize + a5200index);
|
||||
println_Msg(a5200mapselect);
|
||||
if (a5200mapselect == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a5200mapselect == 1)
|
||||
println_Msg(F("TWO CHIP"));
|
||||
else if (a5200mapselect == 2)
|
||||
println_Msg(F("BOUNTY BOB"));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous Mapper (doubleclick)
|
||||
if (i == 0)
|
||||
i = a5200mapcount - 1;
|
||||
else
|
||||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
a5200index = i * 3;
|
||||
a5200mapselect = pgm_read_byte(a5200mapsize + a5200index);
|
||||
println_Msg(a5200mapselect);
|
||||
if (a5200mapselect == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a5200mapselect == 1)
|
||||
println_Msg(F("TWO CHIP"));
|
||||
else if (a5200mapselect == 2)
|
||||
println_Msg(F("BOUNTY BOB"));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next Mapper (press)
|
||||
if (i == (a5200mapcount - 1))
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
a5200index = i * 3;
|
||||
a5200mapselect = pgm_read_byte(a5200mapsize + a5200index);
|
||||
println_Msg(a5200mapselect);
|
||||
if (a5200mapselect == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a5200mapselect == 1)
|
||||
println_Msg(F("TWO CHIP"));
|
||||
else if (a5200mapselect == 2)
|
||||
println_Msg(F("BOUNTY BOB"));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
new5200mapper = a5200mapselect;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("MAPPER "));
|
||||
print_Msg(new5200mapper);
|
||||
|
@ -672,258 +486,25 @@ setmapper:
|
|||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
|
||||
FsFile a5200csvFile;
|
||||
char a5200game[39]; // title
|
||||
char a5200mm[3]; // mapper
|
||||
char a5200rr[3]; // romsize
|
||||
char a5200ll[4]; // linelength (previous line)
|
||||
unsigned long a5200csvpos; // CSV File Position
|
||||
char a5200cartCSV[] = "5200cart.txt"; // CSV List
|
||||
char a5200csvEND[] = "EOF"; // CSV End Marker for scrolling
|
||||
|
||||
bool readLine_5200(FsFile& f, char* line, size_t maxLen) {
|
||||
for (size_t n = 0; n < maxLen; n++) {
|
||||
int c = f.read();
|
||||
if (c < 0 && n == 0) return false; // EOF
|
||||
if (c < 0 || c == '\n') {
|
||||
line[n] = 0;
|
||||
return true;
|
||||
}
|
||||
line[n] = c;
|
||||
}
|
||||
return false; // line too long
|
||||
}
|
||||
|
||||
bool readVals_5200(char* a5200game, char* a5200mm, char* a5200rr, char* a5200ll) {
|
||||
char line[44];
|
||||
a5200csvpos = a5200csvFile.position();
|
||||
if (!readLine_5200(a5200csvFile, line, sizeof(line))) {
|
||||
return false; // EOF or too long
|
||||
}
|
||||
char* comma = strtok(line, ",");
|
||||
int x = 0;
|
||||
while (comma != NULL) {
|
||||
if (x == 0)
|
||||
strcpy(a5200game, comma);
|
||||
else if (x == 1)
|
||||
strcpy(a5200mm, comma);
|
||||
else if (x == 2)
|
||||
strcpy(a5200rr, comma);
|
||||
else if (x == 3)
|
||||
strcpy(a5200ll, comma);
|
||||
comma = strtok(NULL, ",");
|
||||
x += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getCartListInfo_5200() {
|
||||
bool buttonreleased = 0;
|
||||
bool cartselected = 0;
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F(" HOLD TO FAST CYCLE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("HOLD BUTTON TO FAST CYCLE"));
|
||||
#endif
|
||||
delay(2000);
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Held - Fast Cycle
|
||||
while (1) { // Scroll Game List
|
||||
while (readVals_5200(a5200game, a5200mm, a5200rr, a5200ll)) {
|
||||
if (strcmp(a5200csvEND, a5200game) == 0) {
|
||||
a5200csvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(a5200game);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(a5200game);
|
||||
#endif
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
buttonreleased = 1;
|
||||
break;
|
||||
}
|
||||
if (buttonreleased) {
|
||||
buttonreleased = 0; // Reset Flag
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) // Button Released
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("FAST CYCLE OFF"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("FAST CYCLE OFF"));
|
||||
Serial.println(F("PRESS BUTTON TO STEP FORWARD"));
|
||||
Serial.println(F("DOUBLE CLICK TO STEP BACK"));
|
||||
Serial.println(F("HOLD TO SELECT"));
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
while (readVals_5200(a5200game, a5200mm, a5200rr, a5200ll)) {
|
||||
if (strcmp(a5200csvEND, a5200game) == 0) {
|
||||
a5200csvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(a5200game);
|
||||
display.setCursor(0, 48);
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(a5200game);
|
||||
#endif
|
||||
while (1) { // Single Step
|
||||
int b = checkButton();
|
||||
if (b == 1) { // Continue (press)
|
||||
break;
|
||||
}
|
||||
if (b == 2) { // Reset to Start of List (doubleclick)
|
||||
byte prevline = strtol(a5200ll, NULL, 10);
|
||||
a5200csvpos -= prevline;
|
||||
a5200csvFile.seek(a5200csvpos);
|
||||
break;
|
||||
}
|
||||
if (b == 3) { // Long Press - Select Cart (hold)
|
||||
new5200mapper = strtol(a5200mm, NULL, 10);
|
||||
new5200size = strtol(a5200rr, NULL, 10);
|
||||
EEPROM_writeAnything(7, new5200mapper);
|
||||
EEPROM_writeAnything(8, new5200size);
|
||||
cartselected = 1; // SELECTION MADE
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F("SELECTION MADE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("SELECTION MADE"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartselected) {
|
||||
cartselected = 0; // Reset Flag
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("END OF FILE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("END OF FILE"));
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkCSV_5200() {
|
||||
if (getCartListInfo_5200()) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART SELECTED"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(a5200game);
|
||||
display_Update();
|
||||
// Display Settings
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("CODE: M"));
|
||||
print_Msg(new5200mapper);
|
||||
print_Msg(F("/R"));
|
||||
println_Msg(new5200size);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("CART SELECTED"));
|
||||
Serial.println(a5200game);
|
||||
// Display Settings
|
||||
Serial.print(F("CODE: M"));
|
||||
Serial.print(new5200mapper);
|
||||
Serial.print(F("/R"));
|
||||
Serial.println(new5200size);
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("NO SELECTION"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("NO SELECTION"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void checkSize_5200() {
|
||||
EEPROM_readAnything(7, a5200mapper);
|
||||
for (int i = 0; i < a5200mapcount; i++) {
|
||||
a5200index = i * 3;
|
||||
if (a5200mapper == pgm_read_byte(a5200mapsize + a5200index)) {
|
||||
a5200size = pgm_read_byte(a5200mapsize + a5200index + 1);
|
||||
EEPROM_writeAnything(8, a5200size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setCart_5200() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(a5200cartCSV);
|
||||
display_Update();
|
||||
#endif
|
||||
//go to root
|
||||
sd.chdir();
|
||||
sprintf(folder, "5200/CSV");
|
||||
sd.chdir(folder); // Switch Folder
|
||||
a5200csvFile = sd.open(a5200cartCSV, O_READ);
|
||||
if (!a5200csvFile) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CSV FILE NOT FOUND!"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("CSV FILE NOT FOUND!"));
|
||||
#endif
|
||||
while (1) {
|
||||
if (checkButton() != 0)
|
||||
setup_5200();
|
||||
|
||||
struct database_entry_mapper_size entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("5200.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
if(checkCartSelection(myFile, &readDataLineMapperSize, &entry)) {
|
||||
EEPROM_writeAnything(7, entry.gameMapper);
|
||||
EEPROM_writeAnything(8, entry.gameSize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
checkCSV_5200();
|
||||
a5200csvFile.close();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// ATARI 7800 MODULE
|
||||
//******************************************
|
||||
#ifdef enable_7800
|
||||
#ifdef ENABLE_7800
|
||||
// Atari 7800
|
||||
// Cartridge Pinout
|
||||
// 32P 2.54mm pitch (USE 36P CONNECTOR)
|
||||
|
@ -44,6 +44,7 @@
|
|||
// CONTROL PINS:
|
||||
// CLK(PH1) - SNES CPUCLK
|
||||
// R/W(PH6) - SNES /RD
|
||||
// HALT(PH0) - SNES /RESET
|
||||
|
||||
//******************************************
|
||||
// Supported Mappers
|
||||
|
@ -58,9 +59,10 @@ static const byte PROGMEM a7800mapsize[] = {
|
|||
4, 4, 4, // Double Dragon/Rampage 128K [78AC]
|
||||
5, 3, 3, // Realsports Baseball/Tank Command/Tower Toppler/Waterski 64K [78S4]
|
||||
6, 3, 3, // Karateka (PAL) 64K [78S4 Variant]
|
||||
7, 1, 4, // Bankset switching
|
||||
};
|
||||
|
||||
byte a7800mapcount = 7; // (sizeof(a7800mapsize) / sizeof(a7800mapsize[0])) / 3;
|
||||
byte a7800mapcount = 8; // (sizeof(a7800mapsize) / sizeof(a7800mapsize[0])) / 3;
|
||||
byte a7800mapselect;
|
||||
int a7800index;
|
||||
|
||||
|
@ -68,9 +70,7 @@ byte a7800[] = { 16, 32, 48, 64, 128, 144 };
|
|||
byte a7800lo = 0; // Lowest Entry
|
||||
byte a7800hi = 5; // Highest Entry
|
||||
byte a7800mapper = 0;
|
||||
byte new7800mapper;
|
||||
byte a7800size;
|
||||
byte new7800size;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 07 MAPPER
|
||||
|
@ -80,10 +80,7 @@ byte new7800size;
|
|||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char a7800MenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char a7800MenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char a7800MenuItem3[] PROGMEM = "Set Mapper + Size";
|
||||
static const char* const menuOptions7800[] PROGMEM = { a7800MenuItem1, a7800MenuItem2, a7800MenuItem3, string_reset2 };
|
||||
static const char* const menuOptions7800[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, FSTRING_SET_SIZE, FSTRING_RESET };
|
||||
|
||||
void setup_7800() {
|
||||
// Request 5V
|
||||
|
@ -99,8 +96,8 @@ void setup_7800() {
|
|||
DDRL = 0xFF;
|
||||
|
||||
// Set Control Pins to Output
|
||||
// ---(PH0) CLK(PH1) ---(PH3) ---(PH4) ---(PH5) R/W(PH6)
|
||||
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
// HALT(PH0) ---(PH3) ---(PH4) ---(PH5) R/W(PH6)
|
||||
DDRH |= (1 << 0) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set TIME(PJ0) to Output (UNUSED)
|
||||
DDRJ |= (1 << 0);
|
||||
|
@ -109,8 +106,8 @@ void setup_7800() {
|
|||
DDRC = 0x00;
|
||||
|
||||
// Setting Control Pins to HIGH
|
||||
// ---(PH0) CLK(PH1) ---(PH3) ---(PH4) ---(PH5) R/W(PH6)
|
||||
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
// HALT(PH0) ---(PH3) ---(PH4) ---(PH5) R/W(PH6)
|
||||
PORTH |= (1 << 0) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set Unused Data Pins (PA0-PA7) to Output
|
||||
DDRA = 0xFF;
|
||||
|
@ -120,10 +117,36 @@ void setup_7800() {
|
|||
PORTL = 0xFF; // A16-A23
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
|
||||
#ifdef ENABLE_CLOCKGEN
|
||||
// Adafruit Clock Generator
|
||||
|
||||
initializeClockOffset();
|
||||
|
||||
if (!i2c_found) {
|
||||
display_Clear();
|
||||
print_FatalError(F("Clock Generator not found"));
|
||||
}
|
||||
|
||||
// Set Eeprom clock to 1Mhz
|
||||
clockgen.set_freq(200000000ULL, SI5351_CLK1);
|
||||
|
||||
// Start outputting Eeprom clock
|
||||
clockgen.output_enable(SI5351_CLK1, 1); // Eeprom clock
|
||||
|
||||
// Wait for clock generator
|
||||
clockgen.update_status();
|
||||
|
||||
#else
|
||||
// Set CLK(PH1) to Output
|
||||
DDRH |= (1 << 1);
|
||||
// Output a high signal CLK(PH1)
|
||||
PORTH |= (1 << 1);
|
||||
#endif
|
||||
|
||||
checkStatus_7800();
|
||||
strcpy(romName, "ATARI");
|
||||
|
||||
mode = mode_7800;
|
||||
mode = CORE_7800;
|
||||
}
|
||||
|
||||
void a7800Menu() {
|
||||
|
@ -134,7 +157,6 @@ void a7800Menu() {
|
|||
case 0:
|
||||
// Select Cart
|
||||
setCart_7800();
|
||||
wait();
|
||||
setup_7800();
|
||||
break;
|
||||
|
||||
|
@ -163,7 +185,7 @@ void a7800Menu() {
|
|||
// READ CODE
|
||||
//******************************************
|
||||
|
||||
uint8_t readData_7800(uint32_t addr) // Add Input Pullup
|
||||
uint8_t readData_7800(uint16_t addr) // Add Input Pullup
|
||||
{
|
||||
PORTF = addr & 0xFF; // A0-A7
|
||||
PORTK = (addr >> 8) & 0xFF; // A8-A15
|
||||
|
@ -201,7 +223,7 @@ uint8_t readData_7800(uint32_t addr) // Add Input Pullup
|
|||
return ret;
|
||||
}
|
||||
|
||||
void readSegment_7800(uint32_t startaddr, uint32_t endaddr) {
|
||||
void readSegment_7800(uint16_t startaddr, uint32_t endaddr) {
|
||||
for (uint32_t addr = startaddr; addr < endaddr; addr += 512) {
|
||||
for (int w = 0; w < 512; w++) {
|
||||
uint8_t temp = readData_7800(addr + w);
|
||||
|
@ -211,7 +233,29 @@ void readSegment_7800(uint32_t startaddr, uint32_t endaddr) {
|
|||
}
|
||||
}
|
||||
|
||||
void writeData_7800(uint32_t addr, uint8_t data) {
|
||||
void readSegmentBank_7800(uint8_t startbank, uint8_t endbank) {
|
||||
for (uint8_t x = startbank; x < endbank; x++) {
|
||||
writeData_7800(0x8000, x);
|
||||
readSegment_7800(0x8000, 0xC000);
|
||||
}
|
||||
}
|
||||
|
||||
void readStandard_7800() {
|
||||
if (a7800size > 1)
|
||||
readSegment_7800(0x4000, 0x8000); // +16K = 48K
|
||||
if (a7800size > 0)
|
||||
readSegment_7800(0x8000, 0xC000); // +16K = 32K
|
||||
// Base 16K
|
||||
readSegment_7800(0xC000, 0x10000); // 16K
|
||||
}
|
||||
|
||||
void readSupergame_7800() {
|
||||
readSegmentBank_7800(0, 7); // Bank 0-6 16K * 7 = 112K
|
||||
readSegment_7800(0xC000, 0x10000); // Bank 7 +16K = 128K
|
||||
}
|
||||
|
||||
|
||||
void writeData_7800(uint16_t addr, uint8_t data) {
|
||||
PORTF = addr & 0xFF; // A0-A7
|
||||
PORTK = (addr >> 8) & 0xFF; // A8-A15
|
||||
NOP;
|
||||
|
@ -240,13 +284,38 @@ void writeData_7800(uint32_t addr, uint8_t data) {
|
|||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
PORTH |= (1 << 6); // R/W(PH6) HIGH = READ
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
DDRC = 0x00; // Reset to Input
|
||||
}
|
||||
|
||||
// Activision Bankswitch - Double Dragon/Rampage 128K
|
||||
void bankSwitch_7800(uint32_t addr) {
|
||||
void bankSwitch_7800(uint16_t addr) {
|
||||
PORTF = addr & 0xFF; // A0-A7
|
||||
PORTK = (addr >> 8) & 0xFF; // A8-A15
|
||||
NOP;
|
||||
|
@ -273,53 +342,20 @@ void bankSwitch_7800(uint32_t addr) {
|
|||
//******************************************
|
||||
|
||||
void readROM_7800() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".a78");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "7800/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(sd_error_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("7800", "ROM", romName, "a78");
|
||||
|
||||
switch (a7800mapper) {
|
||||
case 0: // Standard 16K/32K/48K [7816/7832/7848]
|
||||
if (a7800size > 1)
|
||||
readSegment_7800(0x4000, 0x8000); // +16K = 48K
|
||||
if (a7800size > 0)
|
||||
readSegment_7800(0x8000, 0xC000); // +16K = 32K
|
||||
// Base 16K
|
||||
readSegment_7800(0xC000, 0x10000); // 16K
|
||||
readStandard_7800();
|
||||
break;
|
||||
|
||||
case 1: // SuperGame 128K [78SG]
|
||||
for (int x = 0; x < 7; x++) {
|
||||
writeData_7800(0x8000, x); // Banks 0-6
|
||||
readSegment_7800(0x8000, 0xC000); // 16K * 7 = 112K
|
||||
}
|
||||
readSegment_7800(0xC000, 0x10000); // Bank 7 +16 = 128K
|
||||
readSupergame_7800();
|
||||
break;
|
||||
|
||||
case 2: // SuperGame - Alien Brigade/Crossbow 144K [78S9]
|
||||
readSegment_7800(0x4000, 0x8000); // 16K
|
||||
for (int x = 0; x < 8; x++) {
|
||||
writeData_7800(0x8000, x); // Banks 0-7
|
||||
readSegment_7800(0x8000, 0xC000); // 16K * 8 = +128K = 144K
|
||||
}
|
||||
readSegmentBank_7800(0, 8); // 16K * 8 = +128K = 144K
|
||||
break;
|
||||
|
||||
case 3: // F-18 Hornet 64K [78AB]
|
||||
|
@ -357,31 +393,53 @@ void readROM_7800() {
|
|||
break;
|
||||
|
||||
case 5: // Realsports Baseball/Tank Command/Tower Toppler/Waterski 64K [78S4]
|
||||
for (int x = 0; x < 4; x++) {
|
||||
writeData_7800(0x8000, x);
|
||||
readSegment_7800(0x8000, 0xC000); // 16K * 4 = 64K
|
||||
}
|
||||
readSegmentBank_7800(0, 4); // 16K * 4 = 64K
|
||||
break;
|
||||
|
||||
case 6: // Karateka (PAL) 64K [78S4 Variant]
|
||||
for (int x = 4; x < 8; x++) {
|
||||
writeData_7800(0x8000, x);
|
||||
readSegment_7800(0x8000, 0xC000); // 16K * 4 = 64K
|
||||
readSegmentBank_7800(4, 8); // 16K * 4 = 64K
|
||||
break;
|
||||
|
||||
case 7: // Bankset switching
|
||||
if (a7800size > 3) {
|
||||
setHalt_7800(1);
|
||||
readSupergame_7800();
|
||||
setHalt_7800(0);
|
||||
readSupergame_7800();
|
||||
} else {
|
||||
setHalt_7800(1);
|
||||
readStandard_7800();
|
||||
setHalt_7800(0);
|
||||
readStandard_7800();
|
||||
}
|
||||
break;
|
||||
}
|
||||
myFile.close();
|
||||
|
||||
unsigned long crcsize = a7800[a7800size] * 0x400;
|
||||
calcCRC(fileName, crcsize, NULL, 0);
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
|
||||
void setHalt_7800(byte on) {
|
||||
if(on == 1) {
|
||||
PORTH |= (1 << 0); // HALT(PH0) HIGH = SALLY
|
||||
} else {
|
||||
PORTH &= ~(1 << 0); // HALT(PH0) LOW = MARIA
|
||||
}
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// ROM SIZE
|
||||
//******************************************
|
||||
|
@ -398,76 +456,46 @@ void checkMapperSize_7800() {
|
|||
}
|
||||
}
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void println_Mapper7800(byte mapper) {
|
||||
if (mapper == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (mapper == 1)
|
||||
println_Msg(F("SUPERGAME 128K[78SG]"));
|
||||
else if (mapper == 2)
|
||||
println_Msg(F("SUPERGAME 144K[78S9]"));
|
||||
else if (mapper == 3)
|
||||
println_Msg(F("F-18 HORNET [78AB]"));
|
||||
else if (mapper == 4)
|
||||
println_Msg(F("DBLDRGN/RMPG [78AC]"));
|
||||
else if (mapper == 5)
|
||||
println_Msg(F("BASEBALL/ETC [78S4]"));
|
||||
else if (mapper == 6)
|
||||
println_Msg(F("KARATEKA(PAL) [78S4]"));
|
||||
else if (mapper == 7)
|
||||
println_Msg(F("BANKSET"));
|
||||
}
|
||||
|
||||
void printRomSize_7800(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(a7800[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_7800() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte new7800size;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (a7800lo == a7800hi)
|
||||
new7800size = a7800lo;
|
||||
else {
|
||||
int b = 0;
|
||||
int i = a7800lo;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(a7800[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == a7800lo)
|
||||
i = a7800hi;
|
||||
else
|
||||
i--;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(a7800[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == a7800hi)
|
||||
i = a7800lo;
|
||||
else
|
||||
i++;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(a7800[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
new7800size = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
new7800size = navigateMenu(a7800lo, a7800hi, &printRomSize_7800);
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(a7800[new7800size]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -492,7 +520,7 @@ setrom:
|
|||
new7800size = sizeROM.toInt() + a7800lo;
|
||||
if (new7800size > a7800hi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
|
@ -507,7 +535,7 @@ setrom:
|
|||
void checkStatus_7800() {
|
||||
EEPROM_readAnything(7, a7800mapper);
|
||||
EEPROM_readAnything(8, a7800size);
|
||||
if (a7800mapper > 6) {
|
||||
if (a7800mapper > 7) {
|
||||
a7800mapper = 0; // default
|
||||
EEPROM_writeAnything(7, a7800mapper);
|
||||
}
|
||||
|
@ -516,28 +544,15 @@ void checkStatus_7800() {
|
|||
EEPROM_writeAnything(8, a7800size);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("ATARI 7800 READER"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(F("MAPPER: "));
|
||||
println_Msg(a7800mapper);
|
||||
if (a7800mapper == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a7800mapper == 1)
|
||||
println_Msg(F("SUPERGAME [78SG]"));
|
||||
else if (a7800mapper == 2)
|
||||
println_Msg(F("SUPERGAME [78S9]"));
|
||||
else if (a7800mapper == 3)
|
||||
println_Msg(F("F-18 HORNET [78AB]"));
|
||||
else if (a7800mapper == 4)
|
||||
println_Msg(F("DBLDRGN/RMPG [78AC]"));
|
||||
else if (a7800mapper == 5)
|
||||
println_Msg(F("BASEBALL/ETC [78S4]"));
|
||||
else if (a7800mapper == 6)
|
||||
println_Msg(F("KARATEKA(PAL)[78S4]"));
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
println_Mapper7800(a7800mapper);
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(a7800[a7800size]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -559,10 +574,12 @@ void checkStatus_7800() {
|
|||
Serial.println(F("Realsports Baseball/Tank Command/Tower Toppler/Waterski [78S4]"));
|
||||
else if (a7800mapper == 6)
|
||||
Serial.println(F("Karateka (PAL) [78S4 Variant]"));
|
||||
Serial.print(F("ROM SIZE: "));
|
||||
else if (a7800mapper == 7)
|
||||
Serial.println(F("Bankset"));
|
||||
Serial.print(FS(FSTRING_ROM_SIZE));
|
||||
Serial.print(A7800[a7800size]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -570,166 +587,23 @@ void checkStatus_7800() {
|
|||
// SET MAPPER
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printMapperSelection_7800(int index) {
|
||||
display_Clear();
|
||||
print_Msg(FS(FSTRING_MAPPER));
|
||||
a7800index = index * 3;
|
||||
a7800mapselect = pgm_read_byte(a7800mapsize + a7800index);
|
||||
println_Msg(a7800mapselect);
|
||||
println_Mapper7800(a7800mapselect);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setMapper_7800() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
int b = 0;
|
||||
int i = 0;
|
||||
// Check Button Status
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Pressed
|
||||
while (1) { // Scroll Mapper List
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
// Correct Overshoot
|
||||
if (i == 0)
|
||||
i = a7800mapcount - 1;
|
||||
else
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
a7800index = i * 3;
|
||||
a7800mapselect = pgm_read_byte(a7800mapsize + a7800index);
|
||||
println_Msg(a7800mapselect);
|
||||
if (a7800mapselect == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a7800mapselect == 1)
|
||||
println_Msg(F("SUPERGAME 128K[78SG]"));
|
||||
else if (a7800mapselect == 2)
|
||||
println_Msg(F("SUPERGAME 144K[78S9]"));
|
||||
else if (a7800mapselect == 3)
|
||||
println_Msg(F("F-18 HORNET [78AB]"));
|
||||
else if (a7800mapselect == 4)
|
||||
println_Msg(F("DBLDRGN/RAMPG [78AC]"));
|
||||
else if (a7800mapselect == 5)
|
||||
println_Msg(F("BASEBALL/ETC [78S4]"));
|
||||
else if (a7800mapselect == 6)
|
||||
println_Msg(F("KARATEKA(PAL) [78S4]"));
|
||||
display_Update();
|
||||
if (i == (a7800mapcount - 1))
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
delay(250);
|
||||
}
|
||||
}
|
||||
byte new7800mapper = 0;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
navigateMenu(0, a7800mapcount - 1, &printMapperSelection_7800);
|
||||
new7800mapper = a7800mapselect;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
a7800index = i * 3;
|
||||
a7800mapselect = pgm_read_byte(a7800mapsize + a7800index);
|
||||
println_Msg(a7800mapselect);
|
||||
if (a7800mapselect == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a7800mapselect == 1)
|
||||
println_Msg(F("SUPERGAME 128K[78SG]"));
|
||||
else if (a7800mapselect == 2)
|
||||
println_Msg(F("SUPERGAME 144K[78S9]"));
|
||||
else if (a7800mapselect == 3)
|
||||
println_Msg(F("F-18 HORNET [78AB]"));
|
||||
else if (a7800mapselect == 4)
|
||||
println_Msg(F("DBLDRGN/RAMPG [78AC]"));
|
||||
else if (a7800mapselect == 5)
|
||||
println_Msg(F("BASEBALL/ETC [78S4]"));
|
||||
else if (a7800mapselect == 6)
|
||||
println_Msg(F("KARATEKA(PAL) [78S4]"));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous Mapper (doubleclick)
|
||||
if (i == 0)
|
||||
i = a7800mapcount - 1;
|
||||
else
|
||||
i--;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
a7800index = i * 3;
|
||||
a7800mapselect = pgm_read_byte(a7800mapsize + a7800index);
|
||||
println_Msg(a7800mapselect);
|
||||
if (a7800mapselect == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a7800mapselect == 1)
|
||||
println_Msg(F("SUPERGAME 128K[78SG]"));
|
||||
else if (a7800mapselect == 2)
|
||||
println_Msg(F("SUPERGAME 144K[78S9]"));
|
||||
else if (a7800mapselect == 3)
|
||||
println_Msg(F("F-18 HORNET [78AB]"));
|
||||
else if (a7800mapselect == 4)
|
||||
println_Msg(F("DBLDRGN/RAMPG [78AC]"));
|
||||
else if (a7800mapselect == 5)
|
||||
println_Msg(F("BASEBALL/ETC [78S4]"));
|
||||
else if (a7800mapselect == 6)
|
||||
println_Msg(F("KARATEKA(PAL) [78S4]"));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
}
|
||||
if (b == 1) { // Next Mapper (press)
|
||||
if (i == (a7800mapcount - 1))
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
a7800index = i * 3;
|
||||
a7800mapselect = pgm_read_byte(a7800mapsize + a7800index);
|
||||
println_Msg(a7800mapselect);
|
||||
if (a7800mapselect == 0)
|
||||
println_Msg(F("STANDARD"));
|
||||
else if (a7800mapselect == 1)
|
||||
println_Msg(F("SUPERGAME 128K[78SG]"));
|
||||
else if (a7800mapselect == 2)
|
||||
println_Msg(F("SUPERGAME 144K[78S9]"));
|
||||
else if (a7800mapselect == 3)
|
||||
println_Msg(F("F-18 HORNET [78AB]"));
|
||||
else if (a7800mapselect == 4)
|
||||
println_Msg(F("DBLDRGN/RAMPG [78AC]"));
|
||||
else if (a7800mapselect == 5)
|
||||
println_Msg(F("BASEBALL/ETC [78S4]"));
|
||||
else if (a7800mapselect == 6)
|
||||
println_Msg(F("KARATEKA(PAL) [78S4]"));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
new7800mapper = a7800mapselect;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("MAPPER "));
|
||||
print_Msg(new7800mapper);
|
||||
|
@ -747,7 +621,8 @@ setmapper:
|
|||
Serial.println(F("4 = Double Dragon/Rampage [78AC]"));
|
||||
Serial.println(F("5 = Realsports Baseball/Tank Command/Tower Toppler/Waterski [78S4]"));
|
||||
Serial.println(F("6 = Karateka (PAL) [78S4 Variant]"));
|
||||
Serial.print(F("Enter Mapper [0-6]: "));
|
||||
Serial.println(F("7 = Bankset"));
|
||||
Serial.print(F("Enter Mapper [0-7]: "));
|
||||
while (Serial.available() == 0) {}
|
||||
newmap = Serial.readStringUntil('\n');
|
||||
Serial.println(newmap);
|
||||
|
@ -765,257 +640,25 @@ setmapper:
|
|||
// CART SELECT CODE
|
||||
//******************************************
|
||||
|
||||
FsFile a7800csvFile;
|
||||
char a7800game[36]; // title
|
||||
char a7800mm[3]; // mapper
|
||||
char a7800rr[3]; // mapper
|
||||
char a7800ll[4]; // linelength (previous line)
|
||||
unsigned long a7800csvpos; // CSV File Position
|
||||
char a7800cartCSV[] = "7800cart.txt"; // CSV List
|
||||
char a7800csvEND[] = "EOF"; // CSV End Marker for scrolling
|
||||
|
||||
bool readLine_7800(FsFile& f, char* line, size_t maxLen) {
|
||||
for (size_t n = 0; n < maxLen; n++) {
|
||||
int c = f.read();
|
||||
if (c < 0 && n == 0) return false; // EOF
|
||||
if (c < 0 || c == '\n') {
|
||||
line[n] = 0;
|
||||
return true;
|
||||
}
|
||||
line[n] = c;
|
||||
}
|
||||
return false; // line too long
|
||||
}
|
||||
|
||||
bool readVals_7800(char* a7800game, char* a7800mm, char* a7800rr, char* a7800ll) {
|
||||
char line[44];
|
||||
a7800csvpos = a7800csvFile.position();
|
||||
if (!readLine_7800(a7800csvFile, line, sizeof(line))) {
|
||||
return false; // EOF or too long
|
||||
}
|
||||
char* comma = strtok(line, ",");
|
||||
int x = 0;
|
||||
while (comma != NULL) {
|
||||
if (x == 0)
|
||||
strcpy(a7800game, comma);
|
||||
else if (x == 1)
|
||||
strcpy(a7800mm, comma);
|
||||
else if (x == 2)
|
||||
strcpy(a7800rr, comma);
|
||||
else if (x == 3)
|
||||
strcpy(a7800ll, comma);
|
||||
comma = strtok(NULL, ",");
|
||||
x += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getCartListInfo_7800() {
|
||||
bool buttonreleased = 0;
|
||||
bool cartselected = 0;
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F(" HOLD TO FAST CYCLE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("HOLD BUTTON TO FAST CYCLE"));
|
||||
#endif
|
||||
delay(2000);
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Held - Fast Cycle
|
||||
while (1) { // Scroll Game List
|
||||
while (readVals_7800(a7800game, a7800mm, a7800rr, a7800ll)) {
|
||||
if (strcmp(a7800csvEND, a7800game) == 0) {
|
||||
a7800csvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(a7800game);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(a7800game);
|
||||
#endif
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
buttonreleased = 1;
|
||||
break;
|
||||
}
|
||||
if (buttonreleased) {
|
||||
buttonreleased = 0; // Reset Flag
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) // Button Released
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("FAST CYCLE OFF"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("FAST CYCLE OFF"));
|
||||
Serial.println(F("PRESS BUTTON TO STEP FORWARD"));
|
||||
Serial.println(F("DOUBLE CLICK TO STEP BACK"));
|
||||
Serial.println(F("HOLD TO SELECT"));
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
while (readVals_7800(a7800game, a7800mm, a7800rr, a7800ll)) {
|
||||
if (strcmp(a7800csvEND, a7800game) == 0) {
|
||||
a7800csvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(a7800game);
|
||||
display.setCursor(0, 48);
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(a7800game);
|
||||
#endif
|
||||
while (1) { // Single Step
|
||||
int b = checkButton();
|
||||
if (b == 1) { // Continue (press)
|
||||
break;
|
||||
}
|
||||
if (b == 2) { // Reset to Start of List (doubleclick)
|
||||
byte prevline = strtol(a7800ll, NULL, 10);
|
||||
a7800csvpos -= prevline;
|
||||
a7800csvFile.seek(a7800csvpos);
|
||||
break;
|
||||
}
|
||||
if (b == 3) { // Long Press - Select Cart (hold)
|
||||
new7800mapper = strtol(a7800mm, NULL, 10);
|
||||
new7800size = strtol(a7800rr, NULL, 10);
|
||||
EEPROM_writeAnything(7, new7800mapper);
|
||||
EEPROM_writeAnything(8, new7800size);
|
||||
cartselected = 1; // SELECTION MADE
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F("SELECTION MADE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("SELECTION MADE"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartselected) {
|
||||
cartselected = 0; // Reset Flag
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("END OF FILE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("END OF FILE"));
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkCSV_7800() {
|
||||
if (getCartListInfo_7800()) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART SELECTED"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(a7800game);
|
||||
display_Update();
|
||||
// Display Settings
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("CODE: M"));
|
||||
print_Msg(new7800mapper);
|
||||
print_Msg(F("/R"));
|
||||
println_Msg(new7800size);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("CART SELECTED"));
|
||||
Serial.println(a7800game);
|
||||
// Display Settings
|
||||
Serial.print(F("CODE: M"));
|
||||
Serial.print(new7800mapper);
|
||||
Serial.print(F("/R"));
|
||||
Serial.println(new7800size);
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("NO SELECTION"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("NO SELECTION"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void checkSize_7800() {
|
||||
EEPROM_readAnything(7, a7800mapper);
|
||||
for (int i = 0; i < a7800mapcount; i++) {
|
||||
a7800index = i * 3;
|
||||
if (a7800mapper == pgm_read_byte(a7800mapsize + a7800index)) {
|
||||
a7800size = pgm_read_byte(a7800mapsize + a7800index + 1);
|
||||
EEPROM_writeAnything(8, a7800size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setCart_7800() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(a7800cartCSV);
|
||||
display_Update();
|
||||
#endif
|
||||
//go to root
|
||||
sd.chdir();
|
||||
sprintf(folder, "7800/CSV");
|
||||
sd.chdir(folder); // Switch Folder
|
||||
a7800csvFile = sd.open(a7800cartCSV, O_READ);
|
||||
if (!a7800csvFile) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CSV FILE NOT FOUND!"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("CSV FILE NOT FOUND!"));
|
||||
#endif
|
||||
while (1) {
|
||||
if (checkButton() != 0)
|
||||
setup_7800();
|
||||
|
||||
struct database_entry_mapper_size entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("7800.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
if(checkCartSelection(myFile, &readDataLineMapperSize, &entry)) {
|
||||
EEPROM_writeAnything(7, entry.gameMapper);
|
||||
EEPROM_writeAnything(8, entry.gameSize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
checkCSV_7800();
|
||||
a7800csvFile.close();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// EMERSON ARCADIA 2001 MODULE
|
||||
//******************************************
|
||||
#if defined(enable_ARC)
|
||||
#if defined(ENABLE_ARC)
|
||||
// Emerson Arcadia 2001
|
||||
// Cartridge Pinout
|
||||
// 30P 2.54mm pitch connector
|
||||
|
@ -40,7 +40,6 @@ byte arclo = 0; // Lowest Entry
|
|||
byte archi = 3; // Highest Entry
|
||||
|
||||
byte arcsize;
|
||||
byte newarcsize;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 08 ROM SIZE
|
||||
|
@ -49,11 +48,7 @@ byte newarcsize;
|
|||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char arcMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char arcMenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char arcMenuItem3[] PROGMEM = "Set Size";
|
||||
static const char arcMenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsARC[] PROGMEM = { arcMenuItem1, arcMenuItem2, arcMenuItem3, arcMenuItem4 };
|
||||
static const char* const menuOptionsARC[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, FSTRING_SET_SIZE, FSTRING_RESET };
|
||||
|
||||
void setup_ARC() {
|
||||
// Request 5V
|
||||
|
@ -93,7 +88,7 @@ void setup_ARC() {
|
|||
checkStatus_ARC();
|
||||
strcpy(romName, "ARCADIA");
|
||||
|
||||
mode = mode_ARC;
|
||||
mode = CORE_ARC;
|
||||
}
|
||||
|
||||
void arcMenu() {
|
||||
|
@ -104,7 +99,6 @@ void arcMenu() {
|
|||
case 0:
|
||||
// Select Cart
|
||||
setCart_ARC();
|
||||
wait();
|
||||
setup_ARC();
|
||||
break;
|
||||
|
||||
|
@ -156,28 +150,7 @@ void readSegment_ARC(uint16_t startaddr, uint16_t endaddr) {
|
|||
}
|
||||
|
||||
void readROM_ARC() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".bin");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "ARC/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Saving to "));
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(create_file_STR);
|
||||
}
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("ARC", "ROM", romName, "bin");
|
||||
|
||||
readSegment_ARC(0x0000, 0x0800); // 2K
|
||||
if (arcsize > 0) {
|
||||
|
@ -191,10 +164,9 @@ void readROM_ARC() {
|
|||
}
|
||||
myFile.close();
|
||||
|
||||
unsigned long crcsize = ARC[arcsize] * 0x400;
|
||||
calcCRC(fileName, crcsize, NULL, 0);
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -204,78 +176,26 @@ void readROM_ARC() {
|
|||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRomSize_ARC(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(ARC[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_ARC() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte newarcsize;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (arclo == archi)
|
||||
newarcsize = arclo;
|
||||
else {
|
||||
int b = 0;
|
||||
int i = arclo;
|
||||
newarcsize = navigateMenu(arclo, archi, &printRomSize_ARC);
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(ARC[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == arclo)
|
||||
i = archi;
|
||||
else
|
||||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(ARC[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == archi)
|
||||
i = arclo;
|
||||
else
|
||||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(ARC[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newarcsize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(ARC[newarcsize]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -300,7 +220,7 @@ setrom:
|
|||
newarcsize = sizeROM.toInt() + arclo;
|
||||
if (newarcsize > archi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
|
@ -319,12 +239,12 @@ void checkStatus_ARC() {
|
|||
EEPROM_writeAnything(8, arcsize);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("ARCADIA 2001 READER"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(ARC[arcsize]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -333,246 +253,32 @@ void checkStatus_ARC() {
|
|||
Serial.print(F("CURRENT ROM SIZE: "));
|
||||
Serial.print(ARC[arcsize]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
|
||||
FsFile arccsvFile;
|
||||
char arcgame[20]; // title
|
||||
char arcrr[3]; // romsize
|
||||
char arcll[4]; // linelength (previous line)
|
||||
unsigned long arccsvpos; // CSV File Position
|
||||
char arccartCSV[] = "arccart.txt"; // CSV List
|
||||
char arccsvEND[] = "EOF"; // CSV End Marker for scrolling
|
||||
|
||||
bool readLine_ARC(FsFile& f, char* line, size_t maxLen) {
|
||||
for (size_t n = 0; n < maxLen; n++) {
|
||||
int c = f.read();
|
||||
if (c < 0 && n == 0) return false; // EOF
|
||||
if (c < 0 || c == '\n') {
|
||||
line[n] = 0;
|
||||
return true;
|
||||
}
|
||||
line[n] = c;
|
||||
}
|
||||
return false; // line too long
|
||||
}
|
||||
|
||||
bool readVals_ARC(char* arcgame, char* arcrr, char* arcll) {
|
||||
char line[26];
|
||||
arccsvpos = arccsvFile.position();
|
||||
if (!readLine_ARC(arccsvFile, line, sizeof(line))) {
|
||||
return false; // EOF or too long
|
||||
}
|
||||
char* comma = strtok(line, ",");
|
||||
int x = 0;
|
||||
while (comma != NULL) {
|
||||
if (x == 0)
|
||||
strcpy(arcgame, comma);
|
||||
else if (x == 1)
|
||||
strcpy(arcrr, comma);
|
||||
else if (x == 2)
|
||||
strcpy(arcll, comma);
|
||||
comma = strtok(NULL, ",");
|
||||
x += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getCartListInfo_ARC() {
|
||||
bool buttonreleased = 0;
|
||||
bool cartselected = 0;
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F(" HOLD TO FAST CYCLE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("HOLD BUTTON TO FAST CYCLE"));
|
||||
#endif
|
||||
delay(2000);
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Held - Fast Cycle
|
||||
while (1) { // Scroll Game List
|
||||
while (readVals_ARC(arcgame, arcrr, arcll)) {
|
||||
if (strcmp(arccsvEND, arcgame) == 0) {
|
||||
arccsvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(arcgame);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(arcgame);
|
||||
#endif
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
buttonreleased = 1;
|
||||
break;
|
||||
}
|
||||
if (buttonreleased) {
|
||||
buttonreleased = 0; // Reset Flag
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) // Button Released
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("FAST CYCLE OFF"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("FAST CYCLE OFF"));
|
||||
Serial.println(F("PRESS BUTTON TO STEP FORWARD"));
|
||||
Serial.println(F("DOUBLE CLICK TO STEP BACK"));
|
||||
Serial.println(F("HOLD TO SELECT"));
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
while (readVals_ARC(arcgame, arcrr, arcll)) {
|
||||
if (strcmp(arccsvEND, arcgame) == 0) {
|
||||
arccsvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(arcgame);
|
||||
display.setCursor(0, 48);
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(arcgame);
|
||||
#endif
|
||||
while (1) { // Single Step
|
||||
int b = checkButton();
|
||||
if (b == 1) { // Continue (press)
|
||||
break;
|
||||
}
|
||||
if (b == 2) { // Reset to Start of List (doubleclick)
|
||||
byte prevline = strtol(arcll, NULL, 10);
|
||||
arccsvpos -= prevline;
|
||||
arccsvFile.seek(arccsvpos);
|
||||
break;
|
||||
}
|
||||
if (b == 3) { // Long Press - Select Cart (hold)
|
||||
newarcsize = strtol(arcrr, NULL, 10);
|
||||
EEPROM_writeAnything(8, newarcsize);
|
||||
cartselected = 1; // SELECTION MADE
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F("SELECTION MADE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("SELECTION MADE"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartselected) {
|
||||
cartselected = 0; // Reset Flag
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("END OF FILE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("END OF FILE"));
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkCSV_ARC() {
|
||||
if (getCartListInfo_ARC()) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART SELECTED"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(arcgame);
|
||||
display_Update();
|
||||
// Display Settings
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("CODE: R"));
|
||||
println_Msg(newarcsize);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("CART SELECTED"));
|
||||
Serial.println(arcgame);
|
||||
// Display Settings
|
||||
Serial.print(F("CODE: R"));
|
||||
Serial.println(newarcsize);
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("NO SELECTION"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("NO SELECTION"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void setCart_ARC() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(arccartCSV);
|
||||
display_Update();
|
||||
#endif
|
||||
//go to root
|
||||
sd.chdir();
|
||||
sprintf(folder, "ARC/CSV");
|
||||
sd.chdir(folder); // Switch Folder
|
||||
arccsvFile = sd.open(arccartCSV, O_READ);
|
||||
if (!arccsvFile) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CSV FILE NOT FOUND!"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("CSV FILE NOT FOUND!"));
|
||||
#endif
|
||||
while (1) {
|
||||
if (checkButton() != 0)
|
||||
setup_ARC();
|
||||
}
|
||||
}
|
||||
checkCSV_ARC();
|
||||
|
||||
arccsvFile.close();
|
||||
byte gameSize;
|
||||
|
||||
// Select starting letter
|
||||
//byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("arccart.txt", O_READ)) {
|
||||
// seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
if(checkCartSelection(myFile, &readDataLineSingleDigit, &gameSize)) {
|
||||
EEPROM_writeAnything(8, gameSize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//******************************************
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// COLECOVISION MODULE
|
||||
//******************************************
|
||||
#ifdef enable_COLV
|
||||
#ifdef ENABLE_COLV
|
||||
|
||||
// Coleco Colecovision
|
||||
// Cartridge Pinout
|
||||
|
@ -39,7 +39,6 @@ byte collo = 0; // Lowest Entry
|
|||
byte colhi = 5; // Highest Entry
|
||||
|
||||
byte colsize;
|
||||
byte newcolsize;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 08 ROM SIZE
|
||||
|
@ -48,11 +47,7 @@ byte newcolsize;
|
|||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char colMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char colMenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char colMenuItem3[] PROGMEM = "Set Size";
|
||||
//static const char colMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsCOL[] PROGMEM = { colMenuItem1, colMenuItem2, colMenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsCOL[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, FSTRING_SET_SIZE, FSTRING_RESET };
|
||||
|
||||
void setup_COL() {
|
||||
// Request 5V
|
||||
|
@ -92,7 +87,7 @@ void setup_COL() {
|
|||
checkStatus_COL();
|
||||
strcpy(romName, "COLECO");
|
||||
|
||||
mode = mode_COL;
|
||||
mode = CORE_COL;
|
||||
}
|
||||
|
||||
void colMenu() {
|
||||
|
@ -167,29 +162,7 @@ void readSegment_COL(uint32_t startaddr, uint32_t endaddr) {
|
|||
}
|
||||
|
||||
void readROM_COL() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".col");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
// sprintf(folder, "COL/ROM/%s/%d", romName, foldern);
|
||||
sprintf(folder, "COL/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("COL", "ROM", romName, "col");
|
||||
|
||||
// RESET ALL CS PINS HIGH (DISABLE)
|
||||
PORTH |= (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
@ -218,7 +191,7 @@ void readROM_COL() {
|
|||
// Compare CRC32 to database and rename ROM if found
|
||||
compareCRC("colv.txt", 0, 1, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -229,78 +202,27 @@ void readROM_COL() {
|
|||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRomSize_COL(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_byte(&(COL[index])));
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_COL() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte newcolsize;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (collo == colhi)
|
||||
newcolsize = collo;
|
||||
else {
|
||||
int b = 0;
|
||||
int i = collo;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_byte(&(COL[i])));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == collo)
|
||||
i = colhi;
|
||||
else
|
||||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_byte(&(COL[i])));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == colhi)
|
||||
i = collo;
|
||||
else
|
||||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_byte(&(COL[i])));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newcolsize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
newcolsize = navigateMenu(collo, colhi, &printRomSize_COL);
|
||||
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(pgm_read_byte(&(COL[newcolsize])));
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -325,7 +247,7 @@ setrom:
|
|||
newcolsize = sizeROM.toInt() + collo;
|
||||
if (newcolsize > colhi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
|
@ -344,15 +266,15 @@ void checkStatus_COL() {
|
|||
EEPROM_writeAnything(8, colsize);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("COLECOVISION READER"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(pgm_read_byte(&(COL[colsize])));
|
||||
println_Msg(F("K"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -361,164 +283,101 @@ void checkStatus_COL() {
|
|||
Serial.print(F("CURRENT ROM SIZE: "));
|
||||
Serial.print(pgm_read_byte(&(COL[colsize])));
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
void setCart_COL() {
|
||||
char gamename[100];
|
||||
char tempStr2[2];
|
||||
struct database_entry_COL {
|
||||
char crc_search[9];
|
||||
byte gameSize;
|
||||
};
|
||||
|
||||
void readDataLine_COL(FsFile& database, void* entry) {
|
||||
struct database_entry_COL* castEntry = (database_entry_COL*)entry;
|
||||
|
||||
// Read CRC32 checksum
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
checksumStr[i] = char(database.read());
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
castEntry->crc_search[i] = char(database.read());
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
castEntry->gameSize = ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void printDataLine_COL(void* entry) {
|
||||
struct database_entry_COL* castEntry = (database_entry_COL*)entry;
|
||||
|
||||
print_Msg(FS(FSTRING_SIZE));
|
||||
print_Msg(castEntry->gameSize);
|
||||
println_Msg(F("KB"));
|
||||
}
|
||||
|
||||
void setCart_COL() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
struct database_entry_COL entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("colv.txt", O_READ)) {
|
||||
// Skip ahead to selected starting letter
|
||||
if ((myLetter > 0) && (myLetter <= 26)) {
|
||||
while (myFile.available()) {
|
||||
// Read current name
|
||||
get_line(gamename, &myFile, 96);
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
// Compare selected letter with first letter of current name until match
|
||||
while (gamename[0] != 64 + myLetter) {
|
||||
skip_line(&myFile);
|
||||
skip_line(&myFile);
|
||||
get_line(gamename, &myFile, 96);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(checkCartSelection(myFile, &readDataLine_COL, &entry, &printDataLine_COL)) {
|
||||
//byte COL[] = {8, 12, 16, 20, 24, 32};
|
||||
switch (entry.gameSize) {
|
||||
case 8:
|
||||
colsize = 0;
|
||||
break;
|
||||
|
||||
// Rewind one line
|
||||
rewind_line(myFile);
|
||||
}
|
||||
case 12:
|
||||
colsize = 1;
|
||||
break;
|
||||
|
||||
// Display database
|
||||
while (myFile.available()) {
|
||||
display_Clear();
|
||||
case 16:
|
||||
colsize = 2;
|
||||
break;
|
||||
|
||||
// Read game name
|
||||
get_line(gamename, &myFile, 96);
|
||||
case 20:
|
||||
colsize = 3;
|
||||
break;
|
||||
|
||||
// Read CRC32 checksum
|
||||
sprintf(checksumStr, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(checksumStr, tempStr2);
|
||||
}
|
||||
case 24:
|
||||
colsize = 4;
|
||||
break;
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
case 32:
|
||||
colsize = 5;
|
||||
break;
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
sprintf(crc_search, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(crc_search, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
cartSize = myFile.read() - 48;
|
||||
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
|
||||
// Skip rest of line
|
||||
myFile.seekCur(2);
|
||||
|
||||
// Skip every 3rd line
|
||||
skip_line(&myFile);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(gamename);
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(cartSize);
|
||||
println_Msg(F("KB"));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
int b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
default:
|
||||
colsize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
rewind_line(myFile, 6);
|
||||
break;
|
||||
}
|
||||
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
//byte COL[] = {8, 12, 16, 20, 24, 32};
|
||||
switch (cartSize) {
|
||||
case 8:
|
||||
colsize = 0;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
colsize = 1;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
colsize = 2;
|
||||
break;
|
||||
|
||||
case 20:
|
||||
colsize = 3;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
colsize = 4;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
colsize = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
colsize = 0;
|
||||
break;
|
||||
}
|
||||
EEPROM_writeAnything(8, colsize);
|
||||
myFile.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
EEPROM_writeAnything(8, colsize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(F("Database file not found"));
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -77,7 +77,7 @@ void DynamicClockSerial::begin(unsigned long baud, byte config, unsigned long sc
|
|||
}
|
||||
|
||||
// ClockedSerial setup
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) && !defined(enable_serial) && defined(ENABLE_UPDATER)
|
||||
#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
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
automatically be enabled if you selected HW2 or newer above.
|
||||
*/
|
||||
|
||||
//#define clockgen_installed
|
||||
//#define ENABLE_CLOCKGEN
|
||||
|
||||
/****/
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
|||
type later in this file.
|
||||
*/
|
||||
|
||||
//#define RTC_installed
|
||||
//#define ENABLE_RTC
|
||||
|
||||
/****/
|
||||
|
||||
|
@ -71,217 +71,252 @@
|
|||
/* [ Atari 2600 --------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_ATARI
|
||||
//#define ENABLE_2600
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Atari 5200 --------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_5200
|
||||
//#define ENABLE_5200
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Atari 7800 --------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_7800
|
||||
//#define ENABLE_7800
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Benesse Pocket Challenge W ----------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_PCW
|
||||
//#define ENABLE_PCW
|
||||
|
||||
/****/
|
||||
|
||||
/* [ C64 --------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_C64
|
||||
//#define ENABLE_C64
|
||||
|
||||
/****/
|
||||
|
||||
/* [ ColecoVision ------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_COLV
|
||||
//#define ENABLE_COLV
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Emerson Arcadia 2001 ----------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_ARC
|
||||
//#define ENABLE_ARC
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Fairchild Channel F ------------------------------------------ ]
|
||||
*/
|
||||
|
||||
//#define enable_FAIRCHILD
|
||||
//#define ENABLE_FAIRCHILD
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Flashrom Programmer for SNES repros -------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_FLASH
|
||||
//#define enable_FLASH16
|
||||
//#define ENABLE_FLASH
|
||||
//#define ENABLE_FLASH16
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Game Boy (Color) and Advance --------------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_GBX
|
||||
#define ENABLE_GBX
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Intellivision ------------------------------------------------ ]
|
||||
*/
|
||||
|
||||
//#define enable_INTV
|
||||
//#define ENABLE_INTV
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Neo Geo Pocket ----------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_NGP
|
||||
//#define ENABLE_NGP
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Nintendo 64 -------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_N64
|
||||
#define ENABLE_N64
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Nintendo Entertainment System/Family Computer ---------------- ]
|
||||
*/
|
||||
|
||||
#define enable_NES
|
||||
#define ENABLE_NES
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Magnavox Odyssey 2 ------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_ODY2
|
||||
//#define ENABLE_ODY2
|
||||
|
||||
/****/
|
||||
|
||||
/* [ MSX ------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_MSX
|
||||
//#define ENABLE_MSX
|
||||
|
||||
/****/
|
||||
|
||||
/* [ PC Engine/TurboGrafx 16 -------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_PCE
|
||||
//#define ENABLE_PCE
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Pokemon Mini -------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_POKE
|
||||
//#define ENABLE_POKE
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Sega Master System/Mark III/Game Gear/SG-1000 ---------------- ]
|
||||
*/
|
||||
|
||||
#define enable_SMS
|
||||
#define ENABLE_SMS
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Sega Mega Drive/Genesis -------------------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_MD
|
||||
#define ENABLE_MD
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super Famicom SF Memory Cassette ----------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_SFM
|
||||
//#define ENABLE_SFM
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super Famicom Satellaview ------------------------------------ ]
|
||||
*/
|
||||
|
||||
//#define enable_SV
|
||||
//#define ENABLE_SV
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super Famicom Sufami Turbo ----------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define ENABLE_ST
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super Famicom Game Processor RAM Cassette -------------------- ]
|
||||
*/
|
||||
|
||||
//#define ENABLE_GPC
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super Nintendo ----------------------------------------------- ]
|
||||
*/
|
||||
|
||||
#define enable_SNES
|
||||
#define ENABLE_SNES
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Vectrex --------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_VECTREX
|
||||
//#define ENABLE_VECTREX
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Virtual Boy -------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_VBOY
|
||||
//#define ENABLE_VBOY
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Watara Supervision ------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_WSV
|
||||
//#define ENABLE_WSV
|
||||
|
||||
/****/
|
||||
|
||||
/* [ WonderSwan and Benesse Pocket Challenge v2 ------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_WS
|
||||
//#define ENABLE_WS
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Super A'can -------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_SUPRACAN
|
||||
//#define ENABLE_SUPRACAN
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Casio Loopy -------------------------------------------------- ]
|
||||
*/
|
||||
|
||||
//#define enable_LOOPY
|
||||
//#define ENABLE_LOOPY
|
||||
|
||||
/****/
|
||||
|
||||
/*==== FIRMWARE OPTIONS ===========================================*/
|
||||
|
||||
/* [ Config File -------------------------------------------------- ]
|
||||
Allow changing some configuration values via a config file. You
|
||||
generally can only use the config to set options or disable
|
||||
certain featuress. It cannot be used to toggle firmware options
|
||||
on, only off.
|
||||
|
||||
Note For Developers: See OSCR.* for info.
|
||||
|
||||
Filename: config.txt
|
||||
*/
|
||||
|
||||
//#define ENABLE_CONFIG
|
||||
|
||||
/****/
|
||||
|
||||
/* [ LCD: Background Color ---------------------------------------- ]
|
||||
Set the backlight color of the LCD if you have one.
|
||||
|
||||
Can be set using config:
|
||||
lcd.confColor=1
|
||||
lcd.red=0
|
||||
lcd.green=0
|
||||
lcd.blue=0
|
||||
|
||||
PARAMETERS:
|
||||
Green, Red, Blue
|
||||
*/
|
||||
|
||||
#define background_color 100, 0, 0
|
||||
#define OPTION_LCD_BG_COLOR 100, 0, 0
|
||||
|
||||
/****/
|
||||
|
||||
|
@ -312,15 +347,18 @@
|
|||
Tests for shorts and other issues in your OSCR build.
|
||||
*/
|
||||
|
||||
#define enable_selftest
|
||||
#define ENABLE_SELFTEST
|
||||
|
||||
/****/
|
||||
|
||||
/* [ Logging ------------------------------------------------------ ]
|
||||
Write all info to OSCR_LOG.txt in root dir
|
||||
|
||||
Can be toggled off using config:
|
||||
oscr.logging=0
|
||||
*/
|
||||
|
||||
#define global_log
|
||||
#define ENABLE_GLOBAL_LOG
|
||||
|
||||
/****/
|
||||
|
||||
|
@ -338,8 +376,8 @@
|
|||
Toggle clock calibration menu and whether or not to use calibration data from snes_clk.txt
|
||||
*/
|
||||
|
||||
//#define clockgen_calibration
|
||||
//#define use_clockgen_calibration
|
||||
//#define OPTION_CLOCKGEN_CALIBRATION
|
||||
//#define OPTION_CLOCKGEN_USE_CALIBRATION
|
||||
|
||||
/****/
|
||||
|
||||
|
@ -353,16 +391,29 @@
|
|||
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.
|
||||
|
||||
**
|
||||
** DEPRECATED: Use the config file instead. See below.
|
||||
**
|
||||
*/
|
||||
|
||||
//#define use_md_conf
|
||||
|
||||
/*
|
||||
Alternatively, define it here by uncommenting and changing the
|
||||
following line. Setting both allows you to change the default.
|
||||
Configure how the MD core saves are formatted.
|
||||
|
||||
Can be set using config:
|
||||
md.saveType=0
|
||||
|
||||
If config is enabled, this option does nothing -- use the config.
|
||||
|
||||
Options:
|
||||
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 DEFAULT_VALUE_segaSram16bit 0
|
||||
//#define OPTION_MD_DEFAULT_SAVE_TYPE 0
|
||||
|
||||
/****/
|
||||
|
||||
|
@ -372,7 +423,7 @@
|
|||
with all Cart Readers
|
||||
*/
|
||||
|
||||
//#define fastcrc
|
||||
//#define OPTION_N64_FASTCRC
|
||||
|
||||
/****/
|
||||
|
||||
|
@ -380,7 +431,7 @@
|
|||
Enable to save a n64log.txt file with rom info in /N64/ROM
|
||||
*/
|
||||
|
||||
//#define savesummarytotxt
|
||||
//#define OPTION_N64_SAVESUMMARY
|
||||
|
||||
/****/
|
||||
|
||||
|
@ -390,39 +441,47 @@
|
|||
You probably shouldn't change this stuff!
|
||||
*/
|
||||
|
||||
#if defined(ENABLE_CONFIG)
|
||||
# define CONFIG_FILE "config.txt"
|
||||
// Define the max length of the key=value pairs
|
||||
// Do your best not to have to increase these.
|
||||
# define CONFIG_KEY_MAX 32
|
||||
# define CONFIG_VALUE_MAX 32
|
||||
#endif
|
||||
|
||||
#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
|
||||
# define ENABLE_LCD
|
||||
# define ENABLE_NEOPIXEL
|
||||
# define ENABLE_ROTARY
|
||||
//# define rotate_counter_clockwise
|
||||
# define ENABLE_CLOCKGEN
|
||||
# define OPTION_N64_FASTCRC
|
||||
# define OPTION_WS_ADAPTER_V2
|
||||
#endif
|
||||
|
||||
#if (defined(HW2) || defined(HW3))
|
||||
#define enable_OLED
|
||||
#define enable_Button2
|
||||
#define clockgen_installed
|
||||
#define CA_LED
|
||||
#define fastcrc
|
||||
# define ENABLE_OLED
|
||||
# define ENABLE_BUTTON2
|
||||
# define ENABLE_CLOCKGEN
|
||||
# define ENABLE_CA_LED
|
||||
# define OPTION_N64_FASTCRC
|
||||
#endif
|
||||
|
||||
#if defined(HW1)
|
||||
#define enable_OLED
|
||||
//#define clockgen_installed
|
||||
//#define fastcrc
|
||||
# define ENABLE_OLED
|
||||
//#define ENABLE_CLOCKGEN
|
||||
//#define OPTION_N64_FASTCRC
|
||||
#endif
|
||||
|
||||
#if defined(SERIAL_MONITOR)
|
||||
#define enable_serial
|
||||
//#define clockgen_installed
|
||||
//#define fastcrc
|
||||
# define ENABLE_SERIAL
|
||||
//#define ENABLE_CLOCKGEN
|
||||
//#define OPTION_N64_FASTCRC
|
||||
#endif
|
||||
|
||||
/* Firmware updater only works with HW3 and HW5 */
|
||||
#if !(defined(HW5) || defined(HW3))
|
||||
#undef ENABLE_UPDATER
|
||||
# undef ENABLE_UPDATER
|
||||
#endif
|
||||
|
||||
/* End of settings */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// FAIRCHILD CHANNEL F MODULE
|
||||
//******************************************
|
||||
#if defined(enable_FAIRCHILD)
|
||||
#if defined(ENABLE_FAIRCHILD)
|
||||
// Fairchild Channel F
|
||||
// Cartridge Pinout
|
||||
// 22P (27P Width) 2.54mm pitch connector
|
||||
|
@ -70,7 +70,6 @@ byte fairchildlo = 0; // Lowest Entry
|
|||
byte fairchildhi = 3; // Highest Entry
|
||||
|
||||
byte fairchildsize;
|
||||
byte newfairchildsize;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 08 ROM SIZE
|
||||
|
@ -79,12 +78,8 @@ byte newfairchildsize;
|
|||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char fairchildMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char fairchildMenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char fairchildMenuItem3[] PROGMEM = "Set Size";
|
||||
static const char fairchildMenuItem4[] PROGMEM = "Read 16K";
|
||||
static const char fairchildMenuItem5[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsFAIRCHILD[] PROGMEM = { fairchildMenuItem1, fairchildMenuItem2, fairchildMenuItem3, fairchildMenuItem4, fairchildMenuItem5 };
|
||||
static const char* const menuOptionsFAIRCHILD[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, FSTRING_SET_SIZE, fairchildMenuItem4, FSTRING_RESET };
|
||||
|
||||
void setup_FAIRCHILD() {
|
||||
// Request 5V
|
||||
|
@ -125,7 +120,7 @@ void setup_FAIRCHILD() {
|
|||
checkStatus_FAIRCHILD();
|
||||
strcpy(romName, "FAIRCHILD");
|
||||
|
||||
mode = mode_FAIRCHILD;
|
||||
mode = CORE_FAIRCHILD;
|
||||
}
|
||||
|
||||
void fairchildMenu() {
|
||||
|
@ -397,29 +392,7 @@ uint8_t readData_FAIRCHILD() {
|
|||
}
|
||||
|
||||
void readROM_FAIRCHILD() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".bin");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "FAIRCHILD/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Saving to "));
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(create_file_STR);
|
||||
}
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("FAIRCHILD", "ROM", romName, "bin");
|
||||
|
||||
unsigned long cartsize = FAIRCHILD[fairchildsize] * 0x400;
|
||||
uint8_t blocks = cartsize / 0x200;
|
||||
|
@ -431,7 +404,7 @@ void readROM_FAIRCHILD() {
|
|||
// 0x55,0x2B - most carts
|
||||
// 0x55,0xAA - alien invasion (4K)
|
||||
// 0x55,0xBB - video whizball (3K)
|
||||
for (int y = 0; y < 0x4800; y++) {
|
||||
for (uint16_t y = 0; y < 0x4800; y++) {
|
||||
uint8_t startbyte = readData_FAIRCHILD();
|
||||
if (startbyte == 0x55) { // Start Byte
|
||||
sdBuffer[0] = startbyte;
|
||||
|
@ -459,7 +432,7 @@ void readROM_FAIRCHILD() {
|
|||
// Skip BIOS/Blocks Code for 4K Carts - Tested with Alien Invasion/Pro Football
|
||||
// Alien Invasion/Pro Football both use a DM74LS02N (Quad 2-Input NOR Gate) with two 2K ROM Chips
|
||||
uint16_t offset = z * 0x200;
|
||||
for (int x = 0; x < 0x800 + offset; x++) { // Skip BIOS/Previous Blocks
|
||||
for (uint16_t x = 0; x < 0x800 + offset; x++) { // Skip BIOS/Previous Blocks
|
||||
readData_FAIRCHILD();
|
||||
}
|
||||
}
|
||||
|
@ -476,27 +449,19 @@ void readROM_FAIRCHILD() {
|
|||
}
|
||||
myFile.close();
|
||||
|
||||
calcCRC(fileName, cartsize, NULL, 0);
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
|
||||
void read16K_FAIRCHILD() // Read 16K Bytes
|
||||
{
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".bin");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "FAIRCHILD/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
void read16K_FAIRCHILD() { // Read 16K Bytes
|
||||
createFolder("FAIRCHILD", "ROM", romName, "bin");
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Saving to "));
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
@ -511,14 +476,14 @@ void read16K_FAIRCHILD() // Read 16K Bytes
|
|||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
unsigned long cartsize = FAIRCHILD[fairchildsize] * 0x400;
|
||||
for (int y = 0; y < 0x20; y++) {
|
||||
for (uint16_t y = 0; y < 0x20; y++) {
|
||||
if (cartsize == 0x1000) { // 4K
|
||||
// Skip BIOS/Blocks Code for 4K Carts - Tested with Alien Invasion/Pro Football
|
||||
// Alien Invasion/Pro Football both use a DM74LS02N (Quad 2-Input NOR Gate) with two 2K ROM Chips
|
||||
// IF CASINO POKER DOES NOT DUMP PROPERLY USING READROM
|
||||
// TEST BY SETTING ROM SIZE TO 2K AND 4K THEN COMPARE 16K DUMPS
|
||||
uint16_t offset = y * 0x200;
|
||||
for (int x = 0; x < 0x800 + offset; x++) { // Skip BIOS/Previous Blocks
|
||||
for (uint16_t x = 0; x < 0x800 + offset; x++) { // Skip BIOS/Previous Blocks
|
||||
readData_FAIRCHILD();
|
||||
}
|
||||
}
|
||||
|
@ -531,9 +496,9 @@ void read16K_FAIRCHILD() // Read 16K Bytes
|
|||
}
|
||||
myFile.close();
|
||||
|
||||
calcCRC(fileName, 0x4000, NULL, 0);
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -543,75 +508,26 @@ void read16K_FAIRCHILD() // Read 16K Bytes
|
|||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRomSize_FAIRCHILD(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(FAIRCHILD[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_FAIRCHILD() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte newfairchildsize;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (fairchildlo == fairchildhi)
|
||||
newfairchildsize = fairchildlo;
|
||||
else {
|
||||
int b = 0;
|
||||
int i = fairchildlo;
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(FAIRCHILD[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == fairchildlo)
|
||||
i = fairchildhi;
|
||||
else
|
||||
i--;
|
||||
newfairchildsize = navigateMenu(fairchildlo, fairchildhi, &printRomSize_FAIRCHILD);
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(FAIRCHILD[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == fairchildhi)
|
||||
i = fairchildlo;
|
||||
else
|
||||
i++;
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(FAIRCHILD[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newfairchildsize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(FAIRCHILD[newfairchildsize]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -636,7 +552,7 @@ setrom:
|
|||
newfairchildsize = sizeROM.toInt() + fairchildlo;
|
||||
if (newfairchildsize > fairchildhi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
|
@ -655,12 +571,12 @@ void checkStatus_FAIRCHILD() {
|
|||
EEPROM_writeAnything(8, fairchildsize);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CHANNEL F READER"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(FAIRCHILD[fairchildsize]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -669,246 +585,32 @@ void checkStatus_FAIRCHILD() {
|
|||
Serial.print(F("CURRENT ROM SIZE: "));
|
||||
Serial.print(FAIRCHILD[fairchildsize]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
|
||||
FsFile fairchildcsvFile;
|
||||
char fairchildgame[33]; // title
|
||||
char fairchildrr[3]; // romsize
|
||||
char fairchildll[4]; // linelength (previous line)
|
||||
unsigned long fairchildcsvpos; // CSV File Position
|
||||
char fairchildcartCSV[] = "fairchildcart.txt"; // CSV List
|
||||
char fairchildcsvEND[] = "EOF"; // CSV End Marker for scrolling
|
||||
|
||||
bool readLine_FAIRCHILD(FsFile& f, char* line, size_t maxLen) {
|
||||
for (size_t n = 0; n < maxLen; n++) {
|
||||
int c = f.read();
|
||||
if (c < 0 && n == 0) return false; // EOF
|
||||
if (c < 0 || c == '\n') {
|
||||
line[n] = 0;
|
||||
return true;
|
||||
}
|
||||
line[n] = c;
|
||||
}
|
||||
return false; // line too long
|
||||
}
|
||||
|
||||
bool readVals_FAIRCHILD(char* fairchildgame, char* fairchildrr, char* fairchildll) {
|
||||
char line[39];
|
||||
fairchildcsvpos = fairchildcsvFile.position();
|
||||
if (!readLine_FAIRCHILD(fairchildcsvFile, line, sizeof(line))) {
|
||||
return false; // EOF or too long
|
||||
}
|
||||
char* comma = strtok(line, ",");
|
||||
int x = 0;
|
||||
while (comma != NULL) {
|
||||
if (x == 0)
|
||||
strcpy(fairchildgame, comma);
|
||||
else if (x == 1)
|
||||
strcpy(fairchildrr, comma);
|
||||
else if (x == 2)
|
||||
strcpy(fairchildll, comma);
|
||||
comma = strtok(NULL, ",");
|
||||
x += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getCartListInfo_FAIRCHILD() {
|
||||
bool buttonreleased = 0;
|
||||
bool cartselected = 0;
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F(" HOLD TO FAST CYCLE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("HOLD BUTTON TO FAST CYCLE"));
|
||||
#endif
|
||||
delay(2000);
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Held - Fast Cycle
|
||||
while (1) { // Scroll Game List
|
||||
while (readVals_FAIRCHILD(fairchildgame, fairchildrr, fairchildll)) {
|
||||
if (strcmp(fairchildcsvEND, fairchildgame) == 0) {
|
||||
fairchildcsvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(fairchildgame);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(fairchildgame);
|
||||
#endif
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
buttonreleased = 1;
|
||||
break;
|
||||
}
|
||||
if (buttonreleased) {
|
||||
buttonreleased = 0; // Reset Flag
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) // Button Released
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("FAST CYCLE OFF"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("FAST CYCLE OFF"));
|
||||
Serial.println(F("PRESS BUTTON TO STEP FORWARD"));
|
||||
Serial.println(F("DOUBLE CLICK TO STEP BACK"));
|
||||
Serial.println(F("HOLD TO SELECT"));
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
while (readVals_FAIRCHILD(fairchildgame, fairchildrr, fairchildll)) {
|
||||
if (strcmp(fairchildcsvEND, fairchildgame) == 0) {
|
||||
fairchildcsvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(fairchildgame);
|
||||
display.setCursor(0, 48);
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(fairchildgame);
|
||||
#endif
|
||||
while (1) { // Single Step
|
||||
int b = checkButton();
|
||||
if (b == 1) { // Continue (press)
|
||||
break;
|
||||
}
|
||||
if (b == 2) { // Reset to Start of List (doubleclick)
|
||||
byte prevline = strtol(fairchildll, NULL, 10);
|
||||
fairchildcsvpos -= prevline;
|
||||
fairchildcsvFile.seek(fairchildcsvpos);
|
||||
break;
|
||||
}
|
||||
if (b == 3) { // Long Press - Select Cart (hold)
|
||||
newfairchildsize = strtol(fairchildrr, NULL, 10);
|
||||
EEPROM_writeAnything(8, newfairchildsize);
|
||||
cartselected = 1; // SELECTION MADE
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F("SELECTION MADE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("SELECTION MADE"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartselected) {
|
||||
cartselected = 0; // Reset Flag
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("END OF FILE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("END OF FILE"));
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkCSV_FAIRCHILD() {
|
||||
if (getCartListInfo_FAIRCHILD()) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART SELECTED"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(fairchildgame);
|
||||
display_Update();
|
||||
// Display Settings
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("CODE: R"));
|
||||
println_Msg(newfairchildsize);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("CART SELECTED"));
|
||||
Serial.println(fairchildgame);
|
||||
// Display Settings
|
||||
Serial.print(F("CODE: R"));
|
||||
Serial.println(newfairchildsize);
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("NO SELECTION"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("NO SELECTION"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void setCart_FAIRCHILD() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(fairchildcartCSV);
|
||||
display_Update();
|
||||
#endif
|
||||
//go to root
|
||||
sd.chdir();
|
||||
sprintf(folder, "FAIRCHILD/CSV");
|
||||
sd.chdir(folder); // Switch Folder
|
||||
fairchildcsvFile = sd.open(fairchildcartCSV, O_READ);
|
||||
if (!fairchildcsvFile) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CSV FILE NOT FOUND!"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("CSV FILE NOT FOUND!"));
|
||||
#endif
|
||||
while (1) {
|
||||
if (checkButton() != 0)
|
||||
setup_FAIRCHILD();
|
||||
}
|
||||
}
|
||||
checkCSV_FAIRCHILD();
|
||||
|
||||
fairchildcsvFile.close();
|
||||
byte gameSize;
|
||||
|
||||
// Select starting letter
|
||||
//byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("fairchildcart.txt", O_READ)) {
|
||||
// seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
if(checkCartSelection(myFile, &readDataLineSingleDigit, &gameSize)) {
|
||||
EEPROM_writeAnything(8, gameSize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//******************************************
|
||||
|
|
File diff suppressed because it is too large
Load Diff
1607
Cart_Reader/GB.ino
1607
Cart_Reader/GB.ino
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +1,15 @@
|
|||
//******************************************
|
||||
// GAME BOY ADVANCE MODULE
|
||||
//******************************************
|
||||
#ifdef enable_GBX
|
||||
#ifdef ENABLE_GBX
|
||||
|
||||
/******************************************
|
||||
Menu
|
||||
*****************************************/
|
||||
// GBA menu items
|
||||
static const char GBAMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char GBAMenuItem2[] PROGMEM = "Read Save";
|
||||
static const char GBAMenuItem3[] PROGMEM = "Write Save";
|
||||
static const char GBAMenuItem4[] PROGMEM = "Force Savetype";
|
||||
static const char GBAMenuItem5[] PROGMEM = "Flash Repro";
|
||||
//static const char GBAMenuItem6[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsGBA[] PROGMEM = { GBAMenuItem1, GBAMenuItem2, GBAMenuItem3, GBAMenuItem4, GBAMenuItem5, string_reset2 };
|
||||
static const char* const menuOptionsGBA[] PROGMEM = { FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, GBAMenuItem4, GBAMenuItem5, FSTRING_RESET };
|
||||
|
||||
// Rom menu
|
||||
static const char GBARomItem1[] PROGMEM = "1 MB";
|
||||
|
@ -66,7 +62,7 @@ void gbaMenu() {
|
|||
compare_checksum_GBA();
|
||||
// CRC32
|
||||
compareCRC("gba.txt", 0, 1, 0);
|
||||
#ifdef global_log
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
save_log();
|
||||
#endif
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
|
@ -116,7 +112,7 @@ void gbaMenu() {
|
|||
break;
|
||||
}
|
||||
setROM_GBA();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -162,7 +158,7 @@ void gbaMenu() {
|
|||
printFlashTypeAndWait(F("Panasonic MN63F805MNP"));
|
||||
} else {
|
||||
printFlashTypeAndWait(F("Unknown"));
|
||||
//print_FatalError(F(""));
|
||||
//print_FatalError(FSTRING_EMPTY);
|
||||
}
|
||||
|
||||
if (flashid == 0x1F3D) { // Atmel
|
||||
|
@ -188,7 +184,7 @@ void gbaMenu() {
|
|||
printFlashTypeAndWait(F("SANYO LE26FV10N1TS"));
|
||||
} else {
|
||||
printFlashTypeAndWait(F("Unknown"));
|
||||
//print_FatalError(F(""));
|
||||
//print_FatalError(FSTRING_EMPTY);
|
||||
}
|
||||
|
||||
eraseFLASH_GBA();
|
||||
|
@ -211,7 +207,7 @@ void gbaMenu() {
|
|||
break;
|
||||
}
|
||||
setROM_GBA();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -228,7 +224,7 @@ void gbaMenu() {
|
|||
case 4:
|
||||
display_Clear();
|
||||
flashRepro_GBA();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -256,7 +252,7 @@ void setup_GBA() {
|
|||
display_Clear();
|
||||
|
||||
// Print start page
|
||||
print_Msg(F("Title: "));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
print_Msg(F("Serial: "));
|
||||
println_Msg(cartID);
|
||||
|
@ -326,10 +322,10 @@ static byte getSaveType() {
|
|||
static void printFlashTypeAndWait(const __FlashStringHelper* caption) {
|
||||
print_Msg(F("FLASH ID: "));
|
||||
println_Msg(flashid_str);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("FLASH Type: "));
|
||||
println_Msg(caption);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -471,7 +467,7 @@ void writeWord_GAB(unsigned long myAddress, word myWord) {
|
|||
writeWord_GBA(myAddress, swapBits(myWord, 0, 1));
|
||||
}
|
||||
|
||||
byte readByte_GBA(unsigned long myAddress) {
|
||||
byte readByte_GBA(uint16_t myAddress) {
|
||||
// Set address ports to output
|
||||
DDRF = 0xFF;
|
||||
DDRK = 0xFF;
|
||||
|
@ -508,7 +504,7 @@ byte readByte_GBA(unsigned long myAddress) {
|
|||
return tempByte;
|
||||
}
|
||||
|
||||
void writeByte_GBA(unsigned long myAddress, byte myData) {
|
||||
void writeByte_GBA(uint16_t myAddress, byte myData) {
|
||||
// Set address ports to output
|
||||
DDRF = 0xFF;
|
||||
DDRK = 0xFF;
|
||||
|
@ -599,17 +595,17 @@ void getCartInfo_GBA() {
|
|||
display_Clear();
|
||||
print_Error(F("CARTRIDGE ERROR"));
|
||||
strcpy(romName, "ERROR");
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("Press Button to"));
|
||||
println_Msg(F("ignore or powercycle"));
|
||||
println_Msg(F("to try again"));
|
||||
display_Update();
|
||||
wait();
|
||||
} else {
|
||||
char tempStr2[2];
|
||||
char tempStr[5];
|
||||
tempStr[4] = 0;
|
||||
|
||||
// cart not in list
|
||||
cartSize = 0;
|
||||
|
@ -630,7 +626,7 @@ void getCartInfo_GBA() {
|
|||
if (myFile.open("gba.txt", O_READ)) {
|
||||
char gamename[100];
|
||||
|
||||
#ifdef global_log
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
// Disable log to prevent unnecessary logging
|
||||
dont_log = true;
|
||||
#endif
|
||||
|
@ -644,10 +640,8 @@ void getCartInfo_GBA() {
|
|||
myFile.seekCur(9);
|
||||
|
||||
// Read 4 bytes into String, do it one at a time so byte order doesn't get mixed up
|
||||
sprintf(tempStr, "%c", myFile.read());
|
||||
for (byte i = 0; i < 3; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(tempStr, tempStr2);
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
tempStr[i] = char(myFile.read());
|
||||
}
|
||||
|
||||
// Check if string is a match
|
||||
|
@ -666,23 +660,15 @@ void getCartInfo_GBA() {
|
|||
myFile.seekCur(9);
|
||||
|
||||
// Read 4 bytes into String, do it one at a time so byte order doesn't get mixed up
|
||||
sprintf(tempStr, "%c", myFile.read());
|
||||
for (byte i = 0; i < 3; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(tempStr, tempStr2);
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
tempStr[i] = char(myFile.read());
|
||||
}
|
||||
|
||||
// Skip the , in the file
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
cartSize = myFile.read() - 48;
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
cartSize = ((myFile.read() - 48) * 10) + (myFile.read() - 48);
|
||||
|
||||
// Skip the , in the file
|
||||
myFile.seekCur(1);
|
||||
|
@ -703,21 +689,9 @@ void getCartInfo_GBA() {
|
|||
print_Msg(F("Save Lib: "));
|
||||
println_Msg(saveTypeStr);
|
||||
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
println_Msg(F(""));
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
printInstructions();
|
||||
|
||||
int b = 0;
|
||||
uint8_t b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
@ -754,7 +728,7 @@ void getCartInfo_GBA() {
|
|||
// Close the file:
|
||||
myFile.close();
|
||||
|
||||
#ifdef global_log
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
// Enable log again
|
||||
dont_log = false;
|
||||
#endif
|
||||
|
@ -785,7 +759,7 @@ void getCartInfo_GBA() {
|
|||
sprintf(calcChecksumStr, "%02X", calcChecksum);
|
||||
println_Msg(calcChecksumStr);
|
||||
print_Error(F("Checksum Error"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -847,30 +821,7 @@ void getCartInfo_GBA() {
|
|||
// Dump ROM
|
||||
void readROM_GBA() {
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".gba");
|
||||
|
||||
// create a new folder for the rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "GBA/ROM/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
//clear the screen
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
//open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(create_file_STR);
|
||||
}
|
||||
createFolderAndOpenFile("GBA", "ROM", romName, "gba");
|
||||
|
||||
//Initialize progress bar
|
||||
uint32_t processedProgressBar = 0;
|
||||
|
@ -914,7 +865,7 @@ void readROM_GBA() {
|
|||
|
||||
// Calculate the checksum of the dumped rom
|
||||
boolean compare_checksum_GBA() {
|
||||
print_Msg(F("Checksum: "));
|
||||
print_Msg(FS(FSTRING_CHECKSUM));
|
||||
display_Update();
|
||||
|
||||
strcpy(fileName, romName);
|
||||
|
@ -958,26 +909,11 @@ boolean compare_checksum_GBA() {
|
|||
/******************************************
|
||||
GBA SRAM SAVE Functions
|
||||
*****************************************/
|
||||
void readSRAM_GBA(boolean browseFile, unsigned long sramSize, uint32_t pos) {
|
||||
void readSRAM_GBA(boolean browseFile, uint32_t sramSize, uint32_t pos) {
|
||||
if (browseFile) {
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".srm");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "GBA/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
// Save location
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolder("GBA", "SAVE", romName, "srm");
|
||||
printAndIncrementFolder();
|
||||
}
|
||||
|
||||
//open file on sd card
|
||||
|
@ -989,7 +925,7 @@ void readSRAM_GBA(boolean browseFile, unsigned long sramSize, uint32_t pos) {
|
|||
if (pos != 0)
|
||||
myFile.seekCur(pos);
|
||||
|
||||
for (unsigned long currAddress = 0; currAddress < sramSize; currAddress += 512) {
|
||||
for (uint32_t currAddress = 0; currAddress < sramSize; currAddress += 512) {
|
||||
for (int c = 0; c < 512; c++) {
|
||||
// Read byte
|
||||
sdBuffer[c] = readByte_GBA(currAddress + c);
|
||||
|
@ -1006,7 +942,7 @@ void readSRAM_GBA(boolean browseFile, unsigned long sramSize, uint32_t pos) {
|
|||
display_Update();
|
||||
}
|
||||
|
||||
void writeSRAM_GBA(boolean browseFile, unsigned long sramSize, uint32_t pos) {
|
||||
void writeSRAM_GBA(boolean browseFile, uint32_t sramSize, uint32_t pos) {
|
||||
if (browseFile) {
|
||||
filePath[0] = '\0';
|
||||
sd.chdir("/");
|
||||
|
@ -1023,7 +959,7 @@ void writeSRAM_GBA(boolean browseFile, unsigned long sramSize, uint32_t pos) {
|
|||
if (pos != 0)
|
||||
myFile.seekCur(pos);
|
||||
|
||||
for (unsigned long currAddress = 0; currAddress < sramSize; currAddress += 512) {
|
||||
for (uint32_t currAddress = 0; currAddress < sramSize; currAddress += 512) {
|
||||
//fill sdBuffer
|
||||
myFile.read(sdBuffer, 512);
|
||||
|
||||
|
@ -1038,7 +974,7 @@ void writeSRAM_GBA(boolean browseFile, unsigned long sramSize, uint32_t pos) {
|
|||
display_Update();
|
||||
|
||||
} else {
|
||||
print_Error(F("File doesnt exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1102,28 +1038,8 @@ void readFRAM_GBA(unsigned long framSize) {
|
|||
PORTH &= ~((1 << 0) | (1 << 6));
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".srm");
|
||||
createFolderAndOpenFile("GBA", "SAVE", romName, "srm");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "GBA/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
// Save location
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
//open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(sd_error_STR);
|
||||
}
|
||||
for (unsigned long currAddress = 0; currAddress < framSize; currAddress += 512) {
|
||||
for (int c = 0; c < 512; c++) {
|
||||
// Pull OE_SRAM(PH6) HIGH
|
||||
|
@ -1225,7 +1141,7 @@ void writeFRAM_GBA(boolean browseFile, unsigned long framSize) {
|
|||
display_Update();
|
||||
|
||||
} else {
|
||||
print_Error(F("File doesnt exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1294,8 +1210,7 @@ unsigned long verifyFRAM_GBA(unsigned long framSize) {
|
|||
/******************************************
|
||||
GBA FLASH SAVE Functions
|
||||
*****************************************/
|
||||
// SST 39VF512 Flashrom
|
||||
void idFlash_GBA() {
|
||||
void initOutputFlash_GBA() {
|
||||
// Output a HIGH signal on CS_ROM(PH3) WE_FLASH(PH5) and OE_FLASH(PH6)
|
||||
PORTH |= (1 << 3) | (1 << 5) | (1 << 6);
|
||||
|
||||
|
@ -1307,6 +1222,11 @@ void idFlash_GBA() {
|
|||
|
||||
// Output a LOW signal on CE_FLASH(PH0)
|
||||
PORTH &= ~(1 << 0);
|
||||
}
|
||||
|
||||
// SST 39VF512 Flashrom
|
||||
void idFlash_GBA() {
|
||||
initOutputFlash_GBA();
|
||||
|
||||
// ID command sequence
|
||||
writeByteFlash_GBA(0x5555, 0xaa);
|
||||
|
@ -1336,17 +1256,7 @@ void idFlash_GBA() {
|
|||
|
||||
// Reset FLASH
|
||||
void resetFLASH_GBA() {
|
||||
// Output a HIGH signal on CS_ROM(PH3) WE_FLASH(PH5) and OE_FLASH(PH6)
|
||||
PORTH |= (1 << 3) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set address ports to output
|
||||
DDRF = 0xFF;
|
||||
DDRK = 0xFF;
|
||||
// Set data pins to output
|
||||
DDRC = 0xFF;
|
||||
|
||||
// Output a LOW signal on CE_FLASH(PH0)
|
||||
PORTH &= ~(1 << 0);
|
||||
initOutputFlash_GBA();
|
||||
|
||||
// Reset command sequence
|
||||
writeByteFlash_GBA(0x5555, 0xAA);
|
||||
|
@ -1361,7 +1271,7 @@ void resetFLASH_GBA() {
|
|||
delay(100);
|
||||
}
|
||||
|
||||
byte readByteFlash_GBA(unsigned long myAddress) {
|
||||
byte readByteFlash_GBA(uint16_t myAddress) {
|
||||
// Set address
|
||||
PORTF = myAddress & 0xFF;
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
|
@ -1384,7 +1294,7 @@ byte readByteFlash_GBA(unsigned long myAddress) {
|
|||
return tempByte;
|
||||
}
|
||||
|
||||
void writeByteFlash_GBA(unsigned long myAddress, byte myData) {
|
||||
void writeByteFlash_GBA(uint16_t myAddress, byte myData) {
|
||||
PORTF = myAddress & 0xFF;
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
PORTC = myData;
|
||||
|
@ -1417,17 +1327,7 @@ void writeByteFlash_GBA(unsigned long myAddress, byte myData) {
|
|||
|
||||
// Erase FLASH
|
||||
void eraseFLASH_GBA() {
|
||||
// Output a HIGH signal on CS_ROM(PH3) WE_FLASH(PH5) and OE_FLASH(PH6)
|
||||
PORTH |= (1 << 3) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set address ports to output
|
||||
DDRF = 0xFF;
|
||||
DDRK = 0xFF;
|
||||
// Set data pins to output
|
||||
DDRC = 0xFF;
|
||||
|
||||
// Output a LOW signal on CE_FLASH(PH0)
|
||||
PORTH &= ~(1 << 0);
|
||||
initOutputFlash_GBA();
|
||||
|
||||
// Erase command sequence
|
||||
writeByteFlash_GBA(0x5555, 0xaa);
|
||||
|
@ -1444,7 +1344,7 @@ void eraseFLASH_GBA() {
|
|||
delay(500);
|
||||
}
|
||||
|
||||
boolean blankcheckFLASH_GBA(unsigned long flashSize) {
|
||||
boolean blankcheckFLASH_GBA(uint32_t flashSize) {
|
||||
// Output a HIGH signal on CS_ROM(PH3) WE_FLASH(PH5)
|
||||
PORTH |= (1 << 3) | (1 << 5);
|
||||
|
||||
|
@ -1468,14 +1368,14 @@ boolean blankcheckFLASH_GBA(unsigned long flashSize) {
|
|||
// Output a LOW signal on OE_FLASH(PH6)
|
||||
PORTH &= ~(1 << 6);
|
||||
|
||||
for (unsigned long currAddress = 0; currAddress < flashSize; currAddress += 512) {
|
||||
for (uint32_t currAddress = 0; currAddress < flashSize; currAddress += 512) {
|
||||
// Fill buffer
|
||||
for (int c = 0; c < 512; c++) {
|
||||
// Read byte
|
||||
sdBuffer[c] = readByteFlash_GBA(currAddress + c);
|
||||
}
|
||||
// Check buffer
|
||||
for (unsigned long currByte = 0; currByte < 512; currByte++) {
|
||||
for (uint32_t currByte = 0; currByte < 512; currByte++) {
|
||||
if (sdBuffer[currByte] != 0xFF) {
|
||||
print_Error(F("Erase failed"));
|
||||
currByte = 512;
|
||||
|
@ -1494,17 +1394,7 @@ boolean blankcheckFLASH_GBA(unsigned long flashSize) {
|
|||
// each sector is 4096 bytes, there are 32 sectors total
|
||||
// therefore the bank size is 65536 bytes, so we have two banks in total
|
||||
void switchBank_GBA(byte bankNum) {
|
||||
// Output a HIGH signal on CS_ROM(PH3) WE_FLASH(PH5) and OE_FLASH(PH6)
|
||||
PORTH |= (1 << 3) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set address ports to output
|
||||
DDRF = 0xFF;
|
||||
DDRK = 0xFF;
|
||||
// Set data pins to output
|
||||
DDRC = 0xFF;
|
||||
|
||||
// Output a LOW signal on CE_FLASH(PH0)
|
||||
PORTH &= ~(1 << 0);
|
||||
initOutputFlash_GBA();
|
||||
|
||||
// Switch bank command sequence
|
||||
writeByte_GBA(0x5555, 0xAA);
|
||||
|
@ -1516,7 +1406,7 @@ void switchBank_GBA(byte bankNum) {
|
|||
PORTH |= (1 << 0);
|
||||
}
|
||||
|
||||
void readFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos) {
|
||||
void readFLASH_GBA(boolean browseFile, uint32_t flashSize, uint32_t pos) {
|
||||
// Output a HIGH signal on CS_ROM(PH3) WE_FLASH(PH5)
|
||||
PORTH |= (1 << 3) | (1 << 5);
|
||||
|
||||
|
@ -1532,25 +1422,9 @@ void readFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos) {
|
|||
|
||||
if (browseFile) {
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".fla");
|
||||
createFolder("GBA", "SAVE", romName, "fla");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
|
||||
sprintf(folder, "GBA/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
// Save location
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
printAndIncrementFolder();
|
||||
}
|
||||
|
||||
//open file on sd card
|
||||
|
@ -1568,7 +1442,7 @@ void readFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos) {
|
|||
// Output a LOW signal on OE_FLASH(PH6)
|
||||
PORTH &= ~(1 << 6);
|
||||
|
||||
for (unsigned long currAddress = 0; currAddress < flashSize; currAddress += 512) {
|
||||
for (uint32_t currAddress = 0; currAddress < flashSize; currAddress += 512) {
|
||||
for (int c = 0; c < 512; c++) {
|
||||
// Read byte
|
||||
sdBuffer[c] = readByteFlash_GBA(currAddress + c);
|
||||
|
@ -1586,7 +1460,7 @@ void readFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos) {
|
|||
display_Update();
|
||||
}
|
||||
|
||||
void busyCheck_GBA(int currByte) {
|
||||
void busyCheck_GBA(uint16_t currByte) {
|
||||
// Set data pins to input
|
||||
DDRC = 0x00;
|
||||
// Output a LOW signal on OE_FLASH(PH6)
|
||||
|
@ -1599,7 +1473,7 @@ void busyCheck_GBA(int currByte) {
|
|||
DDRC = 0xFF;
|
||||
}
|
||||
|
||||
void writeFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos, boolean isAtmel) {
|
||||
void writeFLASH_GBA(boolean browseFile, uint32_t flashSize, uint32_t pos, boolean isAtmel) {
|
||||
// Output a HIGH signal on CS_ROM(PH3) WE_FLASH(PH5) and OE_FLASH(PH6)
|
||||
PORTH |= (1 << 3) | (1 << 5) | (1 << 6);
|
||||
|
||||
|
@ -1632,7 +1506,7 @@ void writeFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos, b
|
|||
PORTH &= ~(1 << 0);
|
||||
|
||||
if (!isAtmel) {
|
||||
for (unsigned long currAddress = 0; currAddress < flashSize; currAddress += 512) {
|
||||
for (uint32_t currAddress = 0; currAddress < flashSize; currAddress += 512) {
|
||||
//fill sdBuffer
|
||||
myFile.read(sdBuffer, 512);
|
||||
|
||||
|
@ -1649,7 +1523,7 @@ void writeFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos, b
|
|||
}
|
||||
}
|
||||
} else {
|
||||
for (unsigned long currAddress = 0; currAddress < flashSize; currAddress += 128) {
|
||||
for (uint32_t currAddress = 0; currAddress < flashSize; currAddress += 128) {
|
||||
//fill sdBuffer
|
||||
myFile.read(sdBuffer, 128);
|
||||
|
||||
|
@ -1673,12 +1547,12 @@ void writeFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos, b
|
|||
|
||||
} else {
|
||||
println_Msg(F("Error"));
|
||||
print_Error(F("File doesnt exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the Flashrom was written without any error
|
||||
unsigned long verifyFLASH_GBA(unsigned long flashSize, uint32_t pos) {
|
||||
unsigned long verifyFLASH_GBA(uint32_t flashSize, uint32_t pos) {
|
||||
// Output a HIGH signal on CS_ROM(PH3) WE_FLASH(PH5)
|
||||
PORTH |= (1 << 3) | (1 << 5);
|
||||
|
||||
|
@ -1723,7 +1597,7 @@ unsigned long verifyFLASH_GBA(unsigned long flashSize, uint32_t pos) {
|
|||
PORTH |= (1 << 0);
|
||||
|
||||
if (wrError == 0) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
} else {
|
||||
print_Msg(wrError);
|
||||
print_Error(F(" Errors"));
|
||||
|
@ -1769,32 +1643,16 @@ void writeEeprom_GBA(word eepSize) {
|
|||
display_Update();
|
||||
} else {
|
||||
println_Msg(F("Error"));
|
||||
print_Error(F("File doesnt exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
// Read eeprom to file
|
||||
void readEeprom_GBA(word eepSize) {
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".eep");
|
||||
createFolder("GBA", "SAVE", romName, "eep");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
|
||||
sprintf(folder, "GBA/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
// Save location
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
printAndIncrementFolder();
|
||||
|
||||
//open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
|
@ -2145,11 +2003,11 @@ void idFlashrom_GBA() {
|
|||
resetMX29GL128E_GBA();
|
||||
} else {
|
||||
println_Msg(F("Error"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("Unknown Flash"));
|
||||
print_Msg(F("Flash ID: "));
|
||||
println_Msg(flashid_str);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_FatalError(F("Check voltage"));
|
||||
}
|
||||
}
|
||||
|
@ -2591,7 +2449,7 @@ void flashRepro_GBA() {
|
|||
println_Msg("");
|
||||
println_Msg(F("This will erase your"));
|
||||
println_Msg(F("Repro Cartridge."));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg("");
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
|
@ -2649,7 +2507,7 @@ void flashRepro_GBA() {
|
|||
print_Msg(F("Blankcheck..."));
|
||||
display_Update();
|
||||
if (blankcheckFlashrom_GBA()) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
*/
|
||||
|
||||
//Write flashrom
|
||||
|
@ -2693,7 +2551,7 @@ void flashRepro_GBA() {
|
|||
delay(1000);
|
||||
}
|
||||
if (verifyFlashrom_GBA() == 1) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
print_FatalError(F("ERROR"));
|
||||
|
@ -2709,11 +2567,11 @@ void flashRepro_GBA() {
|
|||
}
|
||||
} else {
|
||||
println_Msg(F("Error"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("Unknown Flash"));
|
||||
print_Msg(F("Flash ID: "));
|
||||
println_Msg(flashid_str);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_FatalError(F("Check voltage"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// GB MEMORY MODULE
|
||||
//******************************************
|
||||
#ifdef enable_GBX
|
||||
#ifdef ENABLE_GBX
|
||||
|
||||
/******************************************
|
||||
Menu
|
||||
|
@ -86,7 +86,7 @@ void gbmMenu() {
|
|||
// Clear screen
|
||||
display_Clear();
|
||||
if (blankcheckFlash_GBM()) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
println_Msg(F("ERROR"));
|
||||
|
@ -162,7 +162,7 @@ void gbmMenu() {
|
|||
// Erase mapping
|
||||
eraseMapping_GBM();
|
||||
if (blankcheckMapping_GBM()) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
print_Error(F("Erasing failed"));
|
||||
|
@ -173,7 +173,7 @@ void gbmMenu() {
|
|||
writeMapping_GBM();
|
||||
break;
|
||||
}
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// GB SMART MODULE
|
||||
// Supports 32M cart with LH28F016SUT flash
|
||||
//******************************************
|
||||
#ifdef enable_GBX
|
||||
#ifdef ENABLE_GBX
|
||||
#define GB_SMART_GAMES_PER_PAGE 6
|
||||
|
||||
/******************************************
|
||||
|
@ -11,8 +11,7 @@
|
|||
// GB Smart menu items
|
||||
static const char gbSmartMenuItem1[] PROGMEM = "Game Menu";
|
||||
static const char gbSmartMenuItem2[] PROGMEM = "Flash Menu";
|
||||
//static const char gbSmartMenuItem3[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char *const menuOptionsGBSmart[] PROGMEM = { gbSmartMenuItem1, gbSmartMenuItem2, string_reset2 };
|
||||
static const char *const menuOptionsGBSmart[] PROGMEM = { gbSmartMenuItem1, gbSmartMenuItem2, FSTRING_RESET };
|
||||
|
||||
static const char gbSmartFlashMenuItem1[] PROGMEM = "Read Flash";
|
||||
static const char gbSmartFlashMenuItem2[] PROGMEM = "Write Flash";
|
||||
|
@ -20,11 +19,8 @@ static const char gbSmartFlashMenuItem3[] PROGMEM = "Back";
|
|||
static const char *const menuOptionsGBSmartFlash[] PROGMEM = { gbSmartFlashMenuItem1, gbSmartFlashMenuItem2, gbSmartFlashMenuItem3 };
|
||||
|
||||
static const char gbSmartGameMenuItem1[] PROGMEM = "Read Game";
|
||||
static const char gbSmartGameMenuItem2[] PROGMEM = "Read SRAM";
|
||||
static const char gbSmartGameMenuItem3[] PROGMEM = "Write SRAM";
|
||||
static const char gbSmartGameMenuItem4[] PROGMEM = "Switch Game";
|
||||
//static const char gbSmartGameMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char *const menuOptionsGBSmartGame[] PROGMEM = { gbSmartGameMenuItem1, gbSmartGameMenuItem2, gbSmartGameMenuItem3, gbSmartGameMenuItem4, string_reset2 };
|
||||
static const char *const menuOptionsGBSmartGame[] PROGMEM = { gbSmartGameMenuItem1, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, gbSmartGameMenuItem4, FSTRING_RESET };
|
||||
|
||||
struct GBSmartGameInfo {
|
||||
uint8_t start_bank;
|
||||
|
@ -163,7 +159,7 @@ void gbSmartMenu() {
|
|||
}
|
||||
case 1:
|
||||
{
|
||||
mode = mode_GB_GBSmart_Flash;
|
||||
mode = CORE_GB_GBSMART_FLASH;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -227,7 +223,7 @@ void gbSmartGameOptions() {
|
|||
}
|
||||
|
||||
if (gameSubMenu != 3) {
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -269,7 +265,7 @@ gb_smart_load_more_games:
|
|||
getCartInfo_GB();
|
||||
showCartInfo_GB();
|
||||
|
||||
mode = mode_GB_GBSmart_Game;
|
||||
mode = CORE_GB_GBSMART_GAME;
|
||||
}
|
||||
|
||||
void gbSmartFlashMenu() {
|
||||
|
@ -303,7 +299,7 @@ void gbSmartFlashMenu() {
|
|||
println_Msg(F("Attention"));
|
||||
println_Msg(F("This will erase your"));
|
||||
println_Msg(F("GB Smart Cartridge."));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -320,12 +316,12 @@ void gbSmartFlashMenu() {
|
|||
}
|
||||
default:
|
||||
{
|
||||
mode = mode_GB_GBSmart;
|
||||
mode = CORE_GB_GBSMART;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -476,7 +472,7 @@ void gbSmartWriteFlash() {
|
|||
|
||||
writeErrors = gbSmartVerifyFlash();
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
print_STR(error_STR, 0);
|
||||
|
|
398
Cart_Reader/GPC.ino
Normal file
398
Cart_Reader/GPC.ino
Normal file
|
@ -0,0 +1,398 @@
|
|||
//******************************************
|
||||
// SNES Game Processor RAM Cassette code by LuigiBlood
|
||||
// Revision 1.0.0 February 2024
|
||||
//******************************************
|
||||
#ifdef ENABLE_GPC
|
||||
|
||||
/******************************************
|
||||
Game Processor RAM Cassette
|
||||
******************************************/
|
||||
/******************************************
|
||||
Prototype Declarations
|
||||
*****************************************/
|
||||
/* Hoping that sanni will use this progressbar function */
|
||||
extern void draw_progressbar(uint32_t processedsize, uint32_t totalsize);
|
||||
|
||||
//void gpcMenu();
|
||||
void readRAM_GPC();
|
||||
//void setup_GPC();
|
||||
void writeRAM_GPC(void);
|
||||
|
||||
/******************************************
|
||||
Variables
|
||||
*****************************************/
|
||||
//No global variables
|
||||
|
||||
/******************************************
|
||||
Menu
|
||||
*****************************************/
|
||||
// GPC flash menu items
|
||||
static const char gpcFlashMenuItem1[] PROGMEM = "Read RAM";
|
||||
static const char gpcFlashMenuItem2[] PROGMEM = "Write RAM";
|
||||
static const char* const menuOptionsGPCFlash[] PROGMEM = { gpcFlashMenuItem1, gpcFlashMenuItem2, FSTRING_RESET };
|
||||
|
||||
|
||||
void gpcMenu() {
|
||||
// create menu with title and 3 options to choose from
|
||||
unsigned char mainMenu;
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(menuOptionsGPCFlash, 3);
|
||||
mainMenu = question_box(F("Game Processor RAM"), menuOptions, 3, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu) {
|
||||
// Read ram
|
||||
case 0:
|
||||
// Change working dir to root
|
||||
sd.chdir("/");
|
||||
readRAM_GPC();
|
||||
break;
|
||||
|
||||
// Write ram
|
||||
case 1:
|
||||
// Change working dir to root
|
||||
sd.chdir("/");
|
||||
writeRAM_GPC();
|
||||
unsigned long wrErrors;
|
||||
wrErrors = verifyRAM_GPC();
|
||||
if (wrErrors == 0) {
|
||||
println_Msg(F("Verified OK"));
|
||||
display_Update();
|
||||
} else {
|
||||
print_STR(error_STR, 0);
|
||||
print_Msg(wrErrors);
|
||||
print_STR(_bytes_STR, 1);
|
||||
print_Error(did_not_verify_STR);
|
||||
}
|
||||
wait();
|
||||
break;
|
||||
|
||||
// Reset
|
||||
case 2:
|
||||
resetArduino();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************
|
||||
Setup
|
||||
*****************************************/
|
||||
void setup_GPC() {
|
||||
// Request 5V
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
|
||||
// Set cicrstPin(PG1) to Output
|
||||
DDRG |= (1 << 1);
|
||||
// Output a high signal until we're ready to start
|
||||
PORTG |= (1 << 1);
|
||||
// Set cichstPin(PG0) to Input
|
||||
DDRG &= ~(1 << 0);
|
||||
|
||||
// Adafruit Clock Generator
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
|
||||
if (i2c_found) {
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB);
|
||||
clockgen.set_freq(2147727200ULL, SI5351_CLK0);
|
||||
clockgen.set_freq(307200000ULL, SI5351_CLK2);
|
||||
clockgen.output_enable(SI5351_CLK0, 1);
|
||||
clockgen.output_enable(SI5351_CLK1, 0);
|
||||
clockgen.output_enable(SI5351_CLK2, 1);
|
||||
}
|
||||
#ifdef ENABLE_CLOCKGEN
|
||||
else {
|
||||
display_Clear();
|
||||
print_FatalError(F("Clock Generator not found"));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set Address Pins to Output
|
||||
//A0-A7
|
||||
DDRF = 0xFF;
|
||||
//A8-A15
|
||||
DDRK = 0xFF;
|
||||
//BA0-BA7
|
||||
DDRL = 0xFF;
|
||||
//PA0-PA7
|
||||
DDRA = 0xFF;
|
||||
|
||||
// Set Control Pins to Output RST(PH0) CS(PH3) WR(PH5) RD(PH6)
|
||||
DDRH |= (1 << 0) | (1 << 3) | (1 << 5) | (1 << 6);
|
||||
// Switch RST(PH0) and WR(PH5) to HIGH
|
||||
PORTH |= (1 << 0) | (1 << 5);
|
||||
// Switch CS(PH3) and RD(PH6) to LOW
|
||||
PORTH &= ~((1 << 3) | (1 << 6));
|
||||
|
||||
// Set Refresh(PE5) to Output
|
||||
DDRE |= (1 << 5);
|
||||
// Switch Refresh(PE5) to LOW (needed for SA-1)
|
||||
PORTE &= ~(1 << 5);
|
||||
|
||||
// Set CPU Clock(PH1) to Output
|
||||
DDRH |= (1 << 1);
|
||||
//PORTH &= ~(1 << 1);
|
||||
|
||||
// Set IRQ(PH4) to Input
|
||||
DDRH &= ~(1 << 4);
|
||||
// Activate Internal Pullup Resistors
|
||||
//PORTH |= (1 << 4);
|
||||
|
||||
// Set expand(PG5) to output
|
||||
DDRG |= (1 << 5);
|
||||
// Output High
|
||||
PORTG |= (1 << 5);
|
||||
|
||||
// Set Data Pins (D0-D7) to Input
|
||||
DDRC = 0x00;
|
||||
// Enable Internal Pullups
|
||||
//PORTC = 0xFF;
|
||||
|
||||
// Unused pins
|
||||
// Set wram(PE4) to Output
|
||||
DDRE |= (1 << 4);
|
||||
//PORTE &= ~(1 << 4);
|
||||
// Set pawr(PJ1) to Output
|
||||
DDRJ |= (1 << 1);
|
||||
//PORTJ &= ~(1 << 1);
|
||||
// Set pard(PJ0) to Output
|
||||
DDRJ |= (1 << 0);
|
||||
//PORTJ &= ~(1 << 0);
|
||||
|
||||
// Start CIC by outputting a low signal to cicrstPin(PG1)
|
||||
PORTG &= ~(1 << 1);
|
||||
|
||||
// Wait for CIC reset
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
/******************************************
|
||||
Low level functions
|
||||
*****************************************/
|
||||
// Write one byte of data to a location specified by bank and address, 00:0000
|
||||
void writeBank_GPC(byte myBank, word myAddress, byte myData) {
|
||||
PORTL = myBank;
|
||||
PORTF = myAddress & 0xFF;
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
PORTC = myData;
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
||||
// Wait till output is stable
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Switch WR(PH5) to LOW
|
||||
PORTH &= ~(1 << 5);
|
||||
|
||||
// Leave WR low for at least 60ns
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Switch WR(PH5) to HIGH
|
||||
PORTH |= (1 << 5);
|
||||
|
||||
// Leave WR high for at least 50ns
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
}
|
||||
|
||||
// Read one byte of data from a location specified by bank and address, 00:0000
|
||||
byte readBank_GPC(byte myBank, word myAddress) {
|
||||
PORTL = myBank;
|
||||
PORTF = myAddress & 0xFF;
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Read
|
||||
byte tempByte = PINC;
|
||||
return tempByte;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
Game Processor RAM Cassette functions
|
||||
*****************************************/
|
||||
// Read RAM cassette to SD card
|
||||
void readRAM_GPC() {
|
||||
// Set control
|
||||
dataIn();
|
||||
controlIn_SNES();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
createFolderAndOpenFile("SNES", "ROM", "GPC4M", "sfc");
|
||||
|
||||
// Read Banks
|
||||
for (int currBank = 0xC0; currBank < 0xC8; currBank++) {
|
||||
// Dump the bytes to SD 512B at a time
|
||||
for (long currByte = 0; currByte < 65536; currByte += 512) {
|
||||
draw_progressbar((currBank - 0xC0) * 0x10000 + currByte, 0x80000);
|
||||
for (int c = 0; c < 512; c++) {
|
||||
sdBuffer[c] = readBank_GPC(currBank, currByte + c);
|
||||
}
|
||||
myFile.write(sdBuffer, 512);
|
||||
}
|
||||
}
|
||||
draw_progressbar(0x80000, 0x80000); //Finish drawing progress bar
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F("Read ram completed"));
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
|
||||
void writeRAM_GPC(void) {
|
||||
//Display file Browser and wait user to select a file. Size must be 512KB.
|
||||
filePath[0] = '\0';
|
||||
sd.chdir("/");
|
||||
fileBrowser(F("Select SFC file"));
|
||||
// Create filepath
|
||||
sprintf(filePath, "%s/%s", filePath, fileName);
|
||||
display_Clear();
|
||||
|
||||
//open file on sd card
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
|
||||
fileSize = myFile.fileSize();
|
||||
if (fileSize != 0x80000) {
|
||||
println_Msg(F("File must be 512KB"));
|
||||
display_Update();
|
||||
myFile.close();
|
||||
wait();
|
||||
return;
|
||||
}
|
||||
|
||||
//Disable ram cassette write protection
|
||||
dataOut();
|
||||
controlOut_SNES();
|
||||
for (int countProtect = 0; countProtect < 15; countProtect++) {
|
||||
writeBank_GPC(0x20, 0x6000, 0x00);
|
||||
}
|
||||
|
||||
//Write ram
|
||||
dataOut();
|
||||
controlOut_SNES();
|
||||
println_Msg(F("Writing ram..."));
|
||||
display_Update();
|
||||
for (int currBank = 0xC0; currBank < 0xC8; currBank++) {
|
||||
//startAddr = 0x0000
|
||||
for (long currByte = 0x0000; currByte < 0x10000; currByte += 512) {
|
||||
myFile.read(sdBuffer, 512);
|
||||
for (unsigned long c = 0; c < 512; c++) {
|
||||
//startBank = 0x10; CS low
|
||||
writeBank_GPC(currBank, currByte + c, sdBuffer[c]);
|
||||
}
|
||||
}
|
||||
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x80000);
|
||||
}
|
||||
|
||||
//reenable write protection
|
||||
dataIn();
|
||||
controlIn_SNES();
|
||||
byte keepByte = readBank_GPC(0x20, 0x6000);
|
||||
delay(100);
|
||||
dataOut();
|
||||
controlOut_SNES();
|
||||
writeBank_GPC(0x20, 0x6000, keepByte);
|
||||
|
||||
draw_progressbar(0x80000, 0x80000);
|
||||
delay(100);
|
||||
// Set pins to input
|
||||
dataIn();
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg("");
|
||||
println_Msg(F("RAM writing finished"));
|
||||
display_Update();
|
||||
} else {
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the RAM was written without any error
|
||||
unsigned long verifyRAM_GPC() {
|
||||
//open file on sd card
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
// Variable for errors
|
||||
writeErrors = 0;
|
||||
|
||||
// Set control
|
||||
controlIn_SNES();
|
||||
|
||||
//startBank = 0xC0; endBank = 0xC7; CS low
|
||||
for (byte currBank = 0xC0; currBank < 0xC8; currBank++) {
|
||||
//startAddr = 0x0000
|
||||
for (long currByte = 0x0000; currByte < 0x10000; currByte += 512) {
|
||||
//fill sdBuffer
|
||||
myFile.read(sdBuffer, 512);
|
||||
for (unsigned long c = 0; c < 512; c++) {
|
||||
if ((readBank_GPC(currBank, currByte + c)) != sdBuffer[c]) {
|
||||
writeErrors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
return writeErrors;
|
||||
} else {
|
||||
print_Error(F("Can't open file"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//******************************************
|
||||
// End of File
|
||||
//******************************************
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// INTELLIVISION MODULE
|
||||
//******************************************
|
||||
#ifdef enable_INTV
|
||||
#ifdef ENABLE_INTV
|
||||
|
||||
// Mattel Intellivision
|
||||
// Cartridge Pinout
|
||||
|
@ -80,9 +80,7 @@ byte intvlo = 0; // Lowest Entry
|
|||
byte intvhi = 5; // Highest Entry
|
||||
|
||||
byte intvmapper;
|
||||
byte newintvmapper;
|
||||
byte intvsize;
|
||||
byte newintvsize;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 07 MAPPER
|
||||
|
@ -92,11 +90,7 @@ byte newintvsize;
|
|||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char intvMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char intvMenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char intvMenuItem3[] PROGMEM = "Set Mapper + Size";
|
||||
//static const char intvMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsINTV[] PROGMEM = { intvMenuItem1, intvMenuItem2, intvMenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsINTV[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, FSTRING_SET_SIZE, FSTRING_RESET };
|
||||
|
||||
void setup_INTV() {
|
||||
// Request 5V
|
||||
|
@ -134,7 +128,7 @@ void setup_INTV() {
|
|||
checkStatus_INTV();
|
||||
strcpy(romName, "INTV");
|
||||
|
||||
mode = mode_INTV;
|
||||
mode = CORE_INTV;
|
||||
}
|
||||
|
||||
void intvMenu() {
|
||||
|
@ -309,28 +303,7 @@ void readSegment_INTV(uint32_t startaddr, uint32_t endaddr) {
|
|||
|
||||
// MODIFIED READ ROUTINE FOR ALL 10 MAPPERS
|
||||
void readROM_INTV() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".int");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "INTV/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("INTV", "ROM", romName, "int");
|
||||
|
||||
switch (intvmapper) {
|
||||
case 0: //default mattel up to 32K (8K/12K/16K/24K/32K)
|
||||
|
@ -428,7 +401,7 @@ void readROM_INTV() {
|
|||
// Compare CRC32 to database and rename ROM if found
|
||||
compareCRC("intv.txt", 0, 1, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -488,113 +461,22 @@ void ecsBank(uint32_t addr, uint8_t bank) {
|
|||
//******************************************
|
||||
// MAPPER CODE
|
||||
//******************************************
|
||||
|
||||
void setMapper_INTV() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
int b = 0;
|
||||
int i = 0;
|
||||
// Check Button Status
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Pressed
|
||||
while (1) { // Scroll Mapper List
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
// Correct Overshoot
|
||||
if (i == 0)
|
||||
i = intvmapcount - 1;
|
||||
else
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
intvindex = i * 4;
|
||||
intvmapselect = pgm_read_byte(intvmapsize + intvindex);
|
||||
println_Msg(intvmapselect);
|
||||
display_Update();
|
||||
if (i == (intvmapcount - 1))
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
delay(250);
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printMapperSelection_INTV(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
intvindex = i * 4;
|
||||
print_Msg(FS(FSTRING_MAPPER));
|
||||
intvindex = index * 4;
|
||||
intvmapselect = pgm_read_byte(intvmapsize + intvindex);
|
||||
println_Msg(intvmapselect);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
}
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
|
||||
if (b == 2) { // Previous Mapper (doubleclick)
|
||||
if (i == 0)
|
||||
i = intvmapcount - 1;
|
||||
else
|
||||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
intvindex = i * 4;
|
||||
intvmapselect = pgm_read_byte(intvmapsize + intvindex);
|
||||
println_Msg(intvmapselect);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next Mapper (press)
|
||||
if (i == (intvmapcount - 1))
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
intvindex = i * 4;
|
||||
intvmapselect = pgm_read_byte(intvmapsize + intvindex);
|
||||
println_Msg(intvmapselect);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newintvmapper = intvmapselect;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void setMapper_INTV() {
|
||||
byte newintvmapper;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
navigateMenu(0, intvmapcount - 1, &printMapperSelection_INTV);
|
||||
newintvmapper = intvmapselect;
|
||||
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("MAPPER "));
|
||||
print_Msg(newintvmapper);
|
||||
|
@ -618,7 +500,7 @@ setmapper:
|
|||
}
|
||||
if (intvmapfound == false) {
|
||||
Serial.println(F("MAPPER NOT SUPPORTED!"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
newintvmapper = 0;
|
||||
goto setmapper;
|
||||
}
|
||||
|
@ -639,78 +521,26 @@ void checkMapperSize_INTV() {
|
|||
}
|
||||
}
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRomSize_INTV(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_byte(&(INTV[index])));
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_INTV() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte newintvsize;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (intvlo == intvhi)
|
||||
newintvsize = intvlo;
|
||||
else {
|
||||
int b = 0;
|
||||
int i = intvlo;
|
||||
newintvsize = navigateMenu(intvlo, intvhi, &printRomSize_INTV);
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_byte(&(INTV[i])));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == intvlo)
|
||||
i = intvhi;
|
||||
else
|
||||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_byte(&(INTV[i])));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == intvhi)
|
||||
i = intvlo;
|
||||
else
|
||||
i++;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_byte(&(INTV[i])));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newintvsize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(pgm_read_byte(&(INTV[newintvsize])));
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -735,7 +565,7 @@ setrom:
|
|||
newintvsize = sizeROM.toInt() + intvlo;
|
||||
if (newintvsize > intvhi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
|
@ -759,14 +589,14 @@ void checkStatus_INTV() {
|
|||
EEPROM_writeAnything(8, intvsize);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("INTELLIVISION READER"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(F("MAPPER: "));
|
||||
println_Msg(intvmapper);
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(pgm_read_byte(&(INTV[intvsize])));
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -777,178 +607,115 @@ void checkStatus_INTV() {
|
|||
Serial.print(F("CURRENT ROM SIZE: "));
|
||||
Serial.print(pgm_read_byte(&(INTV[intvsize])));
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
void setCart_INTV() {
|
||||
char gamename[100];
|
||||
char tempStr2[2];
|
||||
struct database_entry_INTV {
|
||||
char crc_search[9];
|
||||
byte gameMapper;
|
||||
byte gameSize;
|
||||
};
|
||||
|
||||
void readDataLine_INTV(FsFile& database, void* entry) {
|
||||
struct database_entry_INTV* castEntry = (database_entry_INTV*)entry;
|
||||
// Read CRC32 checksum
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
checksumStr[i] = char(database.read());
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
castEntry->crc_search[i] = char(database.read());
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read mapper
|
||||
castEntry->gameMapper = database.read() - 48;
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
castEntry->gameSize = ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read SRAM size
|
||||
byte sramSize __attribute__((unused)) = database.read() - 48;
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void printDataLine_INTV(void* entry) {
|
||||
struct database_entry_INTV* castEntry = (database_entry_INTV*)entry;
|
||||
print_Msg(FS(FSTRING_SIZE));
|
||||
print_Msg(castEntry->gameSize);
|
||||
println_Msg(F("KB"));
|
||||
print_Msg(FS(FSTRING_MAPPER));
|
||||
println_Msg(castEntry->gameMapper);
|
||||
}
|
||||
|
||||
void setCart_INTV() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
struct database_entry_INTV entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("intv.txt", O_READ)) {
|
||||
// Skip ahead to selected starting letter
|
||||
if ((myLetter > 0) && (myLetter <= 26)) {
|
||||
while (myFile.available()) {
|
||||
// Read current name
|
||||
get_line(gamename, &myFile, 96);
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
// Compare selected letter with first letter of current name until match
|
||||
while (gamename[0] != 64 + myLetter) {
|
||||
skip_line(&myFile);
|
||||
skip_line(&myFile);
|
||||
get_line(gamename, &myFile, 96);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Rewind one line
|
||||
rewind_line(myFile);
|
||||
}
|
||||
|
||||
// Display database
|
||||
while (myFile.available()) {
|
||||
display_Clear();
|
||||
|
||||
// Read game name
|
||||
get_line(gamename, &myFile, 96);
|
||||
|
||||
// Read CRC32 checksum
|
||||
sprintf(checksumStr, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(checksumStr, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
sprintf(crc_search, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(crc_search, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read mapper
|
||||
intvmapper = myFile.read() - 48;
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
cartSize = myFile.read() - 48;
|
||||
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read SRAM size
|
||||
byte sramSize __attribute__((unused)) = myFile.read() - 48;
|
||||
|
||||
// Skip rest of line
|
||||
myFile.seekCur(2);
|
||||
|
||||
// Skip every 3rd line
|
||||
skip_line(&myFile);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(gamename);
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(cartSize);
|
||||
println_Msg(F("KB"));
|
||||
print_Msg(F("Mapper: "));
|
||||
println_Msg(intvmapper);
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
int b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
if(checkCartSelection(myFile, &readDataLine_INTV, &entry, &printDataLine_INTV)) {
|
||||
//byte INTV[] = {8, 12, 16, 24, 32, 48};
|
||||
switch (entry.gameSize) {
|
||||
case 8:
|
||||
intvsize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
rewind_line(myFile, 6);
|
||||
case 12:
|
||||
intvsize = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
//byte INTV[] = {8, 12, 16, 24, 32, 48};
|
||||
switch (cartSize) {
|
||||
case 8:
|
||||
intvsize = 0;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
intvsize = 1;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
intvsize = 2;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
intvsize = 3;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
intvsize = 4;
|
||||
break;
|
||||
|
||||
case 48:
|
||||
intvsize = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
intvsize = 0;
|
||||
break;
|
||||
}
|
||||
EEPROM_writeAnything(7, intvmapper);
|
||||
EEPROM_writeAnything(8, intvsize);
|
||||
myFile.close();
|
||||
case 16:
|
||||
intvsize = 2;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
intvsize = 3;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
intvsize = 4;
|
||||
break;
|
||||
|
||||
case 48:
|
||||
intvsize = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
intvsize = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EEPROM_writeAnything(7, entry.gameMapper);
|
||||
EEPROM_writeAnything(8, intvsize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(F("Database file not found"));
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
//
|
||||
// By @partlyhuman
|
||||
// Special thanks to @kasamikona
|
||||
#ifdef enable_LOOPY
|
||||
#ifdef ENABLE_LOOPY
|
||||
|
||||
// SH-1 memory map locations, ROM starts here
|
||||
const uint32_t LOOPY_MAP_ROM_ZERO = 0x0E000000;
|
||||
|
@ -109,7 +109,7 @@ void setup_LOOPY() {
|
|||
|
||||
getCartInfo_LOOPY();
|
||||
|
||||
mode = mode_LOOPY;
|
||||
mode = CORE_LOOPY;
|
||||
}
|
||||
|
||||
//******************************************
|
||||
|
@ -117,12 +117,8 @@ void setup_LOOPY() {
|
|||
//******************************************
|
||||
|
||||
// Base Menu
|
||||
static const char loopyMenuItem0[] PROGMEM = "Refresh Cart";
|
||||
static const char loopyMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char loopyMenuItem2[] PROGMEM = "Backup SRAM";
|
||||
static const char loopyMenuItem3[] PROGMEM = "Restore SRAM";
|
||||
static const char loopyMenuItem4[] PROGMEM = "Format SRAM";
|
||||
static const char* const menuOptionsLOOPY[] PROGMEM = { loopyMenuItem0, loopyMenuItem1, loopyMenuItem2, loopyMenuItem3, loopyMenuItem4, string_reset2 };
|
||||
static const char* const menuOptionsLOOPY[] PROGMEM = { FSTRING_REFRESH_CART, FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, loopyMenuItem4, FSTRING_RESET };
|
||||
|
||||
void loopyMenu() {
|
||||
convertPgm(menuOptionsLOOPY, 5);
|
||||
|
@ -188,10 +184,10 @@ void loopyMenu() {
|
|||
break;
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
if (waitForInput) {
|
||||
// Wait for user input
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -497,20 +493,20 @@ void getCartInfo_LOOPY() {
|
|||
setRomName_LOOPY("loopy.txt", checksumStr);
|
||||
|
||||
println_Msg(F("Cart Info"));
|
||||
println_Msg(F(" "));
|
||||
print_Msg(F("Name: "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(loopyRomNameLong);
|
||||
print_Msg(F("Checksum: "));
|
||||
print_Msg(FS(FSTRING_CHECKSUM));
|
||||
println_Msg(checksumStr);
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(FS(FSTRING_SIZE));
|
||||
print_Msg(cartSize * 8 / 1024 / 1024);
|
||||
println_Msg(F(" MBit"));
|
||||
print_Msg(F("Sram: "));
|
||||
print_Msg(sramSize * 8 / 1024);
|
||||
println_Msg(F(" KBit"));
|
||||
println_Msg(F(" "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#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);
|
||||
|
@ -526,25 +522,7 @@ void getCartInfo_LOOPY() {
|
|||
void readROM_LOOPY() {
|
||||
dataIn_LOOPY();
|
||||
|
||||
sprintf(fileName, "%s.bin", romName);
|
||||
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "LOOPY/ROM/%d", 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);
|
||||
}
|
||||
createFolderAndOpenFile("LOOPY", "ROM", romName, "bin");
|
||||
|
||||
draw_progressbar(0, cartSize);
|
||||
|
||||
|
@ -661,12 +639,7 @@ void formatSRAM_LOOPY() {
|
|||
void readSRAM_LOOPY() {
|
||||
dataIn_LOOPY();
|
||||
|
||||
sprintf(fileName, "%s.sav", romName);
|
||||
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "LOOPY/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("LOOPY", "SAVE", romName, "sav");
|
||||
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// SEGA MEGA DRIVE MODULE
|
||||
//******************************************
|
||||
// Writes to Sega CD Backup RAM Cart require an extra wire from MRES (B02) to VRES (B27)
|
||||
#ifdef enable_MD
|
||||
#ifdef ENABLE_MD
|
||||
|
||||
/******************************************
|
||||
Variables
|
||||
|
@ -87,10 +87,19 @@ unsigned long bramSize = 0;
|
|||
// REALTEC MAPPER
|
||||
boolean realtec = 0;
|
||||
|
||||
#ifndef DEFAULT_VALUE_segaSram16bit
|
||||
#define DEFAULT_VALUE_segaSram16bit 0
|
||||
#endif
|
||||
int segaSram16bit = DEFAULT_VALUE_segaSram16bit;
|
||||
#if defined(ENABLED_CONFIG)
|
||||
|
||||
int segaSram16bit = 0;
|
||||
|
||||
#else /* !ENABLED_CONFIG */
|
||||
|
||||
# ifndef OPTION_MD_DEFAULT_SAVE_TYPE
|
||||
# define OPTION_MD_DEFAULT_SAVE_TYPE 0
|
||||
# endif /* !OPTION_MD_DEFAULT_SAVE_TYPE */
|
||||
|
||||
int segaSram16bit = OPTION_MD_DEFAULT_SAVE_TYPE;
|
||||
|
||||
#endif /* ENABLED_CONFIG */
|
||||
|
||||
//*****************************************
|
||||
// SONIC & KNUCKLES LOCK-ON MODE VARIABLES
|
||||
|
@ -111,12 +120,15 @@ static word chksumSonic2 = 0x0635;
|
|||
/******************************************
|
||||
Configuration
|
||||
*****************************************/
|
||||
#ifdef use_md_conf
|
||||
#if defined(use_md_conf) && !defined(ENABLE_CONFIG)
|
||||
|
||||
#warning "DEPRECATED: use_md_conf is deprecated. You should use ENABLE_CONFIG instead."
|
||||
|
||||
void mdLoadConf() {
|
||||
if (myFile.open("mdconf.txt", O_READ)) {
|
||||
char line[64];
|
||||
int n;
|
||||
int i;
|
||||
unsigned int n;
|
||||
unsigned int i;
|
||||
while ((n = myFile.fgets(line, sizeof(line) - 1)) > 0) {
|
||||
// preprocess
|
||||
for (i = 0; i < n; i++) {
|
||||
|
@ -173,7 +185,7 @@ void mdLoadConf() {
|
|||
// 2: Duplicate each byte. Pad with 0xFF so that the file size is 64KB.
|
||||
segaSram16bit = atoi(value);
|
||||
if (segaSram16bit != 0 && segaSram16bit != 1 && segaSram16bit != 2) {
|
||||
segaSram16bit = DEFAULT_VALUE_segaSram16bit;
|
||||
segaSram16bit = DEFAULT_VALUE_SAVE_TYPE;
|
||||
}
|
||||
print_Msg(F("segaSram16bit: "));
|
||||
println_Msg(segaSram16bit);
|
||||
|
@ -197,24 +209,17 @@ void pulse_clock(int n) {
|
|||
static const char MDMenuItem1[] PROGMEM = "Game Cartridge";
|
||||
static const char MDMenuItem2[] PROGMEM = "SegaCD RamCart";
|
||||
static const char MDMenuItem3[] PROGMEM = "Flash Repro";
|
||||
//static const char MDMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsMD[] PROGMEM = { MDMenuItem1, MDMenuItem2, MDMenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsMD[] PROGMEM = { MDMenuItem1, MDMenuItem2, MDMenuItem3, FSTRING_RESET };
|
||||
|
||||
// Cart menu items
|
||||
static const char MDCartMenuItem1[] PROGMEM = "Read Rom";
|
||||
static const char MDCartMenuItem2[] PROGMEM = "Read Sram";
|
||||
static const char MDCartMenuItem3[] PROGMEM = "Write Sram";
|
||||
static const char MDCartMenuItem4[] PROGMEM = "Read EEPROM";
|
||||
static const char MDCartMenuItem5[] PROGMEM = "Write EEPROM";
|
||||
static const char MDCartMenuItem6[] PROGMEM = "Cycle cart";
|
||||
//static const char MDCartMenuItem7[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsMDCart[] PROGMEM = { MDCartMenuItem1, MDCartMenuItem2, MDCartMenuItem3, MDCartMenuItem4, MDCartMenuItem5, MDCartMenuItem6, string_reset2 };
|
||||
static const char* const menuOptionsMDCart[] PROGMEM = { FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, MDCartMenuItem4, MDCartMenuItem5, FSTRING_REFRESH_CART, FSTRING_RESET };
|
||||
|
||||
// Sega CD Ram Backup Cartridge menu items
|
||||
static const char SCDMenuItem1[] PROGMEM = "Read Backup RAM";
|
||||
static const char SCDMenuItem2[] PROGMEM = "Write Backup RAM";
|
||||
//static const char SCDMenuItem3[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsSCD[] PROGMEM = { SCDMenuItem1, SCDMenuItem2, string_reset2 };
|
||||
static const char* const menuOptionsSCD[] PROGMEM = { SCDMenuItem1, SCDMenuItem2, FSTRING_RESET };
|
||||
|
||||
// Sega start menu
|
||||
void mdMenu() {
|
||||
|
@ -230,22 +235,22 @@ void mdMenu() {
|
|||
display_Clear();
|
||||
display_Update();
|
||||
setup_MD();
|
||||
mode = mode_MD_Cart;
|
||||
mode = CORE_MD_CART;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_MD();
|
||||
mode = mode_SEGA_CD;
|
||||
mode = CORE_SEGA_CD;
|
||||
break;
|
||||
|
||||
#ifdef enable_FLASH
|
||||
#ifdef ENABLE_FLASH
|
||||
case 2:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_MD();
|
||||
mode = mode_MD_Cart;
|
||||
mode = CORE_MD_CART;
|
||||
// Change working dir to root
|
||||
filePath[0] = '\0';
|
||||
sd.chdir("/");
|
||||
|
@ -279,7 +284,7 @@ void mdMenu() {
|
|||
verifyFlash_MD();
|
||||
// Set CS(PH3) HIGH
|
||||
PORTH |= (1 << 3);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -324,7 +329,7 @@ void mdCartMenu() {
|
|||
} else {
|
||||
print_Error(F("Cart has no ROM"));
|
||||
}
|
||||
#ifdef global_log
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
save_log();
|
||||
#endif
|
||||
break;
|
||||
|
@ -453,7 +458,7 @@ void segaCDMenu() {
|
|||
asm volatile(" jmp 0");
|
||||
break;
|
||||
}
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -467,9 +472,11 @@ void setup_MD() {
|
|||
// Request 5V
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
|
||||
#ifdef use_md_conf
|
||||
#if defined(ENABLE_CONFIG)
|
||||
segaSram16bit = configGetLong(F("md.saveType"));
|
||||
#elif defined(use_md_conf)
|
||||
mdLoadConf();
|
||||
#endif
|
||||
#endif /*ENABLE_CONFIG*/
|
||||
|
||||
// Set Address Pins to Output
|
||||
//A0-A7
|
||||
|
@ -745,7 +752,7 @@ void getCartInfo_MD() {
|
|||
id[c + 1] = loByte;
|
||||
}
|
||||
|
||||
//Identify games using SVP chip
|
||||
// Identify games using SVP chip
|
||||
if (!strncmp("GM MK-1229 ", id, 11) || !strncmp("GM G-7001 ", id, 11)) // Virtua Racing (E/U/J)
|
||||
isSVP = 1;
|
||||
else
|
||||
|
@ -770,48 +777,48 @@ void getCartInfo_MD() {
|
|||
}
|
||||
if (cartSize == 0x300000) {
|
||||
switch (chksum) {
|
||||
case 0xBC5F: //Batman Forever (World)
|
||||
case 0x3CDD: //Donald in Maui Mallard (Brazil) (En)
|
||||
case 0x44AD: //Donald in Maui Mallard (Europe) (Rev A)
|
||||
case 0x2D9A: //Foreman for Real (World)
|
||||
case 0x5648: //Justice League Task Force (World)
|
||||
case 0x0A29: //Mega 6 Vol. 3 (Europe)
|
||||
case 0x7651: //NFL Quarterback Club (World)
|
||||
case 0x74CA: //WWF RAW (World)
|
||||
case 0xBC5F: // Batman Forever (World)
|
||||
case 0x3CDD: // Donald in Maui Mallard (Brazil) (En)
|
||||
case 0x44AD: // Donald in Maui Mallard (Europe) (Rev A)
|
||||
case 0x2D9A: // Foreman for Real (World)
|
||||
case 0x5648: // Justice League Task Force (World)
|
||||
case 0x0A29: // Mega 6 Vol. 3 (Europe)
|
||||
case 0x7651: // NFL Quarterback Club (World)
|
||||
case 0x74CA: // WWF RAW (World)
|
||||
cartSize = 0x400000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartSize == 0x200000) {
|
||||
switch (chksum) {
|
||||
case 0x2078: //Dynamite Headdy (USA, Europe)
|
||||
case 0x2078: // Dynamite Headdy (USA, Europe)
|
||||
chksum = 0x9877;
|
||||
break;
|
||||
case 0xAE95: //Winter Olympic Games (USA)
|
||||
case 0xAE95: // Winter Olympic Games (USA)
|
||||
chksum = 0x56A0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartSize == 0x180000) {
|
||||
switch (chksum) {
|
||||
case 0xFFE2: //Cannon Fodder (Europe)
|
||||
case 0xF418: //Chaos Engine, The (Europe)
|
||||
case 0xF71D: //Fatal Fury (Europe, Korea) (En)
|
||||
case 0xA884: //Flashback (Europe) (En,Fr)
|
||||
case 0x7D68: //Flashback - The Quest for Identity (USA) (En,Fr)
|
||||
case 0x030D: //Shining Force (Europe)
|
||||
case 0xE975: //Shining Force (USA)
|
||||
case 0xFFE2: // Cannon Fodder (Europe)
|
||||
case 0xF418: // Chaos Engine, The (Europe)
|
||||
case 0xF71D: // Fatal Fury (Europe, Korea) (En)
|
||||
case 0xA884: // Flashback (Europe) (En,Fr)
|
||||
case 0x7D68: // Flashback - The Quest for Identity (USA) (En,Fr)
|
||||
case 0x030D: // Shining Force (Europe)
|
||||
case 0xE975: // Shining Force (USA)
|
||||
cartSize = 0x200000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartSize == 0x100000) {
|
||||
switch (chksum) {
|
||||
case 0xCDF5: //Life on Mars (Aftermarket)
|
||||
case 0xCDF5: // Life on Mars (Aftermarket)
|
||||
cartSize = 0x400000;
|
||||
chksum = 0x603A;
|
||||
break;
|
||||
case 0xF85F: //Metal Dragon (Aftermarket)
|
||||
case 0xF85F: // Metal Dragon (Aftermarket)
|
||||
cartSize = 0x200000;
|
||||
chksum = 0x6965;
|
||||
break;
|
||||
|
@ -819,55 +826,59 @@ void getCartInfo_MD() {
|
|||
}
|
||||
if (cartSize == 0xC0000) {
|
||||
switch (chksum) {
|
||||
case 0x9D79: //Wonder Boy in Monster World (USA, Europe)
|
||||
case 0x9D79: // Wonder Boy in Monster World (USA, Europe)
|
||||
cartSize = 0x100000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartSize == 0x80000) {
|
||||
switch (chksum) {
|
||||
case 0x5B3A: //NHL 98 (USA)
|
||||
case 0x06C1: // Madden NFL 98 (USA)
|
||||
cartSize = 0x200000;
|
||||
chksum = 0x8473;
|
||||
break;
|
||||
case 0x5B3A: // NHL 98 (USA)
|
||||
cartSize = 0x200000;
|
||||
chksum = 0x5613;
|
||||
break;
|
||||
case 0xD07D: //Zero Wing (Japan)
|
||||
case 0xD07D: // Zero Wing (Japan)
|
||||
cartSize = 0x100000;
|
||||
chksum = 0xF204;
|
||||
break;
|
||||
case 0x95C9: //Zero Wing (Europe)
|
||||
case 0x9144: //Zoop (Europe)
|
||||
case 0xB8D4: //Zoop (USA)
|
||||
case 0x95C9: // Zero Wing (Europe)
|
||||
case 0x9144: // Zoop (Europe)
|
||||
case 0xB8D4: // Zoop (USA)
|
||||
cartSize = 0x100000;
|
||||
break;
|
||||
case 0xC422: //Jeopardy! (USA)
|
||||
case 0xC422: // Jeopardy! (USA)
|
||||
chksum = 0xC751;
|
||||
break;
|
||||
case 0x0C6A: //Monopoly (USA)
|
||||
case 0x0C6A: // Monopoly (USA)
|
||||
chksum = 0xE1AA;
|
||||
break;
|
||||
case 0xA760: //Gain Ground (USA)
|
||||
case 0xA760: // Gain Ground (USA)
|
||||
chksum = 0x97CD;
|
||||
break;
|
||||
case 0x1404: //Wonder Boy III - Monster Lair (Japan, Europe) (En)
|
||||
case 0x1404: // Wonder Boy III - Monster Lair (Japan, Europe) (En)
|
||||
chksum = 0x53B9;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartSize == 0x40000) {
|
||||
switch (chksum) {
|
||||
case 0x8BC6: //Pac-Attack (USA)
|
||||
case 0xB344: //Pac-Panic (Europe)
|
||||
case 0x8BC6: // Pac-Attack (USA)
|
||||
case 0xB344: // Pac-Panic (Europe)
|
||||
cartSize = 0x100000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartSize == 0x20000) {
|
||||
switch (chksum) {
|
||||
case 0x7E50: //Micro Machines 2 - Turbo Tournament (Europe)
|
||||
case 0x7E50: // Micro Machines 2 - Turbo Tournament (Europe)
|
||||
cartSize = 0x100000;
|
||||
chksum = 0xD074;
|
||||
break;
|
||||
case 0x168B: //Micro Machines - Military (Europe)
|
||||
case 0x168B: // Micro Machines - Military (Europe)
|
||||
cartSize = 0x100000;
|
||||
chksum = 0xCEE0;
|
||||
break;
|
||||
|
@ -890,41 +901,93 @@ void getCartInfo_MD() {
|
|||
chksum = 0x45C6;
|
||||
}
|
||||
|
||||
//YM2612 Instrument Editor (Aftermarket)
|
||||
// YM2612 Instrument Editor (Aftermarket)
|
||||
if (!strncmp("GM 10101010", id, 11) && (chksum == 0xC439)) {
|
||||
chksum = 0x21B0;
|
||||
cartSize = 0x100000;
|
||||
}
|
||||
|
||||
//Technoptimistic (Aftermarket)
|
||||
// Technoptimistic (Aftermarket)
|
||||
if (!strncmp("MU REMUTE01", id, 11) && (chksum == 0x0000)) {
|
||||
chksum = 0xB55C;
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
//Decoder (Aftermarket)
|
||||
// Decoder (Aftermarket)
|
||||
if (!strncmp("GM REMUTE02", id, 11) && (chksum == 0x0000)) {
|
||||
chksum = 0x5426;
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
//Handy Harvy (Aftermarket)
|
||||
// Handy Harvy (Aftermarket)
|
||||
if (!strncmp("GM HHARVYSG", id, 11) && (chksum == 0x0000)) {
|
||||
chksum = 0xD9D2;
|
||||
cartSize = 0x100000;
|
||||
}
|
||||
|
||||
//Jim Power - The Lost Dimension in 3D (Aftermarket)
|
||||
// Jim Power - The Lost Dimension in 3D (Aftermarket)
|
||||
if (!strncmp("GM T-107036", id, 11) && (chksum == 0x0000)) {
|
||||
chksum = 0xAA28;
|
||||
}
|
||||
|
||||
//mikeyeldey95 (Aftermarket)
|
||||
// mikeyeldey95 (Aftermarket)
|
||||
if (!strncmp("GM 00000000-43", id, 14) && (chksum == 0x0000)) {
|
||||
chksum = 0x921B;
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
// Enryuu Seiken Xiao-Mei (Aftermarket)
|
||||
if (!strncmp("GM 00000000-00", id, 14) && (chksum == 0x1E0C)) {
|
||||
chksum = 0xE7E5;
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
// Life on Earth - Reimagined (Aftermarket)
|
||||
if (!strncmp("GM 00000000-00", id, 14) && (chksum == 0x6BD5)) {
|
||||
chksum = 0x1FEA;
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
// Sasha Darko's Sacred Line I (Aftermarket)
|
||||
if (!strncmp("GM 00000005-00", id, 14) && (chksum == 0x9F34)) {
|
||||
chksum = 0xA094;
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
// Sasha Darko's Sacred Line II (Aftermarket)
|
||||
if (!strncmp("GM 00000005-00", id, 14) && (chksum == 0x0E9B)) {
|
||||
chksum = 0x6B4B;
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
// Sasha Darko's Sacred Line (Watermelon Release) (Aftermarket)
|
||||
if (!strncmp("GM T-574323-00", id, 14) && (chksum == 0xAEDD)) {
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
// Kromasphere (Aftermarket)
|
||||
if (!strncmp("GM MK-0000 -00", id, 14) && (chksum == 0xC536)) {
|
||||
chksum = 0xFAB1;
|
||||
cartSize = 0x200000;
|
||||
}
|
||||
|
||||
// YM2017 (Aftermarket)
|
||||
if (!strncmp("GM CSET0001-02", id, 14) && (chksum == 0x0000)) {
|
||||
chksum = 0xE3A9;
|
||||
}
|
||||
|
||||
// The Curse of Illmore Bay (Aftermarket)
|
||||
if (!strncmp("1774 ", id, 14) && (chksum == 0x0000)) {
|
||||
chksum = 0x6E34;
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
// Coffee Crisis (Aftermarket)
|
||||
if (!strncmp("JN-20160131-03", id, 14) && (chksum == 0x0000)) {
|
||||
chksum = 0x8040;
|
||||
cartSize = 0x400000;
|
||||
}
|
||||
|
||||
// Sonic & Knuckles Check
|
||||
SnKmode = 0;
|
||||
if (chksum == 0xDFB3) {
|
||||
|
@ -1073,13 +1136,13 @@ void getCartInfo_MD() {
|
|||
} else {
|
||||
print_Msg(("sramType: "));
|
||||
print_Msg_PaddedHex16(sramType);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(("sramBase: "));
|
||||
print_Msg_PaddedHex32(sramBase);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(("sramEnd: "));
|
||||
print_Msg_PaddedHex32(sramEnd);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_FatalError(F("Unknown Sram Base"));
|
||||
}
|
||||
} else if (sramType == 0xE020) { // SRAM BOTH BYTES
|
||||
|
@ -1095,16 +1158,19 @@ void getCartInfo_MD() {
|
|||
saveType = 3; // BOTH
|
||||
sramSize = sramEnd - sramBase + 1;
|
||||
sramBase = sramBase >> 1;
|
||||
} else {
|
||||
} else if (sramBase == 0x3FFC00) {
|
||||
// Used for some aftermarket carts without sram
|
||||
saveType = 0;
|
||||
}else {
|
||||
print_Msg(("sramType: "));
|
||||
print_Msg_PaddedHex16(sramType);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(("sramBase: "));
|
||||
print_Msg_PaddedHex32(sramBase);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(("sramEnd: "));
|
||||
print_Msg_PaddedHex32(sramEnd);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_FatalError(F("Unknown Sram Base"));
|
||||
}
|
||||
}
|
||||
|
@ -1173,6 +1239,12 @@ void getCartInfo_MD() {
|
|||
}
|
||||
romName[copyToRomName_MD(romName, sdBuffer, sizeof(romName) - 1)] = 0;
|
||||
|
||||
//Check for Slaughter Sport
|
||||
if (!strncmp("GMT5604600jJ", romName, 12) && (chksum == 0xFFFF)) {
|
||||
strcpy(romName, "SLAUGHTERSPORT");
|
||||
chksum = 0x6BAE;
|
||||
}
|
||||
|
||||
//Get Lock-on cart name
|
||||
if (SnKmode >= 2) {
|
||||
char romNameLockon[12];
|
||||
|
@ -1222,19 +1294,19 @@ void getCartInfo_MD() {
|
|||
|
||||
display_Clear();
|
||||
println_Msg(F("Cart Info"));
|
||||
println_Msg(F(" "));
|
||||
print_Msg(F("Name: "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
if (bramCheck != 0x00FF) {
|
||||
print_Msg(F("bramCheck: "));
|
||||
print_Msg_PaddedHex16(bramCheck);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
}
|
||||
if (bramSize > 0) {
|
||||
print_Msg(F("bramSize(KB): "));
|
||||
println_Msg(bramSize >> 10);
|
||||
}
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(FS(FSTRING_SIZE));
|
||||
print_Msg(cartSize * 8 / 1024 / 1024);
|
||||
switch (SnKmode) {
|
||||
case 2:
|
||||
|
@ -1271,7 +1343,7 @@ void getCartInfo_MD() {
|
|||
print_Msg_PaddedHexByte((chksumSonic2 & 0x00ff));
|
||||
break;
|
||||
}
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
if (saveType == 4) {
|
||||
print_Msg(F("Serial EEPROM: "));
|
||||
print_Msg(eepSize * 8 / 1024);
|
||||
|
@ -1284,10 +1356,10 @@ void getCartInfo_MD() {
|
|||
} else
|
||||
println_Msg(F("None"));
|
||||
}
|
||||
println_Msg(F(" "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
|
||||
// Wait for user input
|
||||
#if (defined(enable_LCD) || defined(enable_OLED))
|
||||
#if (defined(ENABLE_LCD) || defined(ENABLE_OLED))
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -1352,29 +1424,7 @@ void readROM_MD() {
|
|||
dataIn_MD();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".BIN");
|
||||
|
||||
// create a new folder
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "MD/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();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(sd_error_STR);
|
||||
}
|
||||
createFolderAndOpenFile("MD", "ROM", romName, "BIN");
|
||||
|
||||
byte buffer[1024] = { 0 };
|
||||
|
||||
|
@ -1650,14 +1700,14 @@ void readROM_MD() {
|
|||
print_Msg(F("Internal checksum..."));
|
||||
display_Update();
|
||||
if (chksum == calcCKS) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
println_Msg(F("Error"));
|
||||
char calcsumStr[5];
|
||||
sprintf(calcsumStr, "%04X", calcCKS);
|
||||
println_Msg(calcsumStr);
|
||||
print_Error(F(""));
|
||||
print_Error(FS(FSTRING_EMPTY));
|
||||
display_Update();
|
||||
}
|
||||
|
||||
|
@ -1665,28 +1715,28 @@ void readROM_MD() {
|
|||
if (SnKmode >= 2) {
|
||||
print_Msg(F("Lock-on checksum..."));
|
||||
if (chksumLockon == calcCKSLockon) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
print_Msg(F("Error"));
|
||||
char calcsumStr[5];
|
||||
sprintf(calcsumStr, "%04X", calcCKSLockon);
|
||||
println_Msg(calcsumStr);
|
||||
print_Error(F(""));
|
||||
print_Error(FS(FSTRING_EMPTY));
|
||||
display_Update();
|
||||
}
|
||||
}
|
||||
if (SnKmode == 3) {
|
||||
print_Msg(F("Adittional checksum..."));
|
||||
if (chksumSonic2 == calcCKSSonic2) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
print_Msg(F("Error"));
|
||||
char calcsumStr[5];
|
||||
sprintf(calcsumStr, "%04X", calcCKSSonic2);
|
||||
println_Msg(calcsumStr);
|
||||
print_Error(F(""));
|
||||
print_Error(FS(FSTRING_EMPTY));
|
||||
display_Update();
|
||||
}
|
||||
}
|
||||
|
@ -1781,14 +1831,7 @@ void readSram_MD() {
|
|||
dataIn_MD();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".srm");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "MD/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("MD", "SAVE", romName, "srm");
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
|
@ -1896,7 +1939,7 @@ unsigned long verifySram_MD() {
|
|||
return writeErrors;
|
||||
}
|
||||
|
||||
#ifdef enable_FLASH
|
||||
#ifdef ENABLE_FLASH
|
||||
//******************************************
|
||||
// Flashrom Functions
|
||||
//******************************************
|
||||
|
@ -2642,15 +2685,7 @@ void readEEP_MD() {
|
|||
dataIn_MD();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".eep");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sd.chdir();
|
||||
sprintf(folder, "MD/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("MD", "SAVE", romName, "eep");
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
|
@ -2684,7 +2719,7 @@ void readEEP_MD() {
|
|||
}
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
display_Clear();
|
||||
print_Msg(F("Saved to "));
|
||||
print_Msg(folder);
|
||||
|
@ -2719,13 +2754,13 @@ void writeEEP_MD() {
|
|||
writeEepromByte(currByte);
|
||||
print_Msg(F("."));
|
||||
if ((currByte != 0) && ((currByte + 1) % 64 == 0))
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
display_Update(); // ON SERIAL = delay(100)
|
||||
}
|
||||
}
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
display_Clear();
|
||||
print_STR(done_STR, 1);
|
||||
display_Update();
|
||||
|
@ -2742,14 +2777,7 @@ void readBram_MD() {
|
|||
dataIn_MD();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, "Cart.brm");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sd.chdir();
|
||||
sprintf(folder, "MD/RAM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("MD", "RAM", "Cart", "brm");
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
|
@ -2772,7 +2800,7 @@ void readBram_MD() {
|
|||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
display_Clear();
|
||||
print_Msg(F("Saved to "));
|
||||
print_Msg(folder);
|
||||
|
@ -2804,7 +2832,7 @@ void writeBram_MD() {
|
|||
writeWord_MD(0x380000, 0); // Disable BRAM Writes
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
display_Clear();
|
||||
print_STR(done_STR, 1);
|
||||
display_Update();
|
||||
|
@ -2837,29 +2865,7 @@ void readRealtec_MD() {
|
|||
dataIn_MD();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".MD");
|
||||
|
||||
// create a new folder
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "MD/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();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(sd_error_STR);
|
||||
}
|
||||
createFolderAndOpenFile("MD", "ROM", romName, "MD");
|
||||
|
||||
// Realtec Registers
|
||||
writeWord_MD(0x201000, 4); // Number of 128K Blocks 0x402000 (0x201000)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// MSX COMPUTER MODULE
|
||||
//******************************************
|
||||
#ifdef enable_MSX
|
||||
#ifdef ENABLE_MSX
|
||||
// MSX
|
||||
// Cartridge Pinout
|
||||
// 50P 2.54mm pitch connector
|
||||
|
@ -105,11 +105,8 @@ byte msxmapselect;
|
|||
int msxindex;
|
||||
|
||||
byte msxmapper;
|
||||
byte newmsxmapper;
|
||||
byte msxsize;
|
||||
byte newmsxsize;
|
||||
byte msxramsize;
|
||||
byte newmsxramsize;
|
||||
uint8_t msxbanks;
|
||||
byte chipselect;
|
||||
|
||||
|
@ -126,11 +123,10 @@ boolean srambit7 = false;
|
|||
// MENU
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char msxMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char msxMenuItem2[] PROGMEM = "Read Cart";
|
||||
static const char msxMenuItem3[] PROGMEM = "Set Mapper + Size";
|
||||
static const char msxMenuItem4[] PROGMEM = "Write SRAM";
|
||||
static const char* const menuOptionsMSX[] PROGMEM = { msxMenuItem1, msxMenuItem2, msxMenuItem3, msxMenuItem4, string_reset2 };
|
||||
static const char* const menuOptionsMSX[] PROGMEM = { FSTRING_SELECT_CART, msxMenuItem2, msxMenuItem3, msxMenuItem4, FSTRING_RESET };
|
||||
|
||||
void msxMenu() {
|
||||
convertPgm(menuOptionsMSX, 5);
|
||||
|
@ -140,7 +136,6 @@ void msxMenu() {
|
|||
case 0:
|
||||
// Select Cart
|
||||
setCart_MSX();
|
||||
wait();
|
||||
setup_MSX();
|
||||
break;
|
||||
|
||||
|
@ -163,7 +158,7 @@ void msxMenu() {
|
|||
case 3:
|
||||
// Write RAM
|
||||
writeRAM_MSX();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -223,7 +218,7 @@ void setup_MSX() {
|
|||
checkStatus_MSX();
|
||||
strcpy(romName, "MSX");
|
||||
|
||||
mode = mode_MSX;
|
||||
mode = CORE_MSX;
|
||||
}
|
||||
|
||||
//******************************************
|
||||
|
@ -295,23 +290,6 @@ void writeData_MSX(uint16_t addr, uint8_t data) {
|
|||
DDRC = 0x00; // Reset to Input
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// POWER
|
||||
//******************************************
|
||||
#ifndef enable_NES
|
||||
int int_pow(int base, int exp) // Power for int
|
||||
{
|
||||
int result = 1;
|
||||
while (exp) {
|
||||
if (exp & 1)
|
||||
result *= base;
|
||||
exp /= 2;
|
||||
base *= base;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
//******************************************
|
||||
// CS CODE
|
||||
//******************************************
|
||||
|
@ -365,28 +343,7 @@ void readROM_MSX() {
|
|||
println_Msg(F("ROM SIZE 0K"));
|
||||
display_Update();
|
||||
} else {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".bin");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "MSX/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(sd_error_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("MSX", "ROM", romName, "bin");
|
||||
|
||||
switch (msxmapper) {
|
||||
case 0: // No Mapper
|
||||
|
@ -560,10 +517,9 @@ void readROM_MSX() {
|
|||
}
|
||||
myFile.close();
|
||||
|
||||
unsigned long crcsize = MSX[msxsize] * 0x400;
|
||||
calcCRC(fileName, crcsize, NULL, 0);
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -720,10 +676,9 @@ void readRAM_MSX() {
|
|||
}
|
||||
myFile.close();
|
||||
|
||||
unsigned long crcsize = MSX[msxramsize] * 0x400;
|
||||
calcCRC(fileName, crcsize, NULL, 0);
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -847,7 +802,7 @@ void writeRAM_MSX() {
|
|||
}
|
||||
myFile.close();
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("RAM FILE WRITTEN!"));
|
||||
display_Update();
|
||||
|
||||
|
@ -862,115 +817,24 @@ void writeRAM_MSX() {
|
|||
//******************************************
|
||||
// MAPPER CODE
|
||||
//******************************************
|
||||
void setMapper_MSX() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
int b = 0;
|
||||
int i = 0;
|
||||
// Check Button Status
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Pressed
|
||||
while (1) { // Scroll Mapper List
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
// Correct Overshoot
|
||||
if (i == 0)
|
||||
i = msxmapcount - 1;
|
||||
else
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
msxindex = i * 5;
|
||||
msxmapselect = pgm_read_byte(msxmapsize + msxindex);
|
||||
println_Msg(msxmapselect);
|
||||
printMapper(msxmapselect);
|
||||
display_Update();
|
||||
if (i == (msxmapcount - 1))
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
delay(250);
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printMapperSelection_MSX(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
msxindex = i * 5;
|
||||
print_Msg(FS(FSTRING_MAPPER));
|
||||
msxindex = index * 5;
|
||||
msxmapselect = pgm_read_byte(msxmapsize + msxindex);
|
||||
println_Msg(msxmapselect);
|
||||
printMapper(msxmapselect);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
}
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous Mapper (doubleclick)
|
||||
if (i == 0)
|
||||
i = msxmapcount - 1;
|
||||
else
|
||||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
msxindex = i * 5;
|
||||
msxmapselect = pgm_read_byte(msxmapsize + msxindex);
|
||||
println_Msg(msxmapselect);
|
||||
printMapper(msxmapselect);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next Mapper (press)
|
||||
if (i == (msxmapcount - 1))
|
||||
i = 0;
|
||||
else
|
||||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("Mapper: "));
|
||||
msxindex = i * 5;
|
||||
msxmapselect = pgm_read_byte(msxmapsize + msxindex);
|
||||
println_Msg(msxmapselect);
|
||||
printMapper(msxmapselect);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newmsxmapper = msxmapselect;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void setMapper_MSX() {
|
||||
byte newmsxmapper;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
navigateMenu(0, msxmapcount - 1, &printMapperSelection_MSX);
|
||||
newmsxmapper = msxmapselect;
|
||||
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("MAPPER "));
|
||||
print_Msg(newmsxmapper);
|
||||
|
@ -995,7 +859,7 @@ setmapper:
|
|||
}
|
||||
if (msxmapfound == false) {
|
||||
Serial.println(F("MAPPER NOT SUPPORTED!"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
newmsxmapper = 0;
|
||||
goto setmapper;
|
||||
}
|
||||
|
@ -1021,27 +885,27 @@ void checkMapperSize_MSX() {
|
|||
//******************************************
|
||||
// SET ROM SIZE
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRomSize_MSX(uint8_t index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(MSX[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_MSX() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte newmsxsize;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (msxlo == msxhi)
|
||||
newmsxsize = msxlo;
|
||||
else {
|
||||
int b = 0;
|
||||
uint8_t b = 0;
|
||||
int i = msxlo;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(MSX[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
printRomSize_MSX(i);
|
||||
printInstructions();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
|
@ -1058,18 +922,8 @@ void setROMSize_MSX() {
|
|||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(MSX[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
printRomSize_MSX(i);
|
||||
printInstructions();
|
||||
}
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
|
@ -1085,18 +939,8 @@ void setROMSize_MSX() {
|
|||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(MSX[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
printRomSize_MSX(i);
|
||||
printInstructions();
|
||||
}
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
|
@ -1106,7 +950,7 @@ void setROMSize_MSX() {
|
|||
}
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
if (msxmapper == 12) // R-Type
|
||||
print_Msg(F("384"));
|
||||
else
|
||||
|
@ -1138,13 +982,13 @@ setrom:
|
|||
if (msxmapper == 11) { // PAC/FM-PAC 0K/64K
|
||||
if ((newmsxromsize > 0) && (newmsxromsize < 4)) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
if (newmsxsize > msxhi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
|
@ -1162,27 +1006,27 @@ setrom:
|
|||
//******************************************
|
||||
// SET RAM SIZE
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRamSize_MSX(uint8_t index) {
|
||||
display_Clear();
|
||||
print_Msg(F("RAM Size: "));
|
||||
println_Msg(MSXRAM[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setRAMSize_MSX() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte newmsxramsize;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (msxramlo == msxramhi)
|
||||
newmsxramsize = msxramlo;
|
||||
else {
|
||||
int b = 0;
|
||||
uint8_t b = 0;
|
||||
int i = msxramlo;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("RAM Size: "));
|
||||
println_Msg(MSXRAM[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
printRamSize_MSX(i);
|
||||
printInstructions();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
|
@ -1199,18 +1043,8 @@ void setRAMSize_MSX() {
|
|||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("RAM Size: "));
|
||||
println_Msg(MSXRAM[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
printRamSize_MSX(i);
|
||||
printInstructions();
|
||||
}
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
|
@ -1226,18 +1060,8 @@ void setRAMSize_MSX() {
|
|||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("RAM Size: "));
|
||||
println_Msg(MSXRAM[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
printRamSize_MSX(i);
|
||||
printInstructions();
|
||||
}
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
|
@ -1273,13 +1097,13 @@ setram:
|
|||
if (msxmapper == 7) { // Koei 8K/32K
|
||||
if (newmsxramsize == 3) { // 16K
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setram;
|
||||
}
|
||||
}
|
||||
if (newmsxramsize > msxramhi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setram;
|
||||
}
|
||||
}
|
||||
|
@ -1311,15 +1135,15 @@ void checkStatus_MSX() {
|
|||
EEPROM_writeAnything(10, msxramsize);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("MSX READER"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(F("MAPPER: "));
|
||||
println_Msg(msxmapper);
|
||||
printMapper(msxmapper);
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
if (msxmapper == 12) // R-Type
|
||||
print_Msg(F("384"));
|
||||
else
|
||||
|
@ -1342,12 +1166,12 @@ void checkStatus_MSX() {
|
|||
Serial.print(F("CURRENT RAM SIZE: "));
|
||||
Serial.print(MSXRAM[msxramsize]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
void printMapper(byte msxmaplabel) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
switch (msxmaplabel) {
|
||||
case 0:
|
||||
println_Msg(F("NONE"));
|
||||
|
@ -1413,255 +1237,53 @@ void printMapper(byte msxmaplabel) {
|
|||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
FsFile msxcsvFile;
|
||||
char msxgame[31]; // title
|
||||
char msxmm[3]; // mapper
|
||||
char msxrr[3]; // romsize
|
||||
char msxss[3]; // ramsize
|
||||
char msxll[4]; // linelength (previous line)
|
||||
unsigned long msxcsvpos; // CSV File Position
|
||||
char msxcartCSV[] = "msxcart.txt"; // CSV List
|
||||
char msxcsvEND[] = "EOF"; // CSV End Marker for scrolling
|
||||
struct database_entry_MSX {
|
||||
byte gameMapper;
|
||||
byte gameSize;
|
||||
byte ramSize;
|
||||
};
|
||||
|
||||
bool readLine_MSX(FsFile& f, char* line, size_t maxLen) {
|
||||
for (size_t n = 0; n < maxLen; n++) {
|
||||
int c = f.read();
|
||||
if (c < 0 && n == 0) return false; // EOF
|
||||
if (c < 0 || c == '\n') {
|
||||
line[n] = 0;
|
||||
return true;
|
||||
}
|
||||
line[n] = c;
|
||||
}
|
||||
return false; // line too long
|
||||
}
|
||||
void readDataLine_MSX(FsFile& database, void* entry) {
|
||||
database_entry_MSX* castEntry = (database_entry_MSX*)entry;
|
||||
// Read mapper
|
||||
castEntry->gameMapper = ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
bool readVals_MSX(char* msxgame, char* msxmm, char* msxrr, char* msxss, char* msxll) {
|
||||
char line[41];
|
||||
msxcsvpos = msxcsvFile.position();
|
||||
if (!readLine_MSX(msxcsvFile, line, sizeof(line))) {
|
||||
return false; // EOF or too long
|
||||
}
|
||||
char* comma = strtok(line, ",");
|
||||
int x = 0;
|
||||
while (comma != NULL) {
|
||||
if (x == 0)
|
||||
strcpy(msxgame, comma);
|
||||
else if (x == 1)
|
||||
strcpy(msxmm, comma);
|
||||
else if (x == 2)
|
||||
strcpy(msxrr, comma);
|
||||
else if (x == 3)
|
||||
strcpy(msxss, comma);
|
||||
else if (x == 4)
|
||||
strcpy(msxll, comma);
|
||||
comma = strtok(NULL, ",");
|
||||
x += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
bool getCartListInfo_MSX() {
|
||||
bool buttonreleased = 0;
|
||||
bool cartselected = 0;
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F(" HOLD TO FAST CYCLE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("HOLD BUTTON TO FAST CYCLE"));
|
||||
#endif
|
||||
delay(2000);
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Held - Fast Cycle
|
||||
while (1) { // Scroll Game List
|
||||
while (readVals_MSX(msxgame, msxmm, msxrr, msxss, msxll)) {
|
||||
if (strcmp(msxcsvEND, msxgame) == 0) {
|
||||
msxcsvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(msxgame);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(msxgame);
|
||||
#endif
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
buttonreleased = 1;
|
||||
break;
|
||||
}
|
||||
if (buttonreleased) {
|
||||
buttonreleased = 0; // Reset Flag
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) // Button Released
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("FAST CYCLE OFF"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("FAST CYCLE OFF"));
|
||||
Serial.println(F("PRESS BUTTON TO STEP FORWARD"));
|
||||
Serial.println(F("DOUBLE CLICK TO STEP BACK"));
|
||||
Serial.println(F("HOLD TO SELECT"));
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
while (readVals_MSX(msxgame, msxmm, msxrr, msxss, msxll)) {
|
||||
if (strcmp(msxcsvEND, msxgame) == 0) {
|
||||
msxcsvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(msxgame);
|
||||
display.setCursor(0, 48);
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(msxgame);
|
||||
#endif
|
||||
while (1) { // Single Step
|
||||
int b = checkButton();
|
||||
if (b == 1) { // Continue (press)
|
||||
break;
|
||||
}
|
||||
if (b == 2) { // Reset to Start of List (doubleclick)
|
||||
byte prevline = strtol(msxll, NULL, 10);
|
||||
msxcsvpos -= prevline;
|
||||
msxcsvFile.seek(msxcsvpos);
|
||||
break;
|
||||
}
|
||||
if (b == 3) { // Long Press - Select Cart (hold)
|
||||
newmsxmapper = strtol(msxmm, NULL, 10);
|
||||
newmsxsize = strtol(msxrr, NULL, 10);
|
||||
newmsxramsize = strtol(msxss, NULL, 10);
|
||||
EEPROM_writeAnything(7, newmsxmapper);
|
||||
EEPROM_writeAnything(8, newmsxsize);
|
||||
EEPROM_writeAnything(10, newmsxramsize);
|
||||
cartselected = 1; // SELECTION MADE
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F("SELECTION MADE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("SELECTION MADE"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartselected) {
|
||||
cartselected = 0; // Reset Flag
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("END OF FILE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("END OF FILE"));
|
||||
#endif
|
||||
// Read rom size
|
||||
castEntry->gameSize = database.read() - 48;
|
||||
|
||||
return false;
|
||||
}
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
void checkCSV_MSX() {
|
||||
if (getCartListInfo_MSX()) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART SELECTED"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(msxgame);
|
||||
display_Update();
|
||||
// Display Settings
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("CODE: M"));
|
||||
print_Msg(newmsxmapper);
|
||||
print_Msg(F("/R"));
|
||||
print_Msg(newmsxsize);
|
||||
print_Msg(F("/S"));
|
||||
println_Msg(newmsxramsize);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("CART SELECTED"));
|
||||
Serial.println(msxgame);
|
||||
// Display Settings
|
||||
Serial.print(F("CODE: M"));
|
||||
Serial.print(newmsxmapper);
|
||||
Serial.print(F("/R"));
|
||||
Serial.print(newmsxsize);
|
||||
Serial.print(F("/S"));
|
||||
Serial.println(newmsxramsize);
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("NO SELECTION"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("NO SELECTION"));
|
||||
#endif
|
||||
}
|
||||
// Read ram size
|
||||
castEntry->ramSize = database.read() - 48;
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void setCart_MSX() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(msxcartCSV);
|
||||
display_Update();
|
||||
#endif
|
||||
//go to root
|
||||
sd.chdir();
|
||||
sprintf(folder, "MSX/CSV");
|
||||
sd.chdir(folder); // Switch Folder
|
||||
msxcsvFile = sd.open(msxcartCSV, O_READ);
|
||||
if (!msxcsvFile) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CSV FILE NOT FOUND!"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("CSV FILE NOT FOUND!"));
|
||||
#endif
|
||||
while (1) {
|
||||
if (checkButton() != 0)
|
||||
setup_MSX();
|
||||
}
|
||||
}
|
||||
checkCSV_MSX();
|
||||
|
||||
msxcsvFile.close();
|
||||
struct database_entry_MSX entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("msxcart.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
if(checkCartSelection(myFile, &readDataLine_MSX, &entry)) {
|
||||
EEPROM_writeAnything(7, entry.gameMapper);
|
||||
EEPROM_writeAnything(8, entry.gameSize);
|
||||
EEPROM_writeAnything(10, entry.ramSize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// NINTENDO 64 MODULE
|
||||
//******************************************
|
||||
#ifdef enable_N64
|
||||
#ifdef ENABLE_N64
|
||||
|
||||
/******************************************
|
||||
Defines
|
||||
|
@ -39,18 +39,15 @@ boolean MN63F81MPN = false;
|
|||
//ControllerTest
|
||||
bool quit = 1;
|
||||
|
||||
#ifdef savesummarytotxt
|
||||
#ifdef OPTION_N64_SAVESUMMARY
|
||||
String CRC1 = "";
|
||||
String CRC2 = "";
|
||||
#endif
|
||||
|
||||
#if !defined(enable_FLASH)
|
||||
#if !defined(ENABLE_FLASH)
|
||||
unsigned long flashSize;
|
||||
#endif
|
||||
|
||||
static const char N64_EEP_FILENAME_FMT[] PROGMEM = "%s.eep";
|
||||
static const char N64_SAVE_DIRNAME_FMT[] PROGMEM = "N64/SAVE/%s/%d";
|
||||
|
||||
/******************************************
|
||||
Menu
|
||||
*****************************************/
|
||||
|
@ -60,30 +57,23 @@ static const char n64MenuItem2[] PROGMEM = "Controller";
|
|||
static const char n64MenuItem3[] PROGMEM = "Flash Repro";
|
||||
static const char n64MenuItem4[] PROGMEM = "Flash Gameshark";
|
||||
static const char n64MenuItem5[] PROGMEM = "Flash Xplorer 64";
|
||||
//static const char n64MenuItem6[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsN64[] PROGMEM = { n64MenuItem1, n64MenuItem2, n64MenuItem3, n64MenuItem4, n64MenuItem5, string_reset2 };
|
||||
static const char* const menuOptionsN64[] PROGMEM = { n64MenuItem1, n64MenuItem2, n64MenuItem3, n64MenuItem4, n64MenuItem5, FSTRING_RESET };
|
||||
|
||||
// N64 controller menu items
|
||||
static const char N64ContMenuItem1[] PROGMEM = "Test Controller";
|
||||
static const char N64ContMenuItem2[] PROGMEM = "Read ControllerPak";
|
||||
static const char N64ContMenuItem3[] PROGMEM = "Write ControllerPak";
|
||||
//static const char N64ContMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsN64Controller[] PROGMEM = { N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsN64Controller[] PROGMEM = { N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, FSTRING_RESET };
|
||||
|
||||
// N64 cart menu items
|
||||
static const char N64CartMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char N64CartMenuItem2[] PROGMEM = "Read Save";
|
||||
static const char N64CartMenuItem3[] PROGMEM = "Write Save";
|
||||
static const char N64CartMenuItem4[] PROGMEM = "Force Savetype";
|
||||
//static const char N64CartMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsN64Cart[] PROGMEM = { N64CartMenuItem1, N64CartMenuItem2, N64CartMenuItem3, N64CartMenuItem4, string_reset2 };
|
||||
static const char* const menuOptionsN64Cart[] PROGMEM = { FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, N64CartMenuItem4, FSTRING_RESET };
|
||||
|
||||
// N64 CRC32 error menu items
|
||||
static const char N64CRCMenuItem1[] PROGMEM = "No";
|
||||
static const char N64CRCMenuItem2[] PROGMEM = "Yes and keep old";
|
||||
static const char N64CRCMenuItem3[] PROGMEM = "Yes and delete old";
|
||||
//static const char N64CRCMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsN64CRC[] PROGMEM = { N64CRCMenuItem1, N64CRCMenuItem2, N64CRCMenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsN64CRC[] PROGMEM = { N64CRCMenuItem1, N64CRCMenuItem2, N64CRCMenuItem3, FSTRING_RESET };
|
||||
|
||||
// Rom menu
|
||||
static const char N64RomItem1[] PROGMEM = "4 MB";
|
||||
|
@ -132,14 +122,14 @@ void n64Menu() {
|
|||
display_Update();
|
||||
setup_N64_Cart();
|
||||
printCartInfo_N64();
|
||||
mode = mode_N64_Cart;
|
||||
mode = CORE_N64_CART;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_N64_Controller();
|
||||
mode = mode_N64_Controller;
|
||||
mode = CORE_N64_CONTROLLER;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
@ -148,7 +138,7 @@ void n64Menu() {
|
|||
setup_N64_Cart();
|
||||
flashRepro_N64();
|
||||
printCartInfo_N64();
|
||||
mode = mode_N64_Cart;
|
||||
mode = CORE_N64_CART;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
@ -157,7 +147,7 @@ void n64Menu() {
|
|||
setup_N64_Cart();
|
||||
flashGameshark_N64();
|
||||
printCartInfo_N64();
|
||||
mode = mode_N64_Cart;
|
||||
mode = CORE_N64_CART;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
@ -165,7 +155,7 @@ void n64Menu() {
|
|||
display_Update();
|
||||
setup_N64_Cart();
|
||||
flashXplorer_N64();
|
||||
mode = mode_N64_Cart;
|
||||
mode = CORE_N64_CART;
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -192,9 +182,9 @@ void n64ControllerMenu() {
|
|||
resetController();
|
||||
display_Clear();
|
||||
display_Update();
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
controllerTest_Display();
|
||||
#elif defined(enable_serial)
|
||||
#elif defined(ENABLE_SERIAL)
|
||||
controllerTest_Serial();
|
||||
#endif
|
||||
quit = 1;
|
||||
|
@ -208,7 +198,7 @@ void n64ControllerMenu() {
|
|||
readMPK();
|
||||
verifyCRC();
|
||||
validateMPK();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -230,7 +220,7 @@ void n64ControllerMenu() {
|
|||
writeMPK();
|
||||
delay(500);
|
||||
verifyMPK();
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -256,7 +246,7 @@ void n64CartMenu() {
|
|||
case 0:
|
||||
display_Clear();
|
||||
sd.chdir("/");
|
||||
#ifndef fastcrc
|
||||
#ifndef OPTION_N64_FASTCRC
|
||||
// Dumping ROM slow
|
||||
readRom_N64();
|
||||
sd.chdir("/");
|
||||
|
@ -266,7 +256,7 @@ void n64CartMenu() {
|
|||
compareCRC("n64.txt", readRom_N64(), 1, 0);
|
||||
#endif
|
||||
|
||||
#ifdef global_log
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
save_log();
|
||||
#endif
|
||||
|
||||
|
@ -296,7 +286,7 @@ void n64CartMenu() {
|
|||
} else {
|
||||
print_Error(F("Savetype Error"));
|
||||
}
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -332,7 +322,7 @@ void n64CartMenu() {
|
|||
display_Update();
|
||||
writeErrors = verifyFram(flashramType);
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
println_Msg("");
|
||||
|
@ -448,7 +438,7 @@ void setup_N64_Cart() {
|
|||
PORTC &= ~(1 << 0);
|
||||
PORTC |= (1 << 1);
|
||||
|
||||
#ifdef clockgen_installed
|
||||
#ifdef ENABLE_CLOCKGEN
|
||||
// Adafruit Clock Generator
|
||||
|
||||
initializeClockOffset();
|
||||
|
@ -479,7 +469,7 @@ void setup_N64_Cart() {
|
|||
// Set sram base address
|
||||
sramBase = 0x08000000;
|
||||
|
||||
#ifdef clockgen_installed
|
||||
#ifdef ENABLE_CLOCKGEN
|
||||
// Wait for clock generator
|
||||
clockgen.update_status();
|
||||
#endif
|
||||
|
@ -1011,7 +1001,7 @@ void get_button() {
|
|||
/******************************************
|
||||
N64 Controller Test
|
||||
*****************************************/
|
||||
#ifdef enable_serial
|
||||
#ifdef ENABLE_SERIAL
|
||||
void controllerTest_Serial() {
|
||||
while (quit) {
|
||||
// Get Button and analog stick
|
||||
|
@ -1038,7 +1028,7 @@ void controllerTest_Serial() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (defined(enable_LCD) || defined(enable_OLED))
|
||||
#if (defined(ENABLE_LCD) || defined(ENABLE_OLED))
|
||||
#define CENTER 64
|
||||
// on which screens do we start
|
||||
int startscreen = 1;
|
||||
|
@ -1933,7 +1923,7 @@ void printCartInfo_N64() {
|
|||
// Print start page
|
||||
if (cartSize != 0) {
|
||||
display_Clear();
|
||||
print_Msg(F("Title: "));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
print_Msg(F("Serial: "));
|
||||
println_Msg(cartID);
|
||||
|
@ -1967,7 +1957,7 @@ void printCartInfo_N64() {
|
|||
println_Msg(checksumStr);
|
||||
|
||||
// Wait for user input
|
||||
println_Msg(F(" "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -1977,7 +1967,7 @@ void printCartInfo_N64() {
|
|||
display_Clear();
|
||||
println_Msg(F("GAMEPAK ERROR"));
|
||||
println_Msg("");
|
||||
print_Msg(F("Title: "));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
print_Msg(F("Serial: "));
|
||||
println_Msg(cartID);
|
||||
|
@ -2189,7 +2179,7 @@ void idCart() {
|
|||
strcpy(romName, cartID);
|
||||
}
|
||||
|
||||
#ifdef savesummarytotxt
|
||||
#ifdef OPTION_N64_SAVESUMMARY
|
||||
// Get CRC1
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (sdBuffer[0x10 + i] < 0x10) {
|
||||
|
@ -2288,30 +2278,15 @@ boolean readEepromPageList(byte* output, byte page_number, byte page_count) {
|
|||
void readEeprom() {
|
||||
if ((saveType == 5) || (saveType == 6)) {
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
snprintf_P(fileName, sizeof(fileName), N64_EEP_FILENAME_FMT, romName);
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
snprintf_P(folder, sizeof(folder), N64_SAVE_DIRNAME_FMT, romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(create_file_STR);
|
||||
}
|
||||
createFolderAndOpenFile("N64", "SAVE", romName, "eep");
|
||||
|
||||
for (int i = 0; i < eepPages; i += sizeof(sdBuffer) / 8) {
|
||||
// If any missing bytes error out
|
||||
if (readEepromPageList(sdBuffer, i, sizeof(sdBuffer) / 8) == 0) {
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(error_STR, 0);
|
||||
println_Msg(F("no data received"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
break;
|
||||
}
|
||||
// Write 64 pages at once to the SD card
|
||||
|
@ -2419,30 +2394,16 @@ void readSram(unsigned long sramSize, byte flashramType) {
|
|||
}
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
const char* suffix;
|
||||
|
||||
if (saveType == 4) {
|
||||
strcat(fileName, ".fla");
|
||||
suffix = "fla";
|
||||
} else if (saveType == 1) {
|
||||
strcat(fileName, ".sra");
|
||||
suffix = "sra";
|
||||
} else {
|
||||
print_FatalError(F("Savetype Error"));
|
||||
}
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "N64/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(sd_error_STR);
|
||||
}
|
||||
createFolderAndOpenFile("N64", "SAVE", romName, suffix);
|
||||
|
||||
for (unsigned long currByte = sramBase; currByte < (sramBase + (sramSize / flashramType)); currByte += offset) {
|
||||
// Set the address
|
||||
|
@ -2546,7 +2507,7 @@ void writeFram(byte flashramType) {
|
|||
|
||||
// Check if empty
|
||||
if (blankcheck_N64(flashramType) == 0) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
println_Msg(F("FAIL"));
|
||||
|
@ -2568,7 +2529,7 @@ void writeFram(byte flashramType) {
|
|||
print_Msg(F("Bank "));
|
||||
for (byte bank = 0; bank < 8; bank++) {
|
||||
print_Msg(bank);
|
||||
print_Msg(F(" "));
|
||||
print_Msg(FS(FSTRING_SPACE));
|
||||
display_Update();
|
||||
|
||||
// Write one bank of 128*128 bytes
|
||||
|
@ -2824,29 +2785,15 @@ void getFramType() {
|
|||
Rom functions
|
||||
*****************************************/
|
||||
// Read rom and save to the SD card
|
||||
#ifndef fastcrc
|
||||
#ifndef OPTION_N64_FASTCRC
|
||||
// dumping rom slow
|
||||
void readRom_N64() {
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".Z64");
|
||||
|
||||
// create a new folder
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "N64/ROM/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("N64", "ROM", romName, "Z64");
|
||||
|
||||
// clear the screen
|
||||
// display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
printAndIncrementFolder();
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
|
@ -2883,25 +2830,11 @@ void readRom_N64() {
|
|||
// dumping rom fast
|
||||
uint32_t readRom_N64() {
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".Z64");
|
||||
|
||||
// create a new folder
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "N64/ROM/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("N64", "ROM", romName, "Z64");
|
||||
|
||||
// clear the screen
|
||||
// display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
printAndIncrementFolder();
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
|
@ -2993,7 +2926,7 @@ uint32_t readRom_N64() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef savesummarytotxt
|
||||
#ifdef OPTION_N64_SAVESUMMARY
|
||||
// Save an info.txt with information on the dumped rom to the SD card
|
||||
void savesummary_N64(boolean checkfound, char crcStr[9], unsigned long timeElapsed) {
|
||||
// Open file on sd card
|
||||
|
@ -3044,7 +2977,7 @@ void savesummary_N64(boolean checkfound, char crcStr[9], unsigned long timeElaps
|
|||
myFile.print(F("Saved To: "));
|
||||
myFile.println(folder);
|
||||
|
||||
#ifdef RTC_installed
|
||||
#ifdef ENABLE_RTC
|
||||
myFile.print(F("Dumped\t: "));
|
||||
myFile.println(RTCStamp());
|
||||
#endif
|
||||
|
@ -3064,7 +2997,7 @@ void savesummary_N64(boolean checkfound, char crcStr[9], unsigned long timeElaps
|
|||
myFile.print(F("Time\t: "));
|
||||
myFile.println(timeElapsed);
|
||||
|
||||
myFile.println(F(" "));
|
||||
myFile.println(FS(FSTRING_SPACE));
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
|
@ -3127,11 +3060,11 @@ void flashRepro_N64() {
|
|||
println_Msg(F("Unknown flashrom"));
|
||||
print_Msg(F("ID: "));
|
||||
print_Msg(vendorID);
|
||||
print_Msg(F(" "));
|
||||
print_Msg(FS(FSTRING_SPACE));
|
||||
print_Msg(flashid_str);
|
||||
print_Msg(F(" "));
|
||||
print_Msg(FS(FSTRING_SPACE));
|
||||
println_Msg(cartID);
|
||||
println_Msg(F(" "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
println_Msg(F("Press button for"));
|
||||
println_Msg(F("manual config"));
|
||||
println_Msg(F("This will erase your"));
|
||||
|
@ -3294,7 +3227,7 @@ void flashRepro_N64() {
|
|||
// Check if erase was successful
|
||||
if (blankcheckFlashrom_N64()) {
|
||||
// Write flashrom
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
print_Msg(F("Writing "));
|
||||
println_Msg(filePath);
|
||||
display_Update();
|
||||
|
@ -3336,7 +3269,7 @@ void flashRepro_N64() {
|
|||
display_Update();
|
||||
writeErrors = verifyFlashrom_N64();
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
print_Msg(writeErrors);
|
||||
|
@ -3384,17 +3317,21 @@ void resetFlashrom_N64(unsigned long flashBase) {
|
|||
delay(100);
|
||||
}
|
||||
|
||||
void sendFlashromCommand_N64(unsigned long addr, byte cmd) {
|
||||
setAddress_N64(addr + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(addr + (0x2AA << 1));
|
||||
writeWord_N64(0x55);
|
||||
setAddress_N64(addr + (0x555 << 1));
|
||||
writeWord_N64(cmd);
|
||||
}
|
||||
|
||||
void idFlashrom_N64() {
|
||||
// Set size to 0 if no ID is found
|
||||
cartSize = 0;
|
||||
|
||||
// Send flashrom ID command
|
||||
setAddress_N64(romBase + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(romBase + (0x2AA << 1));
|
||||
writeWord_N64(0x55);
|
||||
setAddress_N64(romBase + (0x555 << 1));
|
||||
writeWord_N64(0x90);
|
||||
sendFlashromCommand_N64(romBase, 0x90);
|
||||
|
||||
// Read 1 byte vendor ID
|
||||
setAddress_N64(romBase);
|
||||
|
@ -3414,12 +3351,7 @@ void idFlashrom_N64() {
|
|||
resetFlashrom_N64(romBase);
|
||||
|
||||
// Test for second flashrom chip at 0x2000000 (32MB)
|
||||
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(romBase + 0x2000000 + (0x2AA << 1));
|
||||
writeWord_N64(0x55);
|
||||
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||
writeWord_N64(0x90);
|
||||
sendFlashromCommand_N64(romBase + 0x2000000, 0x90);
|
||||
|
||||
char tempID[5];
|
||||
setAddress_N64(romBase + 0x2000000);
|
||||
|
@ -3442,12 +3374,7 @@ void idFlashrom_N64() {
|
|||
resetFlashrom_N64(romBase + 0x800000);
|
||||
|
||||
// Test for second flashrom chip at 0x800000 (8MB)
|
||||
setAddress_N64(romBase + 0x800000 + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(romBase + 0x800000 + (0x2AA << 1));
|
||||
writeWord_N64(0x55);
|
||||
setAddress_N64(romBase + 0x800000 + (0x555 << 1));
|
||||
writeWord_N64(0x90);
|
||||
sendFlashromCommand_N64(romBase + 0x800000, 0x90);
|
||||
|
||||
char tempID[5];
|
||||
setAddress_N64(romBase + 0x800000);
|
||||
|
@ -3470,12 +3397,7 @@ void idFlashrom_N64() {
|
|||
resetIntel4400_N64();
|
||||
|
||||
// Test if second half of the flashrom might be hidden
|
||||
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(romBase + 0x2000000 + (0x2AA << 1));
|
||||
writeWord_N64(0x55);
|
||||
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||
writeWord_N64(0x90);
|
||||
sendFlashromCommand_N64(romBase + 0x2000000, 0x90);
|
||||
|
||||
// Read manufacturer ID
|
||||
setAddress_N64(romBase + 0x2000000);
|
||||
|
@ -3718,18 +3640,8 @@ void eraseFlashrom_N64() {
|
|||
display_Update();
|
||||
|
||||
// Send Erase Command
|
||||
setAddress_N64(romBase + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(romBase + (0x2AA << 1));
|
||||
writeWord_N64(0x55);
|
||||
setAddress_N64(romBase + (0x555 << 1));
|
||||
writeWord_N64(0x80);
|
||||
setAddress_N64(romBase + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(romBase + (0x2AA << 1));
|
||||
writeWord_N64(0x55);
|
||||
setAddress_N64(romBase + (0x555 << 1));
|
||||
writeWord_N64(0x10);
|
||||
sendFlashromCommand_N64(romBase, 0x80);
|
||||
sendFlashromCommand_N64(romBase, 0x10);
|
||||
|
||||
// Read the status register
|
||||
setAddress_N64(romBase);
|
||||
|
@ -3765,12 +3677,7 @@ void eraseSector_N64(unsigned long sectorSize) {
|
|||
}
|
||||
|
||||
// Send Erase Command
|
||||
setAddress_N64(flashBase + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(flashBase + (0x2AA << 1));
|
||||
writeWord_N64(0x55);
|
||||
setAddress_N64(flashBase + (0x555 << 1));
|
||||
writeWord_N64(0x80);
|
||||
sendFlashromCommand_N64(flashBase, 0x80);
|
||||
setAddress_N64(flashBase + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(flashBase + (0x2AA << 1));
|
||||
|
@ -3778,6 +3685,7 @@ void eraseSector_N64(unsigned long sectorSize) {
|
|||
setAddress_N64(romBase + currSector);
|
||||
writeWord_N64(0x30);
|
||||
|
||||
|
||||
// Read the status register
|
||||
setAddress_N64(romBase + currSector);
|
||||
word statusReg = readWord_N64();
|
||||
|
@ -3998,13 +3906,7 @@ void writeFlashrom_N64(unsigned long sectorSize) {
|
|||
// Join two bytes into one word
|
||||
word currWord = ((sdBuffer[currByte] & 0xFF) << 8) | (sdBuffer[currByte + 1] & 0xFF);
|
||||
// 2 unlock commands
|
||||
setAddress_N64(flashBase + (0x555 << 1));
|
||||
writeWord_N64(0xAA);
|
||||
setAddress_N64(flashBase + (0x2AA << 1));
|
||||
writeWord_N64(0x55);
|
||||
// Program command
|
||||
setAddress_N64(flashBase + (0x555 << 1));
|
||||
writeWord_N64(0xA0);
|
||||
sendFlashromCommand_N64(flashBase, 0xA0);
|
||||
// Write word
|
||||
setAddress_N64(romBase + currSector + currSdBuffer + currByte);
|
||||
writeWord_N64(currWord);
|
||||
|
@ -4064,6 +3966,15 @@ unsigned long verifyFlashrom_N64() {
|
|||
/******************************************
|
||||
N64 Gameshark Flash Functions
|
||||
*****************************************/
|
||||
void sendFlashromGamesharkCommand_N64(uint16_t cmd) {
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xAAAA);
|
||||
setAddress_N64(0x1EE05554);
|
||||
writeWord_N64(0x5555);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(cmd);
|
||||
}
|
||||
|
||||
void flashGameshark_N64() {
|
||||
// Check flashrom ID's
|
||||
unlockGSAddressRanges();
|
||||
|
@ -4141,7 +4052,7 @@ void flashGameshark_N64() {
|
|||
display_Clear();
|
||||
display_Update();
|
||||
println_Msg(F("Verfied OK"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("Turn Cart Reader off now"));
|
||||
display_Update();
|
||||
while (1)
|
||||
|
@ -4178,12 +4089,7 @@ void unlockGSAddressRanges() {
|
|||
void idGameshark_N64() {
|
||||
flashid = 0x0;
|
||||
//Send flashrom ID command
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xAAAA);
|
||||
setAddress_N64(0x1EE05554);
|
||||
writeWord_N64(0x5555);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0x9090);
|
||||
sendFlashromGamesharkCommand_N64(0x9090);
|
||||
|
||||
setAddress_N64(0x1EC00000);
|
||||
// Read 1 byte vendor ID
|
||||
|
@ -4213,48 +4119,18 @@ void idGameshark_N64() {
|
|||
void resetGameshark_N64() {
|
||||
if (flashid == 0x0808 || flashid == 0x3535 || flashid == 0x0707) {
|
||||
// Send reset command for SST 29LE010 / AMTEL AT29LV010A / SST 29EE010
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xAAAA);
|
||||
setAddress_N64(0x1EE05554);
|
||||
writeWord_N64(0x5555);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xF0F0);
|
||||
sendFlashromGamesharkCommand_N64(0xF0F0);
|
||||
delay(100);
|
||||
} else if (flashid == 0x0404) {
|
||||
// Send reset command for SST 28LF040
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xAAAA);
|
||||
setAddress_N64(0x1EE05554);
|
||||
writeWord_N64(0x5555);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xFFFF);
|
||||
sendFlashromGamesharkCommand_N64(0xFFFF);
|
||||
delay(300);
|
||||
}
|
||||
}
|
||||
|
||||
// Read rom and save to the SD card
|
||||
void backupGameshark_N64() {
|
||||
// create a new folder
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(fileName, "GS%d", foldern);
|
||||
strcat(fileName, ".z64");
|
||||
sd.mkdir("N64/ROM/Gameshark", true);
|
||||
sd.chdir("N64/ROM/Gameshark");
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Saving "));
|
||||
print_Msg(fileName);
|
||||
println_Msg(F("..."));
|
||||
display_Update();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(sd_error_STR);
|
||||
}
|
||||
createFolderAndOpenFile("N64", "ROM", "GameShark", "z64");
|
||||
|
||||
for (unsigned long currByte = romBase + 0xEC00000; currByte < (romBase + 0xEC00000 + flashSize); currByte += 512) {
|
||||
// Blink led
|
||||
|
@ -4286,18 +4162,8 @@ void eraseGameshark_N64() {
|
|||
|
||||
// Send chip erase to SST 29LE010 / AMTEL AT29LV010A / SST 29EE010
|
||||
if (flashid == 0x0808 || flashid == 0x3535 || flashid == 0x0707) {
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xAAAA);
|
||||
setAddress_N64(0x1EE05554);
|
||||
writeWord_N64(0x5555);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0x8080);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xAAAA);
|
||||
setAddress_N64(0x1EE05554);
|
||||
writeWord_N64(0x5555);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0x1010);
|
||||
sendFlashromGamesharkCommand_N64(0x8080);
|
||||
sendFlashromGamesharkCommand_N64(0x1010);
|
||||
|
||||
delay(20);
|
||||
}
|
||||
|
@ -4321,12 +4187,7 @@ void eraseGameshark_N64() {
|
|||
delay(1000);
|
||||
|
||||
//Erase flash
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xAAAA);
|
||||
setAddress_N64(0x1EE05554);
|
||||
writeWord_N64(0x5555);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0x3030);
|
||||
sendFlashromGamesharkCommand_N64(0x3030);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0x3030);
|
||||
delay(1000);
|
||||
|
@ -4369,12 +4230,7 @@ void writeGameshark_N64() {
|
|||
myFile.read(sdBuffer, 256);
|
||||
|
||||
//Send page write command to both flashroms
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xAAAA);
|
||||
setAddress_N64(0x1EE05554);
|
||||
writeWord_N64(0x5555);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xA0A0);
|
||||
sendFlashromGamesharkCommand_N64(0xA0A0);
|
||||
|
||||
// Write 1 page each, one flashrom gets the low byte, the other the high byte.
|
||||
for (unsigned long currByte = 0; currByte < 256; currByte += 2) {
|
||||
|
@ -4406,12 +4262,7 @@ void writeGameshark_N64() {
|
|||
for (unsigned long currByte = 0; currByte < 256; currByte += 2) {
|
||||
|
||||
// Send byte program command
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0xAAAA);
|
||||
setAddress_N64(0x1EE05554);
|
||||
writeWord_N64(0x5555);
|
||||
setAddress_N64(0x1EF0AAA8);
|
||||
writeWord_N64(0x1010);
|
||||
sendFlashromGamesharkCommand_N64(0x1010);
|
||||
|
||||
// Set address
|
||||
setAddress_N64(romBase + 0xEC00000 + currSector + currSdBuffer + currByte);
|
||||
|
@ -4451,7 +4302,7 @@ void writeGameshark_N64() {
|
|||
unsigned long verifyGameshark_N64() {
|
||||
uint32_t processedProgressBar = 0;
|
||||
uint32_t totalProgressBar = (uint32_t)(fileSize);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
draw_progressbar(0, totalProgressBar);
|
||||
// Open file on sd card
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
|
@ -4489,6 +4340,12 @@ unsigned long verifyGameshark_N64() {
|
|||
/******************************************
|
||||
XPLORER 64 Functions
|
||||
*****************************************/
|
||||
void sendFlashromXplorerCommand_N64(uint16_t cmd) {
|
||||
oddXPaddrWrite(0x1040AAAA, 0xAAAA);
|
||||
evenXPaddrWrite(0x10405555, 0x5555);
|
||||
oddXPaddrWrite(0x1040AAAA, cmd);
|
||||
}
|
||||
|
||||
void flashXplorer_N64() {
|
||||
// Check flashrom ID's
|
||||
idXplorer_N64();
|
||||
|
@ -4552,7 +4409,7 @@ void flashXplorer_N64() {
|
|||
display_Clear();
|
||||
display_Update();
|
||||
println_Msg(F("Verfied OK"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("Turn Cart Reader off now"));
|
||||
display_Update();
|
||||
while (1);
|
||||
|
@ -4581,9 +4438,7 @@ void flashXplorer_N64() {
|
|||
void idXplorer_N64() {
|
||||
flashid = 0x0;
|
||||
//Send flashrom ID command
|
||||
oddXPaddrWrite(0x1040AAAA, 0xAAAA);
|
||||
evenXPaddrWrite(0x10405555, 0x5555);
|
||||
oddXPaddrWrite(0x1040AAAA, 0x9090);
|
||||
sendFlashromXplorerCommand_N64(0x9090);
|
||||
|
||||
setAddress_N64(0x10760000);
|
||||
readWord_N64();
|
||||
|
@ -4608,35 +4463,14 @@ void idXplorer_N64() {
|
|||
|
||||
void resetXplorer_N64() {
|
||||
// Send reset command for SST 29LE010
|
||||
oddXPaddrWrite(0x1040AAAA, 0xAAAA);
|
||||
evenXPaddrWrite(0x10405555, 0x5555);
|
||||
oddXPaddrWrite(0x1040AAAA, 0xF0F0);
|
||||
sendFlashromXplorerCommand_N64(0xF0F0);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// Read rom and save to the SD card
|
||||
void backupXplorer_N64() {
|
||||
// create a new folder
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(fileName, "XP64-%d", foldern);
|
||||
strcat(fileName, ".z64");
|
||||
sd.mkdir("N64/ROM/XPLORER64", true);
|
||||
sd.chdir("N64/ROM/XPLORER64");
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Saving "));
|
||||
print_Msg(fileName);
|
||||
println_Msg(F("..."));
|
||||
display_Update();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(sd_error_STR);
|
||||
}
|
||||
createFolderAndOpenFile("N64", "ROM", "XPLORER64", "z64");
|
||||
|
||||
for (unsigned long currByte = 0x10400000; currByte <= 0x1043FFFF; currByte += 512) {
|
||||
// Blink led
|
||||
|
@ -4719,12 +4553,8 @@ void eraseXplorer_N64() {
|
|||
display_Update();
|
||||
|
||||
// Send chip erase to SST 29LE010
|
||||
oddXPaddrWrite(0x1040AAAA, 0xAAAA);
|
||||
evenXPaddrWrite(0x10405555, 0x5555);
|
||||
oddXPaddrWrite(0x1040AAAA, 0x8080);
|
||||
oddXPaddrWrite(0x1040AAAA, 0xAAAA);
|
||||
evenXPaddrWrite(0x10405555, 0x5555);
|
||||
oddXPaddrWrite(0x1040AAAA,0x1010);
|
||||
sendFlashromXplorerCommand_N64(0x8080);
|
||||
sendFlashromXplorerCommand_N64(0x1010);
|
||||
|
||||
delay(20);
|
||||
}
|
||||
|
@ -4770,9 +4600,7 @@ void writeXplorer_N64() {
|
|||
}
|
||||
|
||||
//Send page write command to both flashroms
|
||||
oddXPaddrWrite(0x1040AAAA, 0xAAAA);
|
||||
evenXPaddrWrite(0x10405555, 0x5555);
|
||||
oddXPaddrWrite(0x1040AAAA, 0xA0A0);
|
||||
sendFlashromXplorerCommand_N64(0xA0A0);
|
||||
|
||||
// Write 1 page each, one flashrom gets the low byte, the other the high byte.
|
||||
for (unsigned long currByte = 0; currByte < 256; currByte += 2) {
|
||||
|
@ -4794,7 +4622,7 @@ void writeXplorer_N64() {
|
|||
unsigned long verifyXplorer_N64() {
|
||||
uint32_t processedProgressBar = 0;
|
||||
uint32_t totalProgressBar = (uint32_t)(262144);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
draw_progressbar(0, totalProgressBar);
|
||||
// Open file on sd card
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
|
|
2276
Cart_Reader/NES.ino
2276
Cart_Reader/NES.ino
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,10 @@
|
|||
//******************************************
|
||||
// NGP MODULE
|
||||
//******************************************
|
||||
#ifdef enable_NGP
|
||||
#ifdef ENABLE_NGP
|
||||
|
||||
static const char ngpMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char ngpMenuItem2[] PROGMEM = "Read chip info";
|
||||
static const char ngpMenuItem3[] PROGMEM = "Change ROM size";
|
||||
//static const char ngpMenuItemReset[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsNGP[] PROGMEM = { ngpMenuItem1, ngpMenuItem2, ngpMenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsNGP[] PROGMEM = { FSTRING_READ_ROM, ngpMenuItem2, FSTRING_SET_SIZE, FSTRING_RESET };
|
||||
|
||||
static const char ngpRomItem1[] PROGMEM = "4 Mbits / 512 KB";
|
||||
static const char ngpRomItem2[] PROGMEM = "8 Mbits / 1 MB";
|
||||
|
@ -80,7 +77,7 @@ void ngpMenu() {
|
|||
break;
|
||||
}
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -174,7 +171,7 @@ void printCartInfo_NGP() {
|
|||
|
||||
println_Msg(F("NGP Cart Info"));
|
||||
|
||||
print_Msg(F("Name: "));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
|
||||
print_Msg(F("App ID: "));
|
||||
|
@ -211,32 +208,18 @@ void readROM_NGP(char* outPathBuf, size_t bufferSize) {
|
|||
changeSize_NGP();
|
||||
|
||||
// generate fullname of rom file
|
||||
snprintf(fileName, FILENAME_LENGTH, "%s.ngp", romName);
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
snprintf(folder, sizeof(folder), "NGP/ROM/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("NGP", "ROM", romName, "ngp");
|
||||
|
||||
// filling output file path to buffer
|
||||
if (outPathBuf != NULL && bufferSize > 0)
|
||||
snprintf(outPathBuf, bufferSize, "%s/%s", folder, fileName);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
printAndIncrementFolder(true);
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
// back to read mode
|
||||
dataOut();
|
||||
writeByte_NGP(0x0, 0xf0);
|
||||
|
@ -266,13 +249,7 @@ void scanChip_NGP() {
|
|||
display_Clear();
|
||||
|
||||
// generate name of report file
|
||||
snprintf(fileName, FILENAME_LENGTH, "%s.txt", romName);
|
||||
|
||||
// create a new folder to save report file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
snprintf(folder, sizeof(folder), "NGP/ROM/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("NGP", "ROM", romName, "txt");
|
||||
|
||||
print_Msg(F("Saving chip report to "));
|
||||
print_Msg(folder);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// MAGNAVOX ODYSSEY 2 MODULE
|
||||
//******************************************
|
||||
#if defined(enable_ODY2)
|
||||
#if defined(ENABLE_ODY2)
|
||||
// Magnavox Odyssey 2
|
||||
// Philips Videopac/Videopac+
|
||||
// Cartridge Pinout
|
||||
|
@ -50,9 +50,7 @@ byte ody2lo = 0; // Lowest Entry
|
|||
byte ody2hi = 4; // Highest Entry
|
||||
|
||||
byte ody2mapper;
|
||||
byte newody2mapper;
|
||||
byte ody2size;
|
||||
byte newody2size;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 07 MAPPER
|
||||
|
@ -62,11 +60,7 @@ byte newody2size;
|
|||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char ody2MenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char ody2MenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char ody2MenuItem3[] PROGMEM = "Set Size";
|
||||
static const char ody2MenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsODY2[] PROGMEM = { ody2MenuItem1, ody2MenuItem2, ody2MenuItem3, ody2MenuItem4 };
|
||||
static const char* const menuOptionsODY2[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, FSTRING_SET_SIZE, FSTRING_RESET };
|
||||
|
||||
void setup_ODY2() {
|
||||
// Request 5V
|
||||
|
@ -109,7 +103,7 @@ void setup_ODY2() {
|
|||
checkStatus_ODY2();
|
||||
strcpy(romName, "ODYSSEY2");
|
||||
|
||||
mode = mode_ODY2;
|
||||
mode = CORE_ODY2;
|
||||
}
|
||||
|
||||
void ody2Menu() {
|
||||
|
@ -120,7 +114,6 @@ void ody2Menu() {
|
|||
case 0:
|
||||
// Select Cart
|
||||
setCart_ODY2();
|
||||
wait();
|
||||
setup_ODY2();
|
||||
break;
|
||||
|
||||
|
@ -219,29 +212,7 @@ void bankSwitch_ODY2(uint16_t addr, uint8_t data) {
|
|||
}
|
||||
|
||||
void readROM_ODY2() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".bin");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "ODY2/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Saving to "));
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(create_file_STR);
|
||||
}
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("ODY2", "ROM", romName, "bin");
|
||||
|
||||
if (ody2mapper == 1) { // A10 CONNECTED
|
||||
// Videopac 31: Musician
|
||||
|
@ -271,10 +242,9 @@ void readROM_ODY2() {
|
|||
}
|
||||
myFile.close();
|
||||
|
||||
unsigned long crcsize = ODY2[ody2size] * 0x400;
|
||||
calcCRC(fileName, crcsize, NULL, 0);
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -284,78 +254,26 @@ void readROM_ODY2() {
|
|||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRomSize_ODY2(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(ODY2[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_ODY2() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte newody2size;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (ody2lo == ody2hi)
|
||||
newody2size = ody2lo;
|
||||
else {
|
||||
int b = 0;
|
||||
int i = ody2lo;
|
||||
newody2size = navigateMenu(ody2lo, ody2hi, &printRomSize_ODY2);
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(ODY2[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == ody2lo)
|
||||
i = ody2hi;
|
||||
else
|
||||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(ODY2[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == ody2hi)
|
||||
i = ody2lo;
|
||||
else
|
||||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(ODY2[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newody2size = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(ODY2[newody2size]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -380,7 +298,7 @@ setrom:
|
|||
newody2size = sizeROM.toInt() + ody2lo;
|
||||
if (newody2size > ody2hi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
|
@ -404,14 +322,14 @@ void checkStatus_ODY2() {
|
|||
EEPROM_writeAnything(8, ody2size);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("ODYSSEY 2 READER"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(F("MAPPER: "));
|
||||
println_Msg(ody2mapper);
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(ODY2[ody2size]);
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -422,255 +340,33 @@ void checkStatus_ODY2() {
|
|||
Serial.print(F("CURRENT ROM SIZE: "));
|
||||
Serial.print(ODY2[ody2size]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
|
||||
FsFile ody2csvFile;
|
||||
char ody2game[51]; // title
|
||||
char ody2mm[3]; // mapper (A10)
|
||||
char ody2rr[3]; // romsize
|
||||
char ody2ll[4]; // linelength (previous line)
|
||||
unsigned long ody2csvpos; // CSV File Position
|
||||
char ody2cartCSV[] = "ody2cart.txt"; // CSV List
|
||||
char ody2csvEND[] = "EOF"; // CSV End Marker for scrolling
|
||||
|
||||
bool readLine_ODY2(FsFile& f, char* line, size_t maxLen) {
|
||||
for (size_t n = 0; n < maxLen; n++) {
|
||||
int c = f.read();
|
||||
if (c < 0 && n == 0) return false; // EOF
|
||||
if (c < 0 || c == '\n') {
|
||||
line[n] = 0;
|
||||
return true;
|
||||
}
|
||||
line[n] = c;
|
||||
}
|
||||
return false; // line too long
|
||||
}
|
||||
|
||||
bool readVals_ODY2(char* ody2game, char* ody2mm, char* ody2rr, char* ody2ll) {
|
||||
char line[59];
|
||||
ody2csvpos = ody2csvFile.position();
|
||||
if (!readLine_ODY2(ody2csvFile, line, sizeof(line))) {
|
||||
return false; // EOF or too long
|
||||
}
|
||||
char* comma = strtok(line, ",");
|
||||
int x = 0;
|
||||
while (comma != NULL) {
|
||||
if (x == 0)
|
||||
strcpy(ody2game, comma);
|
||||
else if (x == 1)
|
||||
strcpy(ody2mm, comma);
|
||||
else if (x == 2)
|
||||
strcpy(ody2rr, comma);
|
||||
else if (x == 3)
|
||||
strcpy(ody2ll, comma);
|
||||
comma = strtok(NULL, ",");
|
||||
x += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getCartListInfo_ODY2() {
|
||||
bool buttonreleased = 0;
|
||||
bool cartselected = 0;
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F(" HOLD TO FAST CYCLE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("HOLD BUTTON TO FAST CYCLE"));
|
||||
#endif
|
||||
delay(2000);
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Held - Fast Cycle
|
||||
while (1) { // Scroll Game List
|
||||
while (readVals_ODY2(ody2game, ody2mm, ody2rr, ody2ll)) {
|
||||
if (strcmp(ody2csvEND, ody2game) == 0) {
|
||||
ody2csvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(ody2game);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(ody2game);
|
||||
#endif
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
buttonreleased = 1;
|
||||
break;
|
||||
}
|
||||
if (buttonreleased) {
|
||||
buttonreleased = 0; // Reset Flag
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) // Button Released
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("FAST CYCLE OFF"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("FAST CYCLE OFF"));
|
||||
Serial.println(F("PRESS BUTTON TO STEP FORWARD"));
|
||||
Serial.println(F("DOUBLE CLICK TO STEP BACK"));
|
||||
Serial.println(F("HOLD TO SELECT"));
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
while (readVals_ODY2(ody2game, ody2mm, ody2rr, ody2ll)) {
|
||||
if (strcmp(ody2csvEND, ody2game) == 0) {
|
||||
ody2csvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(ody2game);
|
||||
display.setCursor(0, 48);
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(ody2game);
|
||||
#endif
|
||||
while (1) { // Single Step
|
||||
int b = checkButton();
|
||||
if (b == 1) { // Continue (press)
|
||||
break;
|
||||
}
|
||||
if (b == 2) { // Reset to Start of List (doubleclick)
|
||||
byte prevline = strtol(ody2ll, NULL, 10);
|
||||
ody2csvpos -= prevline;
|
||||
ody2csvFile.seek(ody2csvpos);
|
||||
break;
|
||||
}
|
||||
if (b == 3) { // Long Press - Select Cart (hold)
|
||||
newody2mapper = strtol(ody2mm, NULL, 10);
|
||||
newody2size = strtol(ody2rr, NULL, 10);
|
||||
EEPROM_writeAnything(7, newody2mapper);
|
||||
EEPROM_writeAnything(8, newody2size);
|
||||
cartselected = 1; // SELECTION MADE
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F("SELECTION MADE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("SELECTION MADE"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartselected) {
|
||||
cartselected = 0; // Reset Flag
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("END OF FILE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("END OF FILE"));
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkCSV_ODY2() {
|
||||
if (getCartListInfo_ODY2()) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART SELECTED"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(ody2game);
|
||||
display_Update();
|
||||
// Display Settings
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("CODE: M"));
|
||||
print_Msg(newody2mapper);
|
||||
print_Msg(F("/R"));
|
||||
println_Msg(newody2size);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("CART SELECTED"));
|
||||
Serial.println(ody2game);
|
||||
// Display Settings
|
||||
Serial.print(F("CODE: M"));
|
||||
Serial.print(newody2mapper);
|
||||
Serial.print(F("/R"));
|
||||
Serial.println(newody2size);
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("NO SELECTION"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("NO SELECTION"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void setCart_ODY2() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(ody2cartCSV);
|
||||
display_Update();
|
||||
#endif
|
||||
//go to root
|
||||
sd.chdir();
|
||||
sprintf(folder, "ODY2/CSV");
|
||||
sd.chdir(folder); // Switch Folder
|
||||
ody2csvFile = sd.open(ody2cartCSV, O_READ);
|
||||
if (!ody2csvFile) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CSV FILE NOT FOUND!"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("CSV FILE NOT FOUND!"));
|
||||
#endif
|
||||
while (1) {
|
||||
if (checkButton() != 0)
|
||||
setup_ODY2();
|
||||
}
|
||||
}
|
||||
checkCSV_ODY2();
|
||||
|
||||
ody2csvFile.close();
|
||||
struct database_entry_mapper_size entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("ody2cart.txt", O_READ)) {
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
if(checkCartSelection(myFile, &readDataLineMapperSize, &entry)) {
|
||||
EEPROM_writeAnything(7, entry.gameMapper);
|
||||
EEPROM_writeAnything(8, entry.gameSize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//******************************************
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
* Contains various enums, variables, etc, for the main program.
|
||||
*
|
||||
* PUBLIC FUNCTIONS :
|
||||
* void setClockScale( VOLTS )
|
||||
* void setClockScale( ClockScale )
|
||||
* VOLTS setVoltage( Voltage )
|
||||
* long configGetLong( Key, OnFailure )
|
||||
* String configGetStr( Key )
|
||||
*
|
||||
* NOTES :
|
||||
* This file is a WIP, I've been moving things into it on my local working
|
||||
|
@ -32,16 +35,52 @@
|
|||
* CHANGES :
|
||||
*
|
||||
* REF NO VERSION DATE WHO DETAIL
|
||||
* 13.2 2024-03-02 Ancyker Add string constants
|
||||
* 13.2 2024-02-29 Ancyker Add config support
|
||||
* 12.5 2023-03-29 Ancyker Initial version
|
||||
*
|
||||
*H*/
|
||||
|
||||
#include "OSCR.h"
|
||||
|
||||
/*==== VARIABLES ==================================================*/
|
||||
/*==== CONSTANTS ==================================================*/
|
||||
|
||||
/**
|
||||
* String Constants
|
||||
**/
|
||||
// Firmware Version
|
||||
char ver[5] = "13.1";
|
||||
constexpr char PROGMEM FSTRING_VERSION[] = "V13.2";
|
||||
|
||||
// Universal
|
||||
constexpr char PROGMEM FSTRING_RESET[] = "Reset";
|
||||
constexpr char PROGMEM FSTRING_OK[] = "OK";
|
||||
constexpr char PROGMEM FSTRING_EMPTY[] = "";
|
||||
constexpr char PROGMEM FSTRING_SPACE[] = " ";
|
||||
constexpr char PROGMEM FSTRING_CURRENT_SETTINGS[] = "CURRENT SETTINGS";
|
||||
|
||||
// Messages
|
||||
constexpr char PROGMEM FSTRING_OSCR[] = "OSCR";
|
||||
constexpr char PROGMEM FSTRING_MODULE_NOT_ENABLED[] = "Module is not enabled.";
|
||||
constexpr char PROGMEM FSTRING_DATABASE_FILE_NOT_FOUND[] = "Database file not found";
|
||||
constexpr char PROGMEM FSTRING_FILE_DOESNT_EXIST[] = "File doesn't exist";
|
||||
|
||||
// Cart
|
||||
constexpr char PROGMEM FSTRING_READ_ROM[] = "Read ROM";
|
||||
constexpr char PROGMEM FSTRING_READ_SAVE[] = "Read Save";
|
||||
constexpr char PROGMEM FSTRING_WRITE_SAVE[] = "Write Save";
|
||||
constexpr char PROGMEM FSTRING_SELECT_CART[] = "Select Cart";
|
||||
constexpr char PROGMEM FSTRING_SELECT_CART_TYPE[] = "Select Cart Type";
|
||||
constexpr char PROGMEM FSTRING_SET_SIZE[] = "Set Size";
|
||||
constexpr char PROGMEM FSTRING_REFRESH_CART[] = "Refresh Cart";
|
||||
constexpr char PROGMEM FSTRING_MAPPER[] = "Mapper: ";
|
||||
constexpr char PROGMEM FSTRING_SIZE[] = "Size: ";
|
||||
constexpr char PROGMEM FSTRING_NAME[] = "Name: ";
|
||||
constexpr char PROGMEM FSTRING_CHECKSUM[] = "Checksum: ";
|
||||
constexpr char PROGMEM FSTRING_ROM_SIZE[] ="ROM SIZE: ";
|
||||
|
||||
/*==== /CONSTANTS =================================================*/
|
||||
|
||||
/*==== VARIABLES ==================================================*/
|
||||
|
||||
// Clock speed
|
||||
unsigned long clock = CS_16MHZ;
|
||||
|
@ -49,6 +88,17 @@ unsigned long clock = CS_16MHZ;
|
|||
// Voltage
|
||||
VOLTS voltage = VOLTS_SET_5V;
|
||||
|
||||
#if defined(ENABLE_CONFIG)
|
||||
|
||||
FsFile configFile;
|
||||
bool useConfig;
|
||||
|
||||
# if defined(ENABLE_GLOBAL_LOG)
|
||||
// Logging
|
||||
bool loggingEnabled = true;
|
||||
# endif /* ENABLE_GLOBAL_LOG */
|
||||
#endif /* ENABLE_CONFIG */
|
||||
|
||||
/*==== /VARIABLES =================================================*/
|
||||
|
||||
/*F******************************************************************
|
||||
|
@ -57,11 +107,11 @@ VOLTS voltage = VOLTS_SET_5V;
|
|||
* DESCRIPTION : Prints the version & feature string to serial
|
||||
*
|
||||
*F*/
|
||||
#if !defined(enable_serial) && defined(ENABLE_UPDATER)
|
||||
#if !defined(ENABLE_SERIAL) && defined(ENABLE_UPDATER)
|
||||
void printVersionToSerial() {
|
||||
ClockedSerial.print(F("OSCR"));
|
||||
ClockedSerial.print(FS(FSTRING_OSCR));
|
||||
ClockedSerial.print(F("::"));
|
||||
ClockedSerial.print(ver);
|
||||
ClockedSerial.print(FS(FSTRING_VERSION));
|
||||
ClockedSerial.print(F("//"));
|
||||
#if defined(HW1)
|
||||
ClockedSerial.print(F("HW1"));
|
||||
|
@ -81,20 +131,20 @@ void printVersionToSerial() {
|
|||
#if defined (ENABLE_VSELECT)
|
||||
ClockedSerial.print(F("|VSELECT"));
|
||||
#endif
|
||||
#if defined (RTC_installed)
|
||||
#if defined (ENABLE_RTC)
|
||||
ClockedSerial.print(F("|RTC"));
|
||||
#endif
|
||||
#if defined (clockgen_installed)
|
||||
#if defined (ENABLE_CLOCKGEN)
|
||||
ClockedSerial.print(F("|CLOCKGEN"));
|
||||
#endif
|
||||
#if defined (fastcrc)
|
||||
#if defined (OPTION_N64_FASTCRC)
|
||||
ClockedSerial.print(F("|FASTCRC"));
|
||||
#endif
|
||||
#if defined (ENABLE_3V3FIX)
|
||||
ClockedSerial.print(F("|3V3FIX"));
|
||||
#endif
|
||||
|
||||
ClockedSerial.println(F(""));
|
||||
ClockedSerial.println(FS(FSTRING_EMPTY));
|
||||
}
|
||||
#else
|
||||
void printVersionToSerial() {}
|
||||
|
@ -107,7 +157,8 @@ void printVersionToSerial() {}
|
|||
*
|
||||
* INPUTS :
|
||||
* PARAMETERS:
|
||||
* VOLTS ClockScale Clock scale
|
||||
* VOLTS ClockScale Clock scale
|
||||
* CLKSCALE ClockScale Clock scale
|
||||
*
|
||||
* PROCESS :
|
||||
* [1] Enable clock prescaler change
|
||||
|
@ -139,6 +190,24 @@ void setClockScale(VOLTS __x)
|
|||
); /*[2]*/
|
||||
}
|
||||
|
||||
void setClockScale(CLKSCALE __x)
|
||||
{
|
||||
clock = (__x == CLKSCALE_16MHZ ? CS_16MHZ : CS_8MHZ);
|
||||
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 )
|
||||
*
|
||||
|
@ -197,14 +266,14 @@ VOLTS setVoltage(VOLTS newVoltage) {
|
|||
// Adjust clock speed when 3V3FIX is enabled
|
||||
#if defined(ENABLE_3V3FIX)
|
||||
// Stop serial if running
|
||||
#if !defined(enable_serial) && defined(ENABLE_UPDATER)
|
||||
#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)
|
||||
#if !defined(ENABLE_SERIAL) && defined(ENABLE_UPDATER)
|
||||
ClockedSerial.begin(UPD_BAUD);
|
||||
#endif
|
||||
#else
|
||||
|
@ -230,13 +299,13 @@ VOLTS setVoltage(VOLTS newVoltage) {
|
|||
|
||||
// Adjust clock speed when 3V3FIX is enabled
|
||||
#if defined(ENABLE_3V3FIX)
|
||||
#if !defined(enable_serial) && defined(ENABLE_UPDATER)
|
||||
#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)
|
||||
#if !defined(ENABLE_SERIAL) && defined(ENABLE_UPDATER)
|
||||
ClockedSerial.begin(UPD_BAUD);
|
||||
#endif
|
||||
#endif
|
||||
|
@ -263,3 +332,146 @@ VOLTS setVoltage(VOLTS newVoltage __attribute__((unused))) {
|
|||
return VOLTS_NOTENABLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_CONFIG)
|
||||
|
||||
/*F******************************************************************
|
||||
* NAME : void configInit()
|
||||
*
|
||||
* DESCRIPTION : Setup the config file.
|
||||
*
|
||||
*F*/
|
||||
void configInit() {
|
||||
useConfig = configFile.open(CONFIG_FILE, O_READ);
|
||||
}
|
||||
|
||||
/*F******************************************************************
|
||||
* NAME : uint8_t configFindKey( Key, Value )
|
||||
*
|
||||
* DESCRIPTION : Search for a key=value pair.
|
||||
*
|
||||
* INPUTS :
|
||||
* PARAMETERS:
|
||||
* __FlashStringHelper Key The key to get the value for.
|
||||
* char* value Variable to store the value in.
|
||||
*
|
||||
* OUTPUTS :
|
||||
* RETURN :
|
||||
* Type: uint8_t Length of the value.
|
||||
*
|
||||
* PROCESS :
|
||||
* [1] Get key length and convert to char array/string.
|
||||
* [2] Parse file line by line.
|
||||
* [3] Check if key in file matches.
|
||||
* [4] Copy string after equals character.
|
||||
* [5] Add null terminator.
|
||||
*
|
||||
* NOTES :
|
||||
* You aren't meant to use this function directly. Check the
|
||||
* functions configGetStr() and configGetLong().
|
||||
*
|
||||
*F*/
|
||||
uint8_t configFindKey(const __FlashStringHelper* searchKey, char* value) {
|
||||
if (!useConfig) return 0;
|
||||
|
||||
char key[CONFIG_KEY_MAX + 1];
|
||||
char buffer[CONFIG_KEY_MAX + CONFIG_VALUE_MAX + 4];
|
||||
int keyLen = 0;
|
||||
int valueLen = 0;
|
||||
|
||||
keyLen = strlcpy_P(key, reinterpret_cast<const char *>(searchKey), CONFIG_KEY_MAX); /*[1]*/
|
||||
|
||||
configFile.rewind();
|
||||
|
||||
while (configFile.available()) { /*[2]*/
|
||||
int bufferLen = configFile.readBytesUntil('\n', buffer, CONFIG_KEY_MAX + CONFIG_VALUE_MAX + 3);
|
||||
|
||||
if (buffer[bufferLen - 1] == '\r')
|
||||
bufferLen--;
|
||||
|
||||
if (bufferLen > (keyLen + 1)) {
|
||||
if (memcmp(buffer, key, keyLen) == 0) { /*[3]*/
|
||||
if (buffer[keyLen] == '=') { /*[4]*/
|
||||
valueLen = bufferLen - keyLen - 1;
|
||||
memcpy(&value[0], &buffer[keyLen + 1], valueLen);
|
||||
value[valueLen] = '\0'; /*[5]*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return valueLen;
|
||||
}
|
||||
|
||||
/*F******************************************************************
|
||||
* NAME : String configGetStr( Key )
|
||||
*
|
||||
* DESCRIPTION : Return the value of a key as a string.
|
||||
*
|
||||
* INPUTS :
|
||||
* PARAMETERS:
|
||||
* __FlashStringHelper Key The key to get the value for.
|
||||
*
|
||||
* OUTPUTS :
|
||||
* RETURN :
|
||||
* Type: String The value of the key or an empty string.
|
||||
*
|
||||
* PROCESS :
|
||||
* [1] Find the key via configFindKey().
|
||||
* [2] Return empty if nothing was found.
|
||||
* [3] Convert to String type.
|
||||
*
|
||||
* NOTES :
|
||||
* You can use this to get strings stored in the config file.
|
||||
* Take care when allocating memory for strings. You should
|
||||
* probably use malloc for it if it's a global variable. If
|
||||
* you do, make sure to free() it after it's not needed.
|
||||
*
|
||||
*F*/
|
||||
String configGetStr(const __FlashStringHelper* key) {
|
||||
if (!useConfig) return {};
|
||||
char value[CONFIG_VALUE_MAX + 1];
|
||||
|
||||
uint8_t valueLen = configFindKey(key, value); /*[1]*/
|
||||
if (valueLen < 1) return {}; /*[2]*/
|
||||
|
||||
String stringVal(value); /*[3]*/
|
||||
|
||||
return stringVal;
|
||||
}
|
||||
|
||||
/*F******************************************************************
|
||||
* NAME : long configGetLong( Key, OnFailure )
|
||||
*
|
||||
* DESCRIPTION : Return the value of a key as an int/long.
|
||||
*
|
||||
* INPUTS :
|
||||
* PARAMETERS:
|
||||
* __FlashStringHelper Key The key to get the value for.
|
||||
* int onFail Value to return on failure. (def=0)
|
||||
*
|
||||
* OUTPUTS :
|
||||
* RETURN :
|
||||
* Type: int The value of the key or onFail.
|
||||
*
|
||||
* PROCESS :
|
||||
* [1] Find the key via configFindKey().
|
||||
* [2] Return onFail if nothing was found.
|
||||
* [3] Convert to long int type and return.
|
||||
*
|
||||
* NOTES :
|
||||
* You can specify hex, i.e. 0xFF for 255, if you want to.
|
||||
*
|
||||
*F*/
|
||||
long configGetLong(const __FlashStringHelper* key, int onFail) {
|
||||
if (!useConfig) return onFail;
|
||||
char value[CONFIG_VALUE_MAX + 1];
|
||||
|
||||
uint8_t valueLen = configFindKey(key, value); /*[1]*/
|
||||
if (valueLen < 1) return onFail; /*[2]*/
|
||||
|
||||
return strtol(value, NULL, 0); /*[3]*/
|
||||
}
|
||||
|
||||
#endif /* ENABLE_CONFIG */
|
||||
|
|
|
@ -10,24 +10,319 @@
|
|||
#include <Wire.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/wdt.h>
|
||||
#include "SdFat.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 IN CONFIG.H !!!
|
||||
#endif
|
||||
# if !(defined(HW1) || defined(HW2) || defined(HW3) || defined(HW4) || defined(HW5) || defined(SERIAL_MONITOR))
|
||||
# error !!! PLEASE CHOOSE HARDWARE VERSION IN CONFIG.H !!!
|
||||
# endif
|
||||
|
||||
#if defined(ENABLE_3V3FIX) && !defined(ENABLE_VSELECT)
|
||||
#warning Using 3V3FIX is best with VSELECT.
|
||||
#endif
|
||||
// Let user know unsafe configs are allowed
|
||||
# if defined(ALLOW_UNSAFE_CONFIG)
|
||||
// Error if defined during GitHub CI tests. This should not happen unless someone accidentally committed their Config.h
|
||||
# if defined(GITHUB_CI)
|
||||
# error !! UNSAFE CONFIGURATIONS ARE ALLOWED !! -- This should not be enabled on the repository!
|
||||
# else /* !defined(GITHUB_CI) */
|
||||
# warning !! UNSAFE CONFIGURATIONS ARE ALLOWED !! -- Unless you are a developer this probably is not something you want set.
|
||||
# endif /* GITHUB_CI */
|
||||
# endif /* ALLOW_UNSAFE_CONFIG */
|
||||
|
||||
# if defined(ENABLE_3V3FIX) && !defined(ENABLE_VSELECT)
|
||||
# warning Using 3V3FIX is best with VSELECT.
|
||||
# endif
|
||||
|
||||
# if defined(ENABLE_VSELECT)
|
||||
|
||||
// Error if not a supported hardware version
|
||||
# if !(defined(HW4) || defined(HW5) || defined(SERIAL_MONITOR))
|
||||
# if defined(ALLOW_UNSAFE_CONFIG)
|
||||
# warning Using VSELECT with hardware revisions other than 4 or 5 is not supported.
|
||||
# else /* !defined(ALLOW_UNSAFE_CONFIG) */
|
||||
# error Using VSELECT with hardware revisions other than 4 or 5 is not supported. \
|
||||
If you understand what you are doing you can define ALLOW_UNSAFE_CONFIG in Config.h to allow compiling.
|
||||
# endif /* ALLOW_UNSAFE_CONFIG */
|
||||
# endif /* !(HW4 | HW5 | SERIAL_MONITOR) */
|
||||
|
||||
// HW4 might work but needs tested. Make sure they know it's untested.
|
||||
# if defined(HW4)
|
||||
# if defined(ALLOW_UNSAFE_CONFIG)
|
||||
# warning Using VSELECT with HW4 is untested. Verification with a multimeter before use is strongly recommended. Please remember to report back with your findings.
|
||||
# else /* !defined(ALLOW_UNSAFE_CONFIG) */
|
||||
# error Using VSELECT with HW4 is untested. Verification with a multimeter before use is strongly recommended. \
|
||||
Define ALLOW_UNSAFE_CONFIG in Config.h to allow compiling. Please report back with your findings after testing!
|
||||
# endif /* ALLOW_UNSAFE_CONFIG */
|
||||
# endif /* HW4 */
|
||||
|
||||
// SERIAL might work but needs tested. Make sure they know it's untested.
|
||||
# if defined(SERIAL_MONITOR)
|
||||
# if defined(ALLOW_UNSAFE_CONFIG)
|
||||
# warning Using VSELECT with a serial-only OSCR is untested. Verification with a multimeter before use is strongly recommended. Please remember to report back with your findings.
|
||||
# else /* !defined(ALLOW_UNSAFE_CONFIG) */
|
||||
# error Using VSELECT with a serial-only OSCR is untested. Verification with a multimeter before use is strongly recommended. \
|
||||
Define ALLOW_UNSAFE_CONFIG in Config.h to allow compiling. Please report back with your findings after testing!
|
||||
# endif /* ALLOW_UNSAFE_CONFIG */
|
||||
# endif /* SERIAL_MONITOR */
|
||||
|
||||
# endif /* ENABLE_VSELECT */
|
||||
|
||||
/*==== CONSTANTS ==================================================*/
|
||||
/**
|
||||
* String Constants
|
||||
**/
|
||||
|
||||
// Version
|
||||
extern const char PROGMEM FSTRING_VERSION[];
|
||||
|
||||
// Universal
|
||||
extern const char PROGMEM FSTRING_OK[];
|
||||
extern const char PROGMEM FSTRING_EMPTY[];
|
||||
extern const char PROGMEM FSTRING_SPACE[];
|
||||
extern const char PROGMEM FSTRING_RESET[];
|
||||
extern const char PROGMEM FSTRING_CURRENT_SETTINGS[];
|
||||
|
||||
// Messages
|
||||
extern const char PROGMEM FSTRING_OSCR[];
|
||||
extern const char PROGMEM FSTRING_MODULE_NOT_ENABLED[];
|
||||
extern const char PROGMEM FSTRING_DATABASE_FILE_NOT_FOUND[];
|
||||
extern const char PROGMEM FSTRING_FILE_DOESNT_EXIST[];
|
||||
|
||||
// Cart
|
||||
extern const char PROGMEM FSTRING_READ_ROM[];
|
||||
extern const char PROGMEM FSTRING_READ_SAVE[];
|
||||
extern const char PROGMEM FSTRING_WRITE_SAVE[];
|
||||
extern const char PROGMEM FSTRING_SELECT_CART[];
|
||||
extern const char PROGMEM FSTRING_SELECT_CART_TYPE[];
|
||||
extern const char PROGMEM FSTRING_SET_SIZE[];
|
||||
extern const char PROGMEM FSTRING_REFRESH_CART[];
|
||||
extern const char PROGMEM FSTRING_MAPPER[];
|
||||
extern const char PROGMEM FSTRING_SIZE[];
|
||||
extern const char PROGMEM FSTRING_ROM_SIZE[];
|
||||
extern const char PROGMEM FSTRING_NAME[];
|
||||
extern const char PROGMEM FSTRING_CHECKSUM[];
|
||||
|
||||
#define FS(pmem_string) (reinterpret_cast<const __FlashStringHelper *>(pmem_string))
|
||||
|
||||
/**
|
||||
* Other Constants
|
||||
**/
|
||||
// Updater baud rate
|
||||
const uint16_t UPD_BAUD = 9600;
|
||||
constexpr uint16_t UPD_BAUD = 9600;
|
||||
// Clock speeds
|
||||
const unsigned long CS_16MHZ = 16000000UL;
|
||||
const unsigned long CS_8MHZ = 8000000UL;
|
||||
constexpr unsigned long CS_16MHZ = 16000000UL;
|
||||
constexpr unsigned long CS_8MHZ = 8000000UL;
|
||||
|
||||
enum CORES: uint8_t {
|
||||
# ifdef ENABLE_N64
|
||||
CORE_N64_CART,
|
||||
CORE_N64_CONTROLLER,
|
||||
# endif
|
||||
# ifdef ENABLE_SNES
|
||||
CORE_SNES,
|
||||
# endif
|
||||
# ifdef ENABLE_SFM
|
||||
CORE_SFM,
|
||||
# ifdef ENABLE_FLASH
|
||||
CORE_SFM_FLASH,
|
||||
# endif
|
||||
CORE_SFM_GAME,
|
||||
# endif
|
||||
# ifdef ENABLE_GBX
|
||||
CORE_GB,
|
||||
CORE_GBA,
|
||||
CORE_GBM,
|
||||
CORE_GB_GBSMART,
|
||||
CORE_GB_GBSMART_FLASH,
|
||||
CORE_GB_GBSMART_GAME,
|
||||
# endif
|
||||
# ifdef ENABLE_FLASH
|
||||
CORE_FLASH8,
|
||||
# ifdef ENABLE_FLASH16
|
||||
CORE_FLASH16,
|
||||
CORE_EPROM,
|
||||
# endif
|
||||
# endif
|
||||
# ifdef ENABLE_MD
|
||||
CORE_MD_CART,
|
||||
CORE_SEGA_CD,
|
||||
# endif
|
||||
# ifdef ENABLE_PCE
|
||||
CORE_PCE,
|
||||
# endif
|
||||
# ifdef ENABLE_SV
|
||||
CORE_SV,
|
||||
# endif
|
||||
# ifdef ENABLE_NES
|
||||
CORE_NES,
|
||||
# endif
|
||||
# ifdef ENABLE_SMS
|
||||
CORE_SMS,
|
||||
# endif
|
||||
# ifdef ENABLE_WS
|
||||
CORE_WS,
|
||||
# endif
|
||||
# ifdef ENABLE_NGP
|
||||
CORE_NGP,
|
||||
# endif
|
||||
# ifdef ENABLE_INTV
|
||||
CORE_INTV,
|
||||
# endif
|
||||
# ifdef ENABLE_COLV
|
||||
CORE_COL,
|
||||
# endif
|
||||
# ifdef ENABLE_VBOY
|
||||
CORE_VBOY,
|
||||
# endif
|
||||
# ifdef ENABLE_WSV
|
||||
CORE_WSV,
|
||||
# endif
|
||||
# ifdef ENABLE_PCW
|
||||
CORE_PCW,
|
||||
# endif
|
||||
# ifdef ENABLE_ODY2
|
||||
CORE_ODY2,
|
||||
# endif
|
||||
# ifdef ENABLE_ARC
|
||||
CORE_ARC,
|
||||
# endif
|
||||
# ifdef ENABLE_FAIRCHILD
|
||||
CORE_FAIRCHILD,
|
||||
# endif
|
||||
# ifdef ENABLE_SUPRACAN
|
||||
CORE_SUPRACAN,
|
||||
# endif
|
||||
# ifdef ENABLE_MSX
|
||||
CORE_MSX,
|
||||
# endif
|
||||
# ifdef ENABLE_POKE
|
||||
CORE_POKE,
|
||||
# endif
|
||||
# ifdef ENABLE_LOOPY
|
||||
CORE_LOOPY,
|
||||
# endif
|
||||
# ifdef ENABLE_C64
|
||||
CORE_C64,
|
||||
# endif
|
||||
# ifdef ENABLE_2600
|
||||
CORE_2600,
|
||||
# endif
|
||||
# ifdef ENABLE_5200
|
||||
CORE_5200,
|
||||
# endif
|
||||
# ifdef ENABLE_7800
|
||||
CORE_7800,
|
||||
# endif
|
||||
# ifdef ENABLE_VECTREX
|
||||
CORE_VECTREX,
|
||||
# endif
|
||||
# ifdef ENABLE_ST
|
||||
CORE_ST,
|
||||
# endif
|
||||
# ifdef ENABLE_GPC
|
||||
CORE_GPC,
|
||||
# endif
|
||||
CORE_MAX // Always last
|
||||
};
|
||||
|
||||
enum SYSTEM_MENU: uint8_t {
|
||||
# if defined(ENABLE_GBX)
|
||||
SYSTEM_MENU_GBX,
|
||||
# endif
|
||||
# if defined(ENABLE_NES)
|
||||
SYSTEM_MENU_NES,
|
||||
# endif
|
||||
# if defined(ENABLE_SNES)
|
||||
SYSTEM_MENU_SNES,
|
||||
# endif
|
||||
# if defined(ENABLE_N64)
|
||||
SYSTEM_MENU_N64,
|
||||
# endif
|
||||
# if defined(ENABLE_MD)
|
||||
SYSTEM_MENU_MD,
|
||||
# endif
|
||||
# if defined(ENABLE_SMS)
|
||||
SYSTEM_MENU_SMS,
|
||||
# endif
|
||||
# if defined(ENABLE_PCE)
|
||||
SYSTEM_MENU_PCE,
|
||||
# endif
|
||||
# if defined(ENABLE_WS)
|
||||
SYSTEM_MENU_WS,
|
||||
# endif
|
||||
# if defined(ENABLE_NGP)
|
||||
SYSTEM_MENU_NGP,
|
||||
# endif
|
||||
# if defined(ENABLE_INTV)
|
||||
SYSTEM_MENU_INTV,
|
||||
# endif
|
||||
# if defined(ENABLE_COLV)
|
||||
SYSTEM_MENU_COLV,
|
||||
# endif
|
||||
# if defined(ENABLE_VBOY)
|
||||
SYSTEM_MENU_VBOY,
|
||||
# endif
|
||||
# if defined(ENABLE_WSV)
|
||||
SYSTEM_MENU_WSV,
|
||||
# endif
|
||||
# if defined(ENABLE_PCW)
|
||||
SYSTEM_MENU_PCW,
|
||||
# endif
|
||||
# if defined(ENABLE_2600)
|
||||
SYSTEM_MENU_2600,
|
||||
# endif
|
||||
# if defined(ENABLE_ODY2)
|
||||
SYSTEM_MENU_ODY2,
|
||||
# endif
|
||||
# if defined(ENABLE_ARC)
|
||||
SYSTEM_MENU_ARC,
|
||||
# endif
|
||||
# if defined(ENABLE_FAIRCHILD)
|
||||
SYSTEM_MENU_FAIRCHILD,
|
||||
# endif
|
||||
# if defined(ENABLE_SUPRACAN)
|
||||
SYSTEM_MENU_SUPRACAN,
|
||||
# endif
|
||||
# if defined(ENABLE_MSX)
|
||||
SYSTEM_MENU_MSX,
|
||||
# endif
|
||||
# if defined(ENABLE_POKE)
|
||||
SYSTEM_MENU_POKE,
|
||||
# endif
|
||||
# if defined(ENABLE_LOOPY)
|
||||
SYSTEM_MENU_LOOPY,
|
||||
# endif
|
||||
# if defined(ENABLE_C64)
|
||||
SYSTEM_MENU_C64,
|
||||
# endif
|
||||
# if defined(ENABLE_5200)
|
||||
SYSTEM_MENU_5200,
|
||||
# endif
|
||||
# if defined(ENABLE_7800)
|
||||
SYSTEM_MENU_7800,
|
||||
# endif
|
||||
# if defined(ENABLE_VECTREX)
|
||||
SYSTEM_MENU_VECTREX,
|
||||
# endif
|
||||
# if defined(ENABLE_FLASH)
|
||||
SYSTEM_MENU_FLASH,
|
||||
# endif
|
||||
# if defined(ENABLE_SELFTEST)
|
||||
SYSTEM_MENU_SELFTEST,
|
||||
# endif
|
||||
SYSTEM_MENU_ABOUT,
|
||||
SYSTEM_MENU_RESET,
|
||||
|
||||
// Total number of options available.
|
||||
SYSTEM_MENU_TOTAL // Always immediately after last menu option
|
||||
};
|
||||
|
||||
// ENUM for VSELECT & 3V3FIX
|
||||
enum CLKSCALE: uint8_t {
|
||||
// Paramters to pass to setVoltage() and setClockScale()
|
||||
CLKSCALE_16MHZ = 0, // ClockScale 0 = 16MHz
|
||||
CLKSCALE_8MHZ, // ClockScale 1 = 8MHz
|
||||
};
|
||||
|
||||
// ENUM for VSELECT & 3V3FIX
|
||||
enum VOLTS: uint8_t {
|
||||
|
@ -42,16 +337,49 @@ enum VOLTS: uint8_t {
|
|||
VOLTS_UNKNOWN // Return value for all other states
|
||||
};
|
||||
|
||||
/*==== /CONSTANTS =================================================*/
|
||||
|
||||
/*==== VARIABLES ==================================================*/
|
||||
extern unsigned long clock;
|
||||
extern char ver[5];
|
||||
//extern char ver[5];
|
||||
extern VOLTS voltage;
|
||||
|
||||
# if defined(ENABLE_CONFIG)
|
||||
/**
|
||||
* Config File Stuff
|
||||
*
|
||||
* You can register GLOBAL configuration variables in this section.
|
||||
* You should put core-specific config variables in the related file.
|
||||
**/
|
||||
|
||||
extern bool useConfig;
|
||||
# ifdef ENABLE_GLOBAL_LOG
|
||||
extern bool loggingEnabled;
|
||||
# endif /* ENABLE_GLOBAL_LOG */
|
||||
# else /* !ENABLE_CONFIG */
|
||||
# ifdef ENABLE_GLOBAL_LOG
|
||||
constexpr bool loggingEnabled = true;
|
||||
# endif /* ENABLE_GLOBAL_LOG */
|
||||
# endif /* ENABLE_CONFIG */
|
||||
|
||||
/*==== /VARIABLES =================================================*/
|
||||
|
||||
/*==== FUNCTIONS ==================================================*/
|
||||
|
||||
extern void printVersionToSerial();
|
||||
extern void setClockScale(VOLTS __x);
|
||||
extern void setClockScale(CLKSCALE __x);
|
||||
extern VOLTS setVoltage(VOLTS volts);
|
||||
|
||||
# if defined(ENABLE_CONFIG)
|
||||
extern void configInit();
|
||||
extern uint8_t configFindKey(const __FlashStringHelper* key, char* value);
|
||||
extern String configGetStr(const __FlashStringHelper* key);
|
||||
extern long configGetLong(const __FlashStringHelper* key, int onFail = 0);
|
||||
# endif /* ENABLE_CONFIG */
|
||||
|
||||
/*==== /FUNCTIONS =================================================*/
|
||||
|
||||
#include "ClockedSerial.h"
|
||||
|
||||
#endif /* OSCR_H_ */
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// Chris Covell - Tennokoe bank support
|
||||
//
|
||||
//******************************************
|
||||
#ifdef enable_PCE
|
||||
#ifdef ENABLE_PCE
|
||||
|
||||
/******************************************
|
||||
Defines
|
||||
|
@ -53,10 +53,9 @@ uint8_t tennokoe_bank_index = 0;
|
|||
static const char pceMenuItem1[] PROGMEM = "HuCARD (swapped)";
|
||||
static const char pceMenuItem2[] PROGMEM = "HuCARD(not swapped)";
|
||||
static const char pceMenuItem3[] PROGMEM = "Turbochip";
|
||||
static const char *const menuOptionspce[] PROGMEM = { pceMenuItem1, pceMenuItem2, pceMenuItem3, string_reset2 };
|
||||
static const char *const menuOptionspce[] PROGMEM = { pceMenuItem1, pceMenuItem2, pceMenuItem3, FSTRING_RESET };
|
||||
|
||||
// PCE card menu items
|
||||
static const char menuOptionspceCart_0[] PROGMEM = "Read ROM";
|
||||
static const char menuOptionspceCart_1[] PROGMEM = "Read RAM Bank %d";
|
||||
static const char menuOptionspceCart_2[] PROGMEM = "Write RAM Bank %d";
|
||||
static const char menuOptionspceCart_3[] PROGMEM = "Inc Bank Number";
|
||||
|
@ -65,8 +64,7 @@ static const char menuOptionspceCart_5[] PROGMEM = "Set %dK ROM size";
|
|||
static const char menuOptionspceCart_5_fmt[] PROGMEM = "ROM size now %dK";
|
||||
|
||||
// Turbochip menu items
|
||||
static const char pceTCMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char *const menuOptionspceTC[] PROGMEM = { pceTCMenuItem1, string_reset2 };
|
||||
static const char *const menuOptionspceTC[] PROGMEM = { FSTRING_READ_ROM, FSTRING_RESET };
|
||||
|
||||
// PCE start menu
|
||||
void pcsMenu(void) {
|
||||
|
@ -84,7 +82,7 @@ void pcsMenu(void) {
|
|||
display_Update();
|
||||
pce_internal_mode = HUCARD;
|
||||
setup_cart_PCE();
|
||||
mode = mode_PCE;
|
||||
mode = CORE_PCE;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -93,7 +91,7 @@ void pcsMenu(void) {
|
|||
display_Update();
|
||||
pce_internal_mode = HUCARD_NOSWAP;
|
||||
setup_cart_PCE();
|
||||
mode = mode_PCE;
|
||||
mode = CORE_PCE;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
@ -102,7 +100,7 @@ void pcsMenu(void) {
|
|||
display_Update();
|
||||
pce_internal_mode = TURBOCHIP;
|
||||
setup_cart_PCE();
|
||||
mode = mode_PCE;
|
||||
mode = CORE_PCE;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
@ -314,9 +312,10 @@ uint32_t detect_rom_size_PCE(void) {
|
|||
uint32_t rom_size;
|
||||
uint8_t read_byte;
|
||||
uint8_t current_byte;
|
||||
uint8_t detect_32, detect_128, detect_256, detect_512, detect_768;
|
||||
uint8_t detect_16, detect_32, detect_128, detect_256, detect_512, detect_768;
|
||||
|
||||
//Initialize variables
|
||||
detect_16 = 0;
|
||||
detect_32 = 0;
|
||||
detect_128 = 0;
|
||||
detect_256 = 0;
|
||||
|
@ -326,16 +325,23 @@ uint32_t detect_rom_size_PCE(void) {
|
|||
//Set pins to read PC Engine cart
|
||||
pin_read_write_PCE();
|
||||
|
||||
//Confirm where mirror address start from (32KB, 128KB, 256KB, 512KB, 768KB, or 1024KB)
|
||||
//Confirm where mirror address start from (16KB, 32KB, 128KB, 256KB, 512KB, 768KB, or 1024KB)
|
||||
for (current_byte = 0; current_byte < DETECTION_SIZE; current_byte++) {
|
||||
if ((current_byte != detect_32) && (current_byte != detect_128) && (current_byte != detect_256) && (current_byte != detect_512) && (current_byte != detect_768)) {
|
||||
if ((current_byte != detect_16) && (current_byte != detect_32) && (current_byte != detect_128) && (current_byte != detect_256) && (current_byte != detect_512) && (current_byte != detect_768)) {
|
||||
//If none matched, it is 1024KB
|
||||
break;
|
||||
}
|
||||
|
||||
//read byte for 32KB, 128KB, 256KB, 512KB detection
|
||||
//read byte for 16KB, 32KB, 128KB, 256KB, 512KB detection
|
||||
read_byte = read_byte_PCE(current_byte);
|
||||
|
||||
//16KB detection
|
||||
if (current_byte == detect_16) {
|
||||
if (read_byte_PCE(current_byte + 16UL * 1024UL) == read_byte) {
|
||||
detect_16++;
|
||||
}
|
||||
}
|
||||
|
||||
//32KB detection
|
||||
if (current_byte == detect_32) {
|
||||
if (read_byte_PCE(current_byte + 32UL * 1024UL) == read_byte) {
|
||||
|
@ -374,11 +380,13 @@ uint32_t detect_rom_size_PCE(void) {
|
|||
}
|
||||
|
||||
//debug
|
||||
//sprintf(fileName, "%d %d %d %d %d", detect_32, detect_128, detect_256, detect_512, detect_768); //using filename global variable as string. Initialzed in below anyways.
|
||||
//sprintf(fileName, "%d %d %d %d %d %d", detect_16, detect_32, detect_128, detect_256, detect_512, detect_768); //using filename global variable as string. Initialzed in below anyways.
|
||||
//println_Msg(fileName);
|
||||
|
||||
//ROM size detection by result
|
||||
if (detect_32 == DETECTION_SIZE) {
|
||||
if (detect_16 == DETECTION_SIZE) {
|
||||
rom_size = 16;
|
||||
} else if (detect_32 == DETECTION_SIZE) {
|
||||
rom_size = 32;
|
||||
} else if (detect_128 == DETECTION_SIZE) {
|
||||
rom_size = 128;
|
||||
|
@ -408,7 +416,7 @@ uint32_t detect_rom_size_PCE(void) {
|
|||
if (read_byte_PCE(0x1F26) == 'P' && read_byte_PCE(0x1F27) == 'O' && read_byte_PCE(0x1F28) == 'P' && read_byte_PCE(0x1F29) == 'U' && read_byte_PCE(0x1F2A) == 'L' && read_byte_PCE(0x1F2B) == 'O' && read_byte_PCE(0x1F2C) == 'U' && read_byte_PCE(0x1F2D) == 'S') {
|
||||
rom_size = 512;
|
||||
}
|
||||
//Dinoforce (World)
|
||||
//Dinoforce (Japan)
|
||||
if (read_byte_PCE(0x15A) == 'D' && read_byte_PCE(0x15B) == 'I' && read_byte_PCE(0x15C) == 'N' && read_byte_PCE(0x15D) == 'O' && read_byte_PCE(0x15E) == '-' && read_byte_PCE(0x15F) == 'F' && read_byte_PCE(0x160) == 'O' && read_byte_PCE(0x161) == 'R' && read_byte_PCE(0x162) == 'C' && read_byte_PCE(0x163) == 'E') {
|
||||
rom_size = 512;
|
||||
}
|
||||
|
@ -590,9 +598,9 @@ void read_tennokoe_bank_PCE(int bank_index) {
|
|||
// for (int i = 0; i < 16; i++) {
|
||||
// uint8_t b = sdBuffer[c + i];
|
||||
// print_Msg_PaddedHexByte(b);
|
||||
// //print_Msg(F(" "));
|
||||
// //print_Msg(FS(FSTRING_SPACE));
|
||||
// }
|
||||
// println_Msg(F(""));
|
||||
// println_Msg(FS(FSTRING_EMPTY));
|
||||
// }
|
||||
|
||||
if (block_index == 0) {
|
||||
|
@ -601,7 +609,7 @@ void read_tennokoe_bank_PCE(int bank_index) {
|
|||
uint8_t b = sdBuffer[i];
|
||||
print_Msg_PaddedHexByte(b);
|
||||
}
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
}
|
||||
if (block_index == 0 && sdBuffer[2] == 0x42 && sdBuffer[3] == 0x4D) {
|
||||
if (sdBuffer[0] != 0x48 || sdBuffer[1] != 0x55) {
|
||||
|
@ -620,7 +628,7 @@ void read_tennokoe_bank_PCE(int bank_index) {
|
|||
//Close the file:
|
||||
myFile.close();
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -717,10 +725,10 @@ void write_tennokoe_bank_PCE(int bank_index) {
|
|||
println_Msg(F("Finished"));
|
||||
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -743,15 +751,7 @@ void read_rom_PCE(void) {
|
|||
println_Msg(F("KB"));
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, "PCEROM");
|
||||
strcat(fileName, ".pce");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sd.chdir("/");
|
||||
sprintf(folder, "PCE/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("PCE", "ROM", "PCEROM", "pce");
|
||||
|
||||
print_Msg(F("Saving ROM to "));
|
||||
print_Msg(folder);
|
||||
|
@ -810,7 +810,7 @@ void read_rom_PCE(void) {
|
|||
//CRC search and rename ROM
|
||||
crc_search(fileName, folder, rom_size, crc);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -822,7 +822,7 @@ void pceMenu() {
|
|||
unsigned char mainMenu;
|
||||
|
||||
if (pce_internal_mode == HUCARD || pce_internal_mode == HUCARD_NOSWAP) {
|
||||
strcpy_P(menuOptions[0], menuOptionspceCart_0);
|
||||
strcpy_P(menuOptions[0], FSTRING_READ_ROM);
|
||||
sprintf_P(menuOptions[1], menuOptionspceCart_1, tennokoe_bank_index + 1);
|
||||
sprintf_P(menuOptions[2], menuOptionspceCart_2, tennokoe_bank_index + 1);
|
||||
strcpy_P(menuOptions[3], menuOptionspceCart_3);
|
||||
|
@ -832,7 +832,7 @@ void pceMenu() {
|
|||
} else {
|
||||
sprintf_P(menuOptions[5], menuOptionspceCart_5, FORCED_SIZE);
|
||||
}
|
||||
strcpy_P(menuOptions[6], string_reset2);
|
||||
strcpy_P(menuOptions[6], FSTRING_RESET);
|
||||
mainMenu = question_box(F("PCE HuCARD menu"), menuOptions, 7, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// BENESSE POCKET CHALLENGE W MODULE
|
||||
//******************************************
|
||||
#ifdef enable_PCW
|
||||
#ifdef ENABLE_PCW
|
||||
|
||||
// Benesse Pocket Challenge W
|
||||
// Cartridge Pinout
|
||||
|
@ -130,16 +130,13 @@ void setup_PCW() {
|
|||
|
||||
strcpy(romName, "PCW");
|
||||
|
||||
mode = mode_PCW;
|
||||
mode = CORE_PCW;
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// MENU
|
||||
//******************************************
|
||||
static const char pcwmenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char pcwmenuItem2[] PROGMEM = "Read SRAM";
|
||||
static const char pcwmenuItem3[] PROGMEM = "Write SRAM";
|
||||
static const char* const menuOptionsPCW[] PROGMEM = { pcwmenuItem1, pcwmenuItem2, pcwmenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsPCW[] PROGMEM = { FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, FSTRING_RESET };
|
||||
|
||||
void pcwMenu() {
|
||||
convertPgm(menuOptionsPCW, 4);
|
||||
|
@ -425,23 +422,12 @@ void readSingleROM_PCW() {
|
|||
print_Msg(F("READING "));
|
||||
print_Msg(rom_size / 1024 / 1024);
|
||||
print_Msg("MB SINGLE-PACK");
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
|
||||
// Create file
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".pcw");
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "PCW/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("PCW", "ROM", romName, "pcw");
|
||||
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
printAndIncrementFolder();
|
||||
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(sd_error_STR);
|
||||
|
@ -467,7 +453,7 @@ void readSingleROM_PCW() {
|
|||
compareCRC("pcw.txt", 0, 1, 0);
|
||||
|
||||
// Wait for user input
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -564,23 +550,12 @@ void readMultiROM_PCW() {
|
|||
print_Msg(F("READING "));
|
||||
print_Msg(rom_size / 1024 / 1024);
|
||||
print_Msg("MB MULTI-PACK");
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
|
||||
// Create file
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".pcw");
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "PCW/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("PCW", "ROM", romName, "pcw");
|
||||
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
printAndIncrementFolder();
|
||||
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(sd_error_STR);
|
||||
|
@ -625,7 +600,7 @@ void readMultiROM_PCW() {
|
|||
compareCRC("pcw.txt", 0, 1, 0);
|
||||
|
||||
// Wait for user input
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -636,13 +611,7 @@ void readMultiROM_PCW() {
|
|||
//******************************************
|
||||
|
||||
void readSRAM_PCW() { // readSRAM_1A()
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".srm");
|
||||
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "PCW/SAVE/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("PCW", "SAVE", romName, "srm");
|
||||
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// POKEMON MINI MODULE
|
||||
//******************************************
|
||||
#ifdef enable_POKE
|
||||
#ifdef ENABLE_POKE
|
||||
// Pokemon Mini
|
||||
// Cartridge Pinout
|
||||
// 32P 0.5mm pitch
|
||||
|
@ -79,8 +79,7 @@
|
|||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char pokeMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char* const menuOptionsPOKE[] PROGMEM = { pokeMenuItem1, string_reset2 };
|
||||
static const char* const menuOptionsPOKE[] PROGMEM = { FSTRING_READ_ROM, FSTRING_RESET };
|
||||
|
||||
void pokeMenu() {
|
||||
convertPgm(menuOptionsPOKE, 2);
|
||||
|
@ -145,7 +144,7 @@ void setup_POKE() {
|
|||
|
||||
strcpy(romName, "POKEMINI");
|
||||
|
||||
mode = mode_POKE;
|
||||
mode = CORE_POKE;
|
||||
}
|
||||
|
||||
//******************************************
|
||||
|
@ -240,28 +239,7 @@ void writeData_POKE(uint32_t addr, uint8_t data) {
|
|||
//******************************************
|
||||
|
||||
void readROM_POKE() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".min");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "POKE/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(sd_error_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("POKE", "ROM", romName, "min");
|
||||
|
||||
// read rom
|
||||
uint32_t progress = 0;
|
||||
|
@ -279,7 +257,7 @@ void readROM_POKE() {
|
|||
|
||||
// compare dump CRC with db values
|
||||
compareCRC("pkmn.txt", 0, 1, 0);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
|
|
|
@ -49,15 +49,14 @@ Also all the menus are stored in progmem and are only recalled to sram when need
|
|||
const char N64ContMenuItem1[] PROGMEM = "Test Controller";
|
||||
const char N64ContMenuItem2[] PROGMEM = "Read ControllerPak";
|
||||
const char N64ContMenuItem3[] PROGMEM = "Write ControllerPak";
|
||||
const char N64ContMenuItem4[] PROGMEM = "Reset";
|
||||
const char* const menuOptionsN64Controller[] PROGMEM = {N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, N64ContMenuItem4};
|
||||
const char* const menuOptionsN64Controller[] PROGMEM = {N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, FSTRING_RESET};
|
||||
```
|
||||
In an effort to keep the codebase as portable as possible instead of using the functions supplied by the OLED library directly to print out text, auxiliary functions like `println_Msg` are being used. So if you want to change to another display library you don't need to change all the code but only the helper functions.
|
||||
```
|
||||
void print_Msg(long unsigned int message) {
|
||||
if (enable_OLED)
|
||||
if (ENABLE_OLED)
|
||||
display.print(message);
|
||||
if (enable_Serial)
|
||||
if (ENABLE_SERIAL)
|
||||
Serial.print(message);
|
||||
}
|
||||
```
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// SF MEMORY MODULE
|
||||
//******************************************
|
||||
#ifdef enable_SFM
|
||||
#ifdef ENABLE_SFM
|
||||
|
||||
/******************************************
|
||||
SF Memory Clock Source
|
||||
|
@ -29,8 +29,7 @@ byte gameAddress[8];
|
|||
// SFM menu items
|
||||
static const char sfmMenuItem1[] PROGMEM = "Game Menu";
|
||||
static const char sfmMenuItem2[] PROGMEM = "Flash Menu";
|
||||
//static const char sfmMenuItem3[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsSFM[] PROGMEM = { sfmMenuItem1, sfmMenuItem2, string_reset2 };
|
||||
static const char* const menuOptionsSFM[] PROGMEM = { sfmMenuItem1, sfmMenuItem2, FSTRING_RESET };
|
||||
|
||||
// SFM flash menu items
|
||||
static const char sfmFlashMenuItem1[] PROGMEM = "Read Flash";
|
||||
|
@ -42,12 +41,9 @@ static const char sfmFlashMenuItem6[] PROGMEM = "Back";
|
|||
static const char* const menuOptionsSFMFlash[] PROGMEM = { sfmFlashMenuItem1, sfmFlashMenuItem2, sfmFlashMenuItem3, sfmFlashMenuItem4, sfmFlashMenuItem5, sfmFlashMenuItem6 };
|
||||
|
||||
// SFM game menu items
|
||||
static const char sfmGameMenuItem1[] PROGMEM = "Read Sram";
|
||||
static const char sfmGameMenuItem2[] PROGMEM = "Read Game";
|
||||
static const char sfmGameMenuItem3[] PROGMEM = "Write Sram";
|
||||
static const char sfmGameMenuItem4[] PROGMEM = "Switch Game";
|
||||
//static const char sfmGameMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsSFMGame[] PROGMEM = { sfmGameMenuItem1, sfmGameMenuItem2, sfmGameMenuItem3, sfmGameMenuItem4, string_reset2 };
|
||||
static const char* const menuOptionsSFMGame[] PROGMEM = { FSTRING_READ_SAVE, sfmGameMenuItem2, FSTRING_WRITE_SAVE, sfmGameMenuItem4, FSTRING_RESET };
|
||||
|
||||
void sfmMenu() {
|
||||
// create menu with title and 3 options to choose from
|
||||
|
@ -64,7 +60,7 @@ void sfmMenu() {
|
|||
break;
|
||||
// Flash menu
|
||||
case 1:
|
||||
mode = mode_SFM_Flash;
|
||||
mode = CORE_SFM_FLASH;
|
||||
break;
|
||||
// Reset
|
||||
case 2:
|
||||
|
@ -108,7 +104,7 @@ void sfmGameMenu() {
|
|||
print_Msg(gameSubMenu + 0x80, HEX);
|
||||
println_Msg(F(" Timeout"));
|
||||
println_Msg(readBank_SFM(0, 0x2400), HEX);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_FatalError(F("Powercycle SFM cart"));
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +113,7 @@ void sfmGameMenu() {
|
|||
|
||||
// Print info
|
||||
getCartInfo_SFM();
|
||||
mode = mode_SFM_Game;
|
||||
mode = CORE_SFM_GAME;
|
||||
} else {
|
||||
// No menu so switch to only game
|
||||
// Switch to game
|
||||
|
@ -129,7 +125,7 @@ void sfmGameMenu() {
|
|||
|
||||
// Print info
|
||||
getCartInfo_SFM();
|
||||
mode = mode_SFM_Game;
|
||||
mode = CORE_SFM_GAME;
|
||||
}
|
||||
} else {
|
||||
print_Error(F("Switch to HiRom failed"));
|
||||
|
@ -193,7 +189,7 @@ void sfmGameOptions() {
|
|||
break;
|
||||
}
|
||||
if (gameSubMenu != 3) {
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -201,7 +197,7 @@ void sfmGameOptions() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef enable_FLASH
|
||||
#ifdef ENABLE_FLASH
|
||||
void sfmFlashMenu() {
|
||||
// create menu with title and 6 options to choose from
|
||||
unsigned char flashSubMenu;
|
||||
|
@ -224,7 +220,7 @@ void sfmFlashMenu() {
|
|||
print_Msg(F("Switch to HiRom..."));
|
||||
display_Update();
|
||||
if (send_SFM(0x04) == 0x2A) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
|
||||
// Reset flash
|
||||
|
@ -301,7 +297,7 @@ void sfmFlashMenu() {
|
|||
print_Msg(F("Switch to HiRom..."));
|
||||
display_Update();
|
||||
if (send_SFM(0x04) == 0x2A) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
idFlash_SFM(0xC0);
|
||||
if (flashid == 0xc2f3) {
|
||||
|
@ -340,7 +336,7 @@ void sfmFlashMenu() {
|
|||
print_Msg(F("Switch to HiRom..."));
|
||||
display_Update();
|
||||
if (send_SFM(0x04) == 0x2A) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
idFlash_SFM(0xC0);
|
||||
if (flashid == 0xc2f3) {
|
||||
|
@ -391,7 +387,7 @@ void sfmFlashMenu() {
|
|||
print_Msg(F("Blankcheck..."));
|
||||
display_Update();
|
||||
if (blankcheckMapping_SFM()) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
println_Msg(F("Nope"));
|
||||
|
@ -420,11 +416,11 @@ void sfmFlashMenu() {
|
|||
|
||||
// Go back
|
||||
case 5:
|
||||
mode = mode_SFM;
|
||||
mode = CORE_SFM;
|
||||
break;
|
||||
}
|
||||
if (flashSubMenu != 5) {
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -577,7 +573,7 @@ void setup_SFM() {
|
|||
clockgen.output_enable(SI5351_CLK2, 0);
|
||||
clockgen.output_enable(SI5351_CLK0, 1);
|
||||
}
|
||||
#ifdef clockgen_installed
|
||||
#ifdef ENABLE_CLOCKGEN
|
||||
else {
|
||||
display_Clear();
|
||||
print_FatalError(F("Clock Generator not found"));
|
||||
|
@ -600,8 +596,8 @@ void setup_SFM() {
|
|||
// Abort, something is wrong
|
||||
if (timeout == 5) {
|
||||
println_Msg(F("Hirom All Timeout"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_FatalError(F("Powercycle SFM cart"));
|
||||
}
|
||||
}
|
||||
|
@ -727,7 +723,7 @@ void getCartInfo_SFM() {
|
|||
if (checkcart_SFM() == 0) {
|
||||
// Checksum either corrupt or 0000
|
||||
errorLvl = 1;
|
||||
setColor_RGB(255, 0, 0);
|
||||
rgbLed(red_color);
|
||||
display_Clear();
|
||||
println_Msg(F("ERROR"));
|
||||
println_Msg(F("Rom header corrupt"));
|
||||
|
@ -739,17 +735,17 @@ void getCartInfo_SFM() {
|
|||
}
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Name: "));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
println_Msg(F(" "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
|
||||
print_Msg(F("Version: 1."));
|
||||
println_Msg(romVersion);
|
||||
|
||||
print_Msg(F("Checksum: "));
|
||||
print_Msg(FS(FSTRING_CHECKSUM));
|
||||
println_Msg(checksumStr);
|
||||
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(FS(FSTRING_SIZE));
|
||||
print_Msg(romSize);
|
||||
println_Msg(F("Mbit "));
|
||||
|
||||
|
@ -886,14 +882,7 @@ void readROM_SFM() {
|
|||
controlIn_SFM();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".sfc");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "NP/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("NP", "ROM", romName, "sfc");
|
||||
|
||||
//clear the screen
|
||||
display_Clear();
|
||||
|
@ -1641,14 +1630,14 @@ boolean unlockHirom() {
|
|||
print_Msg(F("Switch to HiRom..."));
|
||||
display_Update();
|
||||
if (send_SFM(0x04) == 0x2A) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
// Unlock Write Protection
|
||||
print_Msg(F("Enable Write..."));
|
||||
display_Update();
|
||||
send_SFM(0x02);
|
||||
if (readBank_SFM(0, 0x2401) == 0x4) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -1720,7 +1709,7 @@ void write_SFM(int startBank, uint32_t pos) {
|
|||
print_Msg(F("Blankcheck..."));
|
||||
display_Update();
|
||||
if (blankcheck_SFM(startBank)) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
println_Msg(F("Nope"));
|
||||
|
@ -1733,7 +1722,7 @@ void write_SFM(int startBank, uint32_t pos) {
|
|||
print_Msg(F("Blankcheck..."));
|
||||
display_Update();
|
||||
if (blankcheck_SFM(startBank)) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
print_FatalError(F("Could not erase flash"));
|
||||
|
@ -1750,7 +1739,7 @@ void write_SFM(int startBank, uint32_t pos) {
|
|||
display_Update();
|
||||
writeErrors = verifyFlash_SFM(startBank, pos);
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
display_Update();
|
||||
} else {
|
||||
print_STR(error_STR, 0);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//***********************************************************
|
||||
// SEGA MASTER SYSTEM / MARK III / GAME GEAR / SG-1000 MODULE
|
||||
//***********************************************************
|
||||
#ifdef enable_SMS
|
||||
#ifdef ENABLE_SMS
|
||||
|
||||
//******************************************
|
||||
// Menus
|
||||
|
@ -16,10 +16,7 @@ static const char SMSAdapterItem6[] PROGMEM = "SG-1000 raphnet";
|
|||
static const char* const SMSAdapterMenu[] PROGMEM = { SMSAdapterItem1, SMSAdapterItem2, SMSAdapterItem3, SMSAdapterItem4, SMSAdapterItem5, SMSAdapterItem6 };
|
||||
|
||||
// Operations menu
|
||||
static const char SMSOperationItem1[] PROGMEM = "Read Rom";
|
||||
static const char SMSOperationItem2[] PROGMEM = "Read from SRAM";
|
||||
static const char SMSOperationItem3[] PROGMEM = "Write to SRAM";
|
||||
static const char* const SMSOperationMenu[] PROGMEM = { SMSOperationItem1, SMSOperationItem2, SMSOperationItem3, string_reset2 };
|
||||
static const char* const SMSOperationMenu[] PROGMEM = { FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, FSTRING_RESET };
|
||||
|
||||
// Rom sizes menu
|
||||
static const char SMSRomSizeItem1[] PROGMEM = "8 KB";
|
||||
|
@ -103,40 +100,40 @@ void smsOperations() {
|
|||
|
||||
if (system_sms) {
|
||||
if (adapter_raphnet) {
|
||||
SMSOperation = question_box(F("SMS/MarkIII raphnet"), menuOptions, 4, 0);
|
||||
SMSOperation = question_box(FS(SMSAdapterItem1), menuOptions, 4, 0);
|
||||
} else if (adapter_retrode) {
|
||||
SMSOperation = question_box(F("SMS Retrode"), menuOptions, 4, 0);
|
||||
SMSOperation = question_box(FS(SMSAdapterItem2), menuOptions, 4, 0);
|
||||
} else if (adapter_retron) {
|
||||
SMSOperation = question_box(F("SMS Retron 3in1"), menuOptions, 4, 0);
|
||||
SMSOperation = question_box(FS(SMSAdapterItem3), menuOptions, 4, 0);
|
||||
}
|
||||
} else if (system_gg) {
|
||||
if (adapter_retrode) {
|
||||
SMSOperation = question_box(F("GameGear Retrode"), menuOptions, 4, 0);
|
||||
SMSOperation = question_box(FS(SMSAdapterItem4), menuOptions, 4, 0);
|
||||
} else if (adapter_retron) {
|
||||
SMSOperation = question_box(F("GameGear Retron 3in1"), menuOptions, 4, 0);
|
||||
SMSOperation = question_box(FS(SMSAdapterItem5), menuOptions, 4, 0);
|
||||
}
|
||||
} else if (system_sg1000) {
|
||||
SMSOperation = question_box(F("SG-1000 raphnet"), menuOptions, 1, 0);
|
||||
SMSOperation = question_box(FS(SMSAdapterItem6), menuOptions, 1, 0);
|
||||
}
|
||||
|
||||
switch (SMSOperation) {
|
||||
case 0:
|
||||
// Read ROM
|
||||
mode = mode_SMS;
|
||||
mode = CORE_SMS;
|
||||
setup_SMS();
|
||||
readROM_SMS();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Read SRAM
|
||||
mode = mode_SMS;
|
||||
mode = CORE_SMS;
|
||||
setup_SMS();
|
||||
readSRAM_SMS();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Write SRAM
|
||||
mode = mode_SMS;
|
||||
mode = CORE_SMS;
|
||||
setup_SMS();
|
||||
writeSRAM_SMS();
|
||||
break;
|
||||
|
@ -394,7 +391,7 @@ void getCartInfo_SMS() {
|
|||
default:
|
||||
cartSize = 48 * 1024UL;
|
||||
// LED Error
|
||||
setColor_RGB(0, 0, 255);
|
||||
rgbLed(blue_color);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -421,7 +418,7 @@ void getCartInfo_SMS() {
|
|||
// print_Msg(bank);
|
||||
// print_Msg(F(" offset "));
|
||||
// print_Msg_PaddedHex32(mirror_offset + 0x7FF0);
|
||||
// println_Msg(F(""));
|
||||
// println_Msg(FS(FSTRING_EMPTY));
|
||||
|
||||
if (strcmp(romName2, romName) == 0) {
|
||||
break;
|
||||
|
@ -509,13 +506,13 @@ void getCartInfo_SMS() {
|
|||
// Display cart info
|
||||
display_Clear();
|
||||
println_Msg(F("SMS/GG header not found"));
|
||||
println_Msg(F(" "));
|
||||
print_Msg(F("Name: "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
print_Msg(F("Selected Size: "));
|
||||
print_Msg(cartSize / 1024);
|
||||
println_Msg(F("KB"));
|
||||
println_Msg(F(" "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
sprintf(romName, "UNKNOWN");
|
||||
}
|
||||
|
||||
|
@ -527,17 +524,17 @@ void getCartInfo_SMS() {
|
|||
} else {
|
||||
println_Msg(F("GG header info"));
|
||||
}
|
||||
println_Msg(F(" "));
|
||||
print_Msg(F("Name: "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(FS(FSTRING_SIZE));
|
||||
print_Msg(cartSize / 1024);
|
||||
println_Msg(F("KB"));
|
||||
println_Msg(F(" "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
}
|
||||
|
||||
// Wait for user input
|
||||
#if (defined(enable_LCD) || defined(enable_OLED))
|
||||
#if (defined(ENABLE_LCD) || defined(ENABLE_OLED))
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -545,7 +542,7 @@ void getCartInfo_SMS() {
|
|||
#endif
|
||||
|
||||
// Turn off LED
|
||||
setColor_RGB(0, 0, 0);
|
||||
rgbLed(black_color);
|
||||
}
|
||||
|
||||
//******************************************
|
||||
|
@ -553,33 +550,15 @@ void getCartInfo_SMS() {
|
|||
//******************************************
|
||||
void readROM_SMS() {
|
||||
// Get name, add extension depending on the system and convert to char array for sd lib
|
||||
EEPROM_readAnything(0, foldern);
|
||||
strcpy(fileName, romName);
|
||||
if (system_sms) {
|
||||
strcat(fileName, ".sms");
|
||||
sprintf(folder, "SMS/ROM/%s/%d", romName, foldern);
|
||||
createFolder("SMS", "ROM", romName, "sms");
|
||||
} else if (system_gg) {
|
||||
strcat(fileName, ".gg");
|
||||
sprintf(folder, "GG/ROM/%s/%d", romName, foldern);
|
||||
createFolder("GG", "ROM", romName, "gg");
|
||||
} else {
|
||||
strcat(fileName, ".sg");
|
||||
sprintf(folder, "SG1000/ROM/%s/%d", romName, foldern);
|
||||
createFolder("SG1000", "ROM", romName, "sg");
|
||||
}
|
||||
|
||||
// Create a new folder
|
||||
sd.chdir("/");
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// Write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
printAndIncrementFolder(true);
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
|
@ -619,13 +598,13 @@ void readROM_SMS() {
|
|||
// for (word xi = 0; xi < 0x100; xi++) {
|
||||
// if (xi%16==0) {
|
||||
// print_Msg_PaddedHex16(xi);
|
||||
// print_Msg(F(" "));
|
||||
// print_Msg(FS(FSTRING_SPACE));
|
||||
// }
|
||||
// print_Msg_PaddedHexByte(sdBuffer[xi]);
|
||||
// if (xi>0&&((xi+1)%16)==0) {
|
||||
// println_Msg(F(""));
|
||||
// println_Msg(FS(FSTRING_EMPTY));
|
||||
// } else {
|
||||
// print_Msg(F(" "));
|
||||
// print_Msg(FS(FSTRING_SPACE));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
@ -649,7 +628,7 @@ void readROM_SMS() {
|
|||
compareCRC("sg1000.txt", 0, 1, 0);
|
||||
}
|
||||
|
||||
#ifdef global_log
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
save_log();
|
||||
#endif
|
||||
|
||||
|
@ -661,58 +640,37 @@ void readROM_SMS() {
|
|||
///*****************************************
|
||||
void readSRAM_SMS() {
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".sav");
|
||||
const char* system;
|
||||
|
||||
EEPROM_readAnything(0, foldern);
|
||||
if (system_gg) {
|
||||
sprintf(folder, "GG/SAVE/%s/%d", romName, foldern);
|
||||
system = "GG";
|
||||
} else {
|
||||
sprintf(folder, "SMS/SAVE/%s/%d", romName, foldern);
|
||||
system = "SMS";
|
||||
}
|
||||
createFolderAndOpenFile(system, "SAVE", romName, "sav");
|
||||
|
||||
// Create a new folder
|
||||
sd.chdir("/");
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
// Write the whole 32KB
|
||||
// When there is only 8KB of SRAM, the contents should be duplicated
|
||||
word bankSize = 16 * 1024UL;
|
||||
for (byte currBank = 0x0; currBank < 2; currBank++) {
|
||||
writeByte_SMS(0xFFFC, 0x08 | (currBank << 2));
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
// Blink led
|
||||
blinkLED();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
// Create file on sd card
|
||||
if (myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
// Write the whole 32KB
|
||||
// When there is only 8KB of SRAM, the contents should be duplicated
|
||||
word bankSize = 16 * 1024UL;
|
||||
for (byte currBank = 0x0; currBank < 2; currBank++) {
|
||||
writeByte_SMS(0xFFFC, 0x08 | (currBank << 2));
|
||||
|
||||
// Blink led
|
||||
blinkLED();
|
||||
|
||||
// Read 16KB from slot 2 which starts at 0x8000
|
||||
for (word currBuffer = 0; currBuffer < bankSize; currBuffer += 512) {
|
||||
// Fill SD buffer
|
||||
for (int currByte = 0; currByte < 512; currByte++) {
|
||||
sdBuffer[currByte] = readByte_SMS(0x8000 + currBuffer + currByte);
|
||||
}
|
||||
myFile.write(sdBuffer, 512);
|
||||
// Read 16KB from slot 2 which starts at 0x8000
|
||||
for (word currBuffer = 0; currBuffer < bankSize; currBuffer += 512) {
|
||||
// Fill SD buffer
|
||||
for (int currByte = 0; currByte < 512; currByte++) {
|
||||
sdBuffer[currByte] = readByte_SMS(0x8000 + currBuffer + currByte);
|
||||
}
|
||||
myFile.write(sdBuffer, 512);
|
||||
}
|
||||
// Close file
|
||||
myFile.close();
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
} else {
|
||||
print_FatalError(sd_error_STR);
|
||||
}
|
||||
// Close file
|
||||
myFile.close();
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
}
|
||||
|
||||
//**********************************************
|
||||
|
@ -740,7 +698,7 @@ void writeSRAM_SMS() {
|
|||
}
|
||||
print_Msg(F("sramSize: "));
|
||||
print_Msg(sramSize);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
word bankSize = 16 * 1024;
|
||||
for (word address = 0x0; address < sramSize; address += 512) {
|
||||
byte currBank = address >= bankSize ? 1 : 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// SUPER NINTENDO MODULE
|
||||
//******************************************
|
||||
#ifdef enable_SNES
|
||||
#ifdef ENABLE_SNES
|
||||
|
||||
/******************************************
|
||||
Defines
|
||||
|
@ -32,41 +32,34 @@ boolean altconf = 0;
|
|||
static const char snsMenuItem1[] PROGMEM = "SNES/SFC cartridge";
|
||||
static const char snsMenuItem2[] PROGMEM = "SF Memory Cassette";
|
||||
static const char snsMenuItem3[] PROGMEM = "Satellaview BS-X";
|
||||
static const char snsMenuItem4[] PROGMEM = "Flash repro";
|
||||
#ifdef clockgen_calibration
|
||||
static const char snsMenuItem5[] PROGMEM = "Calibrate Clock";
|
||||
//static const char snsMenuItem6[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5, string_reset2 };
|
||||
static const char snsMenuItem4[] PROGMEM = "Sufami Turbo";
|
||||
static const char snsMenuItem5[] PROGMEM = "Game Processor RAM";
|
||||
static const char snsMenuItem6[] PROGMEM = "Flash repro";
|
||||
#ifdef OPTION_CLOCKGEN_CALIBRATION
|
||||
static const char snsMenuItem7[] PROGMEM = "Calibrate Clock";
|
||||
static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5, snsMenuItem6, snsMenuItem7, FSTRING_RESET };
|
||||
#else
|
||||
//static const char snsMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, string_reset2 };
|
||||
static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5, snsMenuItem6, FSTRING_RESET };
|
||||
#endif
|
||||
|
||||
// SNES menu items
|
||||
static const char SnesMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char SnesMenuItem2[] PROGMEM = "Read Save";
|
||||
static const char SnesMenuItem3[] PROGMEM = "Write Save";
|
||||
static const char SnesMenuItem4[] PROGMEM = "Test SRAM";
|
||||
static const char SnesMenuItem5[] PROGMEM = "Cycle cart";
|
||||
static const char SnesMenuItem6[] PROGMEM = "Force cart type";
|
||||
//static const char SnesMenuItem7[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsSNES[] PROGMEM = { SnesMenuItem1, SnesMenuItem2, SnesMenuItem3, SnesMenuItem4, SnesMenuItem5, SnesMenuItem6, string_reset2 };
|
||||
static const char* const menuOptionsSNES[] PROGMEM = { FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, SnesMenuItem4, FSTRING_REFRESH_CART, SnesMenuItem6, FSTRING_RESET };
|
||||
|
||||
// Manual config menu items
|
||||
static const char confMenuItem1[] PROGMEM = "Use header info";
|
||||
static const char confMenuItem2[] PROGMEM = "4MB LoROM 256K SRAM";
|
||||
static const char confMenuItem3[] PROGMEM = "4MB HiROM 64K SRAM";
|
||||
static const char confMenuItem4[] PROGMEM = "6MB ExROM 256K SRAM";
|
||||
//static const char confMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsConfManual[] PROGMEM = { confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4, string_reset2 };
|
||||
static const char* const menuOptionsConfManual[] PROGMEM = { confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4, FSTRING_RESET };
|
||||
|
||||
// Repro menu items
|
||||
static const char reproMenuItem1[] PROGMEM = "LoROM (P0)";
|
||||
static const char reproMenuItem2[] PROGMEM = "HiROM (P0)";
|
||||
static const char reproMenuItem3[] PROGMEM = "ExLoROM (P1)";
|
||||
static const char reproMenuItem4[] PROGMEM = "ExHiROM (P1)";
|
||||
//static const char reproMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsRepro[] PROGMEM = { reproMenuItem1, reproMenuItem2, reproMenuItem3, reproMenuItem4, string_reset2 };
|
||||
static const char* const menuOptionsRepro[] PROGMEM = { reproMenuItem1, reproMenuItem2, reproMenuItem3, reproMenuItem4, FSTRING_RESET };
|
||||
|
||||
// SNES repro menu
|
||||
void reproMenu() {
|
||||
|
@ -78,7 +71,7 @@ void reproMenu() {
|
|||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (snsRepro) {
|
||||
#ifdef enable_FLASH
|
||||
#ifdef ENABLE_FLASH
|
||||
case 0:
|
||||
// LoRom
|
||||
display_Clear();
|
||||
|
@ -87,7 +80,7 @@ void reproMenu() {
|
|||
setup_Flash8();
|
||||
id_Flash8();
|
||||
wait();
|
||||
mode = mode_FLASH8;
|
||||
mode = CORE_FLASH8;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -98,7 +91,7 @@ void reproMenu() {
|
|||
setup_Flash8();
|
||||
id_Flash8();
|
||||
wait();
|
||||
mode = mode_FLASH8;
|
||||
mode = CORE_FLASH8;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
@ -109,7 +102,7 @@ void reproMenu() {
|
|||
setup_Flash8();
|
||||
id_Flash8();
|
||||
wait();
|
||||
mode = mode_FLASH8;
|
||||
mode = CORE_FLASH8;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
@ -120,7 +113,7 @@ void reproMenu() {
|
|||
setup_Flash8();
|
||||
id_Flash8();
|
||||
wait();
|
||||
mode = mode_FLASH8;
|
||||
mode = CORE_FLASH8;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -132,15 +125,15 @@ void reproMenu() {
|
|||
|
||||
// SNES start menu
|
||||
void snsMenu() {
|
||||
// create menu with title and 6 options to choose from
|
||||
// create menu with title and 7 options to choose from
|
||||
unsigned char snsCart;
|
||||
// Copy menuOptions out of progmem
|
||||
#ifdef clockgen_calibration
|
||||
convertPgm(menuOptionsSNS, 6);
|
||||
snsCart = question_box(F("Select Cart Type"), menuOptions, 6, 0);
|
||||
#ifdef OPTION_CLOCKGEN_CALIBRATION
|
||||
convertPgm(menuOptionsSNS, 8);
|
||||
snsCart = question_box(FS(FSTRING_SELECT_CART_TYPE), menuOptions, 8, 0);
|
||||
#else
|
||||
convertPgm(menuOptionsSNS, 5);
|
||||
snsCart = question_box(F("Select Cart Type"), menuOptions, 5, 0);
|
||||
convertPgm(menuOptionsSNS, 7);
|
||||
snsCart = question_box(FS(FSTRING_SELECT_CART_TYPE), menuOptions, 7, 0);
|
||||
#endif
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
|
@ -149,40 +142,58 @@ void snsMenu() {
|
|||
display_Clear();
|
||||
display_Update();
|
||||
setup_Snes();
|
||||
mode = mode_SNES;
|
||||
mode = CORE_SNES;
|
||||
break;
|
||||
|
||||
#ifdef enable_SFM
|
||||
#ifdef ENABLE_SFM
|
||||
case 1:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_SFM();
|
||||
mode = mode_SFM;
|
||||
mode = CORE_SFM;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef enable_SV
|
||||
#ifdef ENABLE_SV
|
||||
case 2:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_SV();
|
||||
mode = mode_SV;
|
||||
mode = CORE_SV;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef enable_FLASH
|
||||
#ifdef ENABLE_ST
|
||||
case 3:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_ST();
|
||||
mode = CORE_ST;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_GPC
|
||||
case 4:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GPC();
|
||||
mode = CORE_GPC;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FLASH
|
||||
case 5:
|
||||
setup_FlashVoltage();
|
||||
reproMenu();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 4:
|
||||
#ifdef clockgen_calibration
|
||||
case 6:
|
||||
#ifdef OPTION_CLOCKGEN_CALIBRATION
|
||||
clkcal();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case 7:
|
||||
#endif
|
||||
resetArduino();
|
||||
break;
|
||||
|
@ -214,7 +225,7 @@ void snesMenu() {
|
|||
compare_checksum();
|
||||
// CRC32
|
||||
compareCRC("snes.txt", 0, 1, 0);
|
||||
#ifdef global_log
|
||||
#ifdef ENABLE_GLOBAL_LOG
|
||||
save_log();
|
||||
#endif
|
||||
display_Update();
|
||||
|
@ -266,8 +277,8 @@ void snesMenu() {
|
|||
println_Msg(F("Warning:"));
|
||||
println_Msg(F("This can erase"));
|
||||
println_Msg(F("your save games"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("Press any button to"));
|
||||
println_Msg(F("start sram testing"));
|
||||
display_Update();
|
||||
|
@ -324,7 +335,7 @@ void snesMenu() {
|
|||
resetArduino();
|
||||
break;
|
||||
}
|
||||
//println_Msg(F(""));
|
||||
//println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -469,7 +480,7 @@ void setup_Snes() {
|
|||
clockgen.update_status();
|
||||
delay(500);
|
||||
}
|
||||
#ifdef clockgen_installed
|
||||
#ifdef ENABLE_CLOCKGEN
|
||||
else {
|
||||
display_Clear();
|
||||
print_FatalError(F("Clock Generator not found"));
|
||||
|
@ -729,14 +740,14 @@ void getCartInfo_SNES() {
|
|||
// Checksum either corrupt or 0000
|
||||
manualConfig = 1;
|
||||
errorLvl = 1;
|
||||
setColor_RGB(255, 0, 0);
|
||||
rgbLed(red_color);
|
||||
|
||||
display_Clear();
|
||||
println_Msg(F("ERROR"));
|
||||
println_Msg(F("Rom header corrupt"));
|
||||
println_Msg(F("or missing"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("Press button for"));
|
||||
println_Msg(F("manual configuration"));
|
||||
println_Msg(F("or powercycle if SA1"));
|
||||
|
@ -747,7 +758,7 @@ void getCartInfo_SNES() {
|
|||
}
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Title: "));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
|
||||
print_Msg(F("Revision: "));
|
||||
|
@ -762,7 +773,7 @@ void getCartInfo_SNES() {
|
|||
print_Msg(F("ExHiRom"));
|
||||
else
|
||||
print_Msg(romType);
|
||||
print_Msg(F(" "));
|
||||
print_Msg(FS(FSTRING_SPACE));
|
||||
if (romSpeed == 0)
|
||||
println_Msg(F("SlowROM"));
|
||||
else if (romSpeed == 2)
|
||||
|
@ -810,7 +821,7 @@ void getCartInfo_SNES() {
|
|||
else if (romChips == 249)
|
||||
println_Msg(F("SPC RAM RTC"));
|
||||
else
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
|
||||
|
||||
if (altconf)
|
||||
|
@ -835,19 +846,19 @@ void getCartInfo_SNES() {
|
|||
print_Msg(sramSize >> 3);
|
||||
println_Msg(F(" KB"));
|
||||
|
||||
print_Msg(F("Checksum: "));
|
||||
print_Msg(FS(FSTRING_CHECKSUM));
|
||||
println_Msg(checksumStr);
|
||||
display_Update();
|
||||
|
||||
// Wait for user input
|
||||
#if (defined(enable_LCD) || defined(enable_OLED))
|
||||
#if (defined(ENABLE_LCD) || defined(ENABLE_OLED))
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
#endif
|
||||
#ifdef enable_serial
|
||||
println_Msg(F(" "));
|
||||
#ifdef ENABLE_SERIAL
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
#endif
|
||||
|
||||
// Start manual config
|
||||
|
@ -865,7 +876,7 @@ void checkAltConf(char crcStr[9]) {
|
|||
// Get cart info
|
||||
display_Clear();
|
||||
println_Msg(F("Searching database..."));
|
||||
print_Msg(F("Checksum: "));
|
||||
print_Msg(FS(FSTRING_CHECKSUM));
|
||||
println_Msg(checksumStr);
|
||||
display_Update();
|
||||
|
||||
|
@ -922,7 +933,7 @@ void checkAltConf(char crcStr[9]) {
|
|||
if (((romSize != romSize2) || (numBanks != numBanks2)) && ((romSize2 == 10) || (romSize2 == 12) || (romSize2 == 20) || (romSize2 == 24) || (romSize2 == 40) || (romSize2 == 48))) {
|
||||
// Correct size
|
||||
println_Msg(F("Correcting size"));
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(FS(FSTRING_SIZE));
|
||||
print_Msg(romSize);
|
||||
print_Msg(F(" -> "));
|
||||
print_Msg(romSize2);
|
||||
|
@ -995,6 +1006,8 @@ boolean checkcart_SNES() {
|
|||
romType = EX; // Check if ExHiROM
|
||||
} else if (romType == 0x3A) {
|
||||
romType = HI; // Check if SPC7110
|
||||
} else if (strcmp("3BB0", checksumStr) == 0) { // invalid romType due to too long ROM name (Yuyu no Quiz de GO!GO!)
|
||||
romType = LO;
|
||||
} else {
|
||||
romType &= 1; // Must be LoROM or HiROM
|
||||
}
|
||||
|
@ -1278,30 +1291,7 @@ void readROM_SNES() {
|
|||
controlIn_SNES();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".sfc");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "SNES/ROM/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
//clear the screen
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
//open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(create_file_STR);
|
||||
}
|
||||
createFolderAndOpenFile("SNES", "ROM", romName, "sfc");
|
||||
|
||||
//Dump Derby Stallion '96 (Japan) and Sound Novel Tsukuru (Japan) - Actual Size is 24Mb
|
||||
if ((romType == LO) && (numBanks == 96) && ((strcmp("CC86", checksumStr) == 0) || (strcmp("A77B", checksumStr) == 0))) {
|
||||
|
@ -1436,7 +1426,7 @@ void readROM_SNES() {
|
|||
display_Update();
|
||||
readHiRomBanks(240, 256, &myFile);
|
||||
}
|
||||
//println_Msg(F(""));
|
||||
//println_Msg(FS(FSTRING_EMPTY));
|
||||
display_Clear(); // need more space due to the 4 progress bars
|
||||
|
||||
// Return mapping registers to initial settings...
|
||||
|
@ -1635,7 +1625,7 @@ void writeSRAM(boolean browseFile) {
|
|||
display_Update();
|
||||
|
||||
} else {
|
||||
print_Error(F("File doesnt exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1644,14 +1634,7 @@ void readSRAM() {
|
|||
controlIn_SNES();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".srm");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "SNES/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("SNES", "SAVE", romName, "srm");
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
|
@ -2236,7 +2219,7 @@ boolean eraseSRAM(byte b) {
|
|||
}
|
||||
}
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("OK"));
|
||||
println_Msg(FS(FSTRING_OK));
|
||||
return 1;
|
||||
} else {
|
||||
println_Msg(F("ERROR"));
|
||||
|
|
190
Cart_Reader/ST.ino
Normal file
190
Cart_Reader/ST.ino
Normal file
|
@ -0,0 +1,190 @@
|
|||
/******************************************
|
||||
SUPER FAMICOM SUFAMI TURBO MODULE
|
||||
******************************************/
|
||||
#ifdef ENABLE_ST
|
||||
|
||||
/******************************************
|
||||
Menu
|
||||
*****************************************/
|
||||
// Sufami Turbo menu items
|
||||
static const char stMenuItem1[] PROGMEM = "Read cart in Slot A";
|
||||
static const char stMenuItem2[] PROGMEM = "Read cart in Slot B";
|
||||
static const char* const menuOptionsST[] PROGMEM = { stMenuItem1, stMenuItem2, FSTRING_RESET };
|
||||
|
||||
void stMenu() {
|
||||
// Create ST menu with title and 3 options to choose from
|
||||
unsigned char mainMenu;
|
||||
convertPgm(menuOptionsST, 3);
|
||||
mainMenu = question_box(F("Sufami Turbo"), menuOptions, 3, 0);
|
||||
|
||||
// Wait for user choice to come back from the question box menu
|
||||
switch (mainMenu) {
|
||||
// Read cart in ST slot A
|
||||
case 0:
|
||||
readSlot(0);
|
||||
break;
|
||||
|
||||
// Read cart in ST slot B
|
||||
case 1:
|
||||
readSlot(1);
|
||||
break;
|
||||
|
||||
// Reset
|
||||
case 2:
|
||||
resetArduino();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************
|
||||
Setup
|
||||
*****************************************/
|
||||
void setup_ST() {
|
||||
// Request 5V
|
||||
setVoltage(VOLTS_SET_5V);
|
||||
|
||||
// Set cicrstPin(PG1) to Output
|
||||
DDRG |= (1 << 1);
|
||||
// Output a high signal until we're ready to start
|
||||
PORTG |= (1 << 1);
|
||||
// Set cichstPin(PG0) to Input
|
||||
DDRG &= ~(1 << 0);
|
||||
|
||||
// Set Address Pins to Output
|
||||
//A0-A7
|
||||
DDRF = 0xFF;
|
||||
//A8-A15
|
||||
DDRK = 0xFF;
|
||||
//BA0-BA7
|
||||
DDRL = 0xFF;
|
||||
//PA0-PA7
|
||||
DDRA = 0xFF;
|
||||
|
||||
// Set Control Pins to Output RST(PH0) CS(PH3) WR(PH5) RD(PH6)
|
||||
DDRH |= (1 << 0) | (1 << 3) | (1 << 5) | (1 << 6);
|
||||
// Switch RST(PH0) and WR(PH5) to HIGH
|
||||
PORTH |= (1 << 0) | (1 << 5);
|
||||
// Switch CS(PH3) and RD(PH6) to LOW
|
||||
PORTH &= ~((1 << 3) | (1 << 6));
|
||||
// Set Refresh(PE5) to Output
|
||||
DDRE |= (1 << 5);
|
||||
// Switch Refresh(PE5) to LOW (needed for SA-1)
|
||||
PORTE &= ~(1 << 5);
|
||||
// Set CPU Clock(PH1) to Output
|
||||
DDRH |= (1 << 1);
|
||||
// Set IRQ(PH4) to Input
|
||||
DDRH &= ~(1 << 4);
|
||||
// Set expand(PG5) to Input
|
||||
DDRG &= ~(1 << 5);
|
||||
// Set Data Pins (D0-D7) to Input
|
||||
DDRC = 0x00;
|
||||
// Unused pins
|
||||
// Set wram(PE4) to Output
|
||||
DDRE |= (1 << 4);
|
||||
// Set pawr(PJ1) to Output
|
||||
DDRJ |= (1 << 1);
|
||||
// Set pard(PJ0) to Output
|
||||
DDRJ |= (1 << 0);
|
||||
|
||||
//Check if Sufami Turbo adapter is inserted
|
||||
if (!getHeader(0)) {
|
||||
display_Clear();
|
||||
println_Msg(F("Sufami Turbo adapter"));
|
||||
println_Msg(F("was not found."));
|
||||
display_Update();
|
||||
wait();
|
||||
resetArduino();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************
|
||||
ROM Functions
|
||||
******************************************/
|
||||
// Verify if 'BANDAI' header is present in specified bank
|
||||
bool getHeader(unsigned int bank) {
|
||||
byte snesHeader[16];
|
||||
PORTL = bank;
|
||||
|
||||
// Read first bytes
|
||||
for (uint16_t c = 0, currByte = 0; c < 16; c++, currByte++) {
|
||||
PORTF = (currByte & 0xFF);
|
||||
PORTK = ((currByte >> 8) & 0xFF);
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
snesHeader[c] = PINC;
|
||||
}
|
||||
|
||||
// Format internal name
|
||||
buildRomName(romName, &snesHeader[0], 14);
|
||||
|
||||
// Check if 'BANDAI' header is present
|
||||
if (strncmp(romName, "BANDAI SFC-ADX", 14) == 0)
|
||||
return(1);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
// Select the slot to use and detect cart size
|
||||
void readSlot(bool cartSlot) {
|
||||
// Set control
|
||||
dataIn();
|
||||
controlIn_SNES();
|
||||
sd.chdir("/");
|
||||
display_Clear();
|
||||
|
||||
if(!cartSlot) { // Slot A was selected
|
||||
if (getHeader(32)) { // Look for a cart in slot A
|
||||
if (getHeader(48)) // Look for mirrored data in slot A
|
||||
readRom_ST(32,48); // Dump 512KB cart
|
||||
else
|
||||
readRom_ST(32,64); // Dump 1MB cart
|
||||
}
|
||||
else {
|
||||
println_Msg(F("No cart detected in Slot A"));
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
}
|
||||
else { // Slot B was selected
|
||||
if (getHeader(64)) { // Look for a cart in slot B
|
||||
if (getHeader(80)) // Look for mirrored data in slot B
|
||||
readRom_ST(64,80); // Dump 512KB cart
|
||||
else
|
||||
readRom_ST(64,96); // Dump 1MB cart
|
||||
}
|
||||
else {
|
||||
println_Msg(F("No cart detected in Slot B"));
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read ST rom to SD card
|
||||
void readRom_ST(unsigned int bankStart, unsigned int bankEnd) {
|
||||
// create a new folder to save rom file
|
||||
createFolderAndOpenFile("ST", "ROM", "SUFAMI_TURBO", "st");
|
||||
|
||||
// Read specified banks
|
||||
readLoRomBanks(bankStart + 0x80, bankEnd + 0x80, &myFile);
|
||||
|
||||
// Close file:
|
||||
myFile.close();
|
||||
|
||||
// Compare dump CRC with db values
|
||||
compareCRC("st.txt", 0, 1, 0);
|
||||
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
#endif
|
||||
|
||||
//******************************************
|
||||
// End of File
|
||||
//******************************************
|
|
@ -2,19 +2,16 @@
|
|||
// Super A'can MODULE
|
||||
// Only tested with HW3 and HW5
|
||||
//******************************************
|
||||
#ifdef enable_SUPRACAN
|
||||
#ifdef ENABLE_SUPRACAN
|
||||
|
||||
/******************************************
|
||||
Menu
|
||||
*****************************************/
|
||||
static const char acanMenuItem1[] PROGMEM = "Read Rom";
|
||||
static const char acanMenuItem2[] PROGMEM = "Read Save";
|
||||
static const char acanMenuItem3[] PROGMEM = "Write Save";
|
||||
static const char acanMenuItem4[] PROGMEM = "Read UM6650";
|
||||
static const char acanMenuItem5[] PROGMEM = "Write UM6650";
|
||||
static const char acanMenuItem6[] PROGMEM = "Flash repro";
|
||||
|
||||
static const char *const menuOptionsAcan[] PROGMEM = { acanMenuItem1, acanMenuItem2, acanMenuItem3, acanMenuItem4, acanMenuItem5, string_reset2, acanMenuItem6 };
|
||||
static const char *const menuOptionsAcan[] PROGMEM = { FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, acanMenuItem4, acanMenuItem5, FSTRING_RESET, acanMenuItem6 };
|
||||
|
||||
void setup_SuprAcan() {
|
||||
// Request 5V
|
||||
|
@ -82,7 +79,7 @@ void setup_SuprAcan() {
|
|||
clockgen.update_status();
|
||||
delay(500);
|
||||
}
|
||||
#ifdef clockgen_installed
|
||||
#ifdef ENABLE_CLOCKGEN
|
||||
else {
|
||||
print_FatalError(F("Clock Generator not found"));
|
||||
}
|
||||
|
@ -142,7 +139,7 @@ void suprAcanMenu() {
|
|||
}
|
||||
}
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
wait();
|
||||
|
@ -151,23 +148,7 @@ void suprAcanMenu() {
|
|||
static void readROM_Acan() {
|
||||
uint32_t crc32 = 0xffffffff;
|
||||
|
||||
EEPROM_readAnything(0, foldern);
|
||||
snprintf(folder, FILEPATH_LENGTH, "/ACAN/ROM/%d", foldern);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
if (!myFile.open("rom.bin", O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("/ACAN", "ROM", "rom", "bin");
|
||||
|
||||
draw_progressbar(0, cartSize);
|
||||
|
||||
|
@ -190,29 +171,12 @@ static void readROM_Acan() {
|
|||
|
||||
print_Msg(F("CRC32: "));
|
||||
print_Msg_PaddedHex32(crc32);
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_STR(done_STR, 1);
|
||||
}
|
||||
|
||||
static void readSRAM_Acan() {
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
snprintf(folder, FILEPATH_LENGTH, "/ACAN/SAVE/%d", foldern);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
if (!myFile.open("save.bin", O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("/ACAN", "SAVE", "save", "bin");
|
||||
|
||||
dataIn_MD();
|
||||
for (uint32_t i = 0; i < 0x10000; i += 1024) {
|
||||
|
@ -235,7 +199,7 @@ static void writeSRAM_Acan() {
|
|||
display_Clear();
|
||||
|
||||
if (!myFile.open(filePath, O_READ)) {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -263,7 +227,7 @@ static void verifySRAM_Acan() {
|
|||
display_Update();
|
||||
|
||||
if (!myFile.open(filePath, O_READ)) {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -293,24 +257,7 @@ static void verifySRAM_Acan() {
|
|||
}
|
||||
|
||||
static void readUM6650() {
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
snprintf(folder, sizeof(folder), "/ACAN/UM6650/%d", foldern);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
if (!myFile.open("UM6650.bin", O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("/ACAN", "UM6650", "UM6650", "bin");
|
||||
|
||||
for (uint16_t i = 0; i < 256; i++) {
|
||||
dataOut_MD();
|
||||
|
@ -331,7 +278,7 @@ static void verifyUM6650() {
|
|||
display_Update();
|
||||
|
||||
if (!myFile.open(filePath, O_READ)) {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -368,7 +315,7 @@ static void writeUM6650() {
|
|||
display_Clear();
|
||||
|
||||
if (!myFile.open(filePath, O_READ)) {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -403,7 +350,7 @@ static void flashCart_Acan() {
|
|||
display_Clear();
|
||||
|
||||
if (!myFile.open(filePath, O_READ)) {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -482,7 +429,7 @@ static void checkRomExist_Acan() {
|
|||
|
||||
cartSize = getRomSize_Acan();
|
||||
romSize = cartSize >> 17;
|
||||
mode = mode_SUPRACAN;
|
||||
mode = CORE_SUPRACAN;
|
||||
|
||||
if (cartSize == 0)
|
||||
print_Error(F("Unable to find rom signature..."));
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// Revision 1.0.0 October 22nd 2018
|
||||
// Added BSX Sram, copied from skamans enhanced sketch //sanni
|
||||
//******************************************
|
||||
#ifdef enable_SV
|
||||
#ifdef ENABLE_SV
|
||||
|
||||
/******************************************
|
||||
Satellaview 8M Memory Pack
|
||||
|
@ -37,8 +37,7 @@ static const char svFlashMenuItem1[] PROGMEM = "Read Memory Pack";
|
|||
static const char svFlashMenuItem2[] PROGMEM = "Write Memory Pack";
|
||||
static const char svFlashMenuItem3[] PROGMEM = "Read BS-X Sram";
|
||||
static const char svFlashMenuItem4[] PROGMEM = "Write BS-X Sram";
|
||||
static const char svFlashMenuItem5[] PROGMEM = "Back";
|
||||
static const char* const menuOptionsSVFlash[] PROGMEM = { svFlashMenuItem1, svFlashMenuItem2, svFlashMenuItem3, svFlashMenuItem4, svFlashMenuItem5 };
|
||||
static const char* const menuOptionsSVFlash[] PROGMEM = { svFlashMenuItem1, svFlashMenuItem2, svFlashMenuItem3, svFlashMenuItem4, FSTRING_RESET };
|
||||
|
||||
|
||||
void svMenu() {
|
||||
|
@ -122,7 +121,7 @@ void setup_SV() {
|
|||
clockgen.output_enable(SI5351_CLK1, 0);
|
||||
clockgen.output_enable(SI5351_CLK2, 1);
|
||||
}
|
||||
#ifdef clockgen_installed
|
||||
#ifdef ENABLE_CLOCKGEN
|
||||
else {
|
||||
display_Clear();
|
||||
print_FatalError(F("Clock Generator not found"));
|
||||
|
@ -289,13 +288,7 @@ void readSRAM_SV() {
|
|||
controlIn_SNES();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, "BSX.srm");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "SNES/SAVE/BSX/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("SNES", "SAVE", "BSX", "srm");
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
|
@ -374,7 +367,7 @@ void writeSRAM_SV() {
|
|||
println_Msg(F("SRAM writing finished"));
|
||||
display_Update();
|
||||
} else {
|
||||
print_Error(F("File doesnt exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,29 +413,7 @@ void readROM_SV() {
|
|||
controlIn_SNES();
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
strcpy(fileName, "MEMPACK.bs");
|
||||
|
||||
// create a new folder for the save file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "SNES/ROM/%s/%d", "MEMPACK", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
//clear the screen
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
//open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_FatalError(create_file_STR);
|
||||
}
|
||||
createFolderAndOpenFile("SNES", "ROM", "MEMPACK", "bs");
|
||||
|
||||
// Read Banks
|
||||
for (int currBank = 0x40; currBank < 0x50; currBank++) {
|
||||
|
@ -517,7 +488,7 @@ void writeROM_SV(void) {
|
|||
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
||||
for (long currByte = 0; currByte < 65536; currByte++) {
|
||||
if (0xFF != readBank_SV(currBank, currByte)) {
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("Erase failed"));
|
||||
display_Update();
|
||||
myFile.close();
|
||||
|
@ -560,7 +531,7 @@ void writeROM_SV(void) {
|
|||
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
||||
for (long currByte = 0; currByte < 65536; currByte++) {
|
||||
if (myFile.read() != readBank_SV(currBank, currByte)) {
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
println_Msg(F("Verify failed"));
|
||||
display_Update();
|
||||
myFile.close();
|
||||
|
@ -578,7 +549,7 @@ void writeROM_SV(void) {
|
|||
wait();
|
||||
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// VIRTUALBOY MODULE
|
||||
//******************************************
|
||||
#ifdef enable_VBOY
|
||||
#ifdef ENABLE_VBOY
|
||||
// Nintendo VirtualBoy
|
||||
// Cartridge Pinout
|
||||
// 60P 2.00mm pitch connector
|
||||
|
@ -89,7 +89,7 @@ void setup_VBOY() {
|
|||
|
||||
getCartInfo_VB();
|
||||
|
||||
mode = mode_VBOY;
|
||||
mode = CORE_VBOY;
|
||||
}
|
||||
|
||||
//******************************************
|
||||
|
@ -97,11 +97,7 @@ void setup_VBOY() {
|
|||
//******************************************
|
||||
|
||||
// Base Menu
|
||||
static const char vboyMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char vboyMenuItem2[] PROGMEM = "Read SRAM";
|
||||
static const char vboyMenuItem3[] PROGMEM = "Write SRAM";
|
||||
//static const char vboyMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsVBOY[] PROGMEM = { vboyMenuItem1, vboyMenuItem2, vboyMenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsVBOY[] PROGMEM = { FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, FSTRING_RESET };
|
||||
|
||||
void vboyMenu() {
|
||||
convertPgm(menuOptionsVBOY, 4);
|
||||
|
@ -127,7 +123,7 @@ void vboyMenu() {
|
|||
} else {
|
||||
print_Error(F("Cart has no SRAM"));
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#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);
|
||||
|
@ -157,7 +153,7 @@ void vboyMenu() {
|
|||
} else {
|
||||
print_Error(F("Cart has no SRAM"));
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#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);
|
||||
|
@ -384,10 +380,10 @@ void getCartInfo_VB() {
|
|||
|
||||
display_Clear();
|
||||
println_Msg(F("Cart Info"));
|
||||
println_Msg(F(" "));
|
||||
print_Msg(F("Name: "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
print_Msg(FS(FSTRING_NAME));
|
||||
println_Msg(romName);
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(FS(FSTRING_SIZE));
|
||||
print_Msg(cartSize * 8 / 1024 / 1024);
|
||||
println_Msg(F(" MBit"));
|
||||
print_Msg(F("Sram: "));
|
||||
|
@ -396,9 +392,9 @@ void getCartInfo_VB() {
|
|||
println_Msg(F(" KBit"));
|
||||
} else
|
||||
println_Msg(F("None"));
|
||||
println_Msg(F(" "));
|
||||
println_Msg(FS(FSTRING_SPACE));
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#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);
|
||||
|
@ -414,26 +410,7 @@ void getCartInfo_VB() {
|
|||
void readROM_VB() {
|
||||
dataIn_VB();
|
||||
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".vb");
|
||||
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "VBOY/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);
|
||||
}
|
||||
createFolderAndOpenFile("VBOY", "ROM", romName, "vb");
|
||||
|
||||
word d = 0;
|
||||
uint32_t progress = 0;
|
||||
|
@ -478,9 +455,9 @@ void readROM_VB() {
|
|||
// 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))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
// Wait for user input
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -517,13 +494,7 @@ void writeSRAM_VB() {
|
|||
void readSRAM_VB() {
|
||||
dataIn_VB();
|
||||
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".srm");
|
||||
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "VBOY/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
createFolder("VBOY", "SAVE", romName, "srm");
|
||||
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// VECTREX MODULE
|
||||
//******************************************
|
||||
#ifdef enable_VECTREX
|
||||
#ifdef ENABLE_VECTREX
|
||||
// Vectrex
|
||||
// Cartridge Pinout
|
||||
// 36P 2.54mm pitch connector
|
||||
|
@ -55,11 +55,10 @@
|
|||
#define PB6_ENABLE PORTH |= (1 << 5) // PB6 HIGH
|
||||
#define PB6_DISABLE PORTH &= ~(1 << 5) // PB6 LOW
|
||||
|
||||
byte VECTREX[] = { 4, 8, 12 };
|
||||
byte VECTREX[] = { 4, 8, 12, 16, 32, 64 };
|
||||
byte vectrexlo = 0; // Lowest Entry
|
||||
byte vectrexhi = 2; // Highest Entry
|
||||
byte vectrexhi = 5; // Highest Entry
|
||||
byte vectrexsize;
|
||||
byte newvectrexsize;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 08 ROM SIZE
|
||||
|
@ -68,10 +67,7 @@ byte newvectrexsize;
|
|||
// Menu
|
||||
//******************************************
|
||||
// Base Menu
|
||||
static const char vectrexMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char vectrexMenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char vectrexMenuItem3[] PROGMEM = "Set Size";
|
||||
static const char* const menuOptionsVECTREX[] PROGMEM = { vectrexMenuItem1, vectrexMenuItem2, vectrexMenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsVECTREX[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, FSTRING_SET_SIZE, FSTRING_RESET };
|
||||
|
||||
void setup_VECTREX() {
|
||||
// Request 5V
|
||||
|
@ -116,7 +112,7 @@ void setup_VECTREX() {
|
|||
checkStatus_VECTREX();
|
||||
strcpy(romName, "VECTREX");
|
||||
|
||||
mode = mode_VECTREX;
|
||||
mode = CORE_VECTREX;
|
||||
}
|
||||
|
||||
void vectrexMenu() {
|
||||
|
@ -127,7 +123,6 @@ void vectrexMenu() {
|
|||
case 0:
|
||||
// Select Cart
|
||||
setCart_VECTREX();
|
||||
wait();
|
||||
setup_VECTREX();
|
||||
break;
|
||||
|
||||
|
@ -201,45 +196,25 @@ void readSegment_VECTREX(uint16_t startaddr, uint16_t endaddr) {
|
|||
//******************************************
|
||||
|
||||
void readROM_VECTREX() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".vec");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
sprintf(folder, "VECTREX/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(sd_error_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("VECTREX", "ROM", romName, "vec");
|
||||
|
||||
PB6_DISABLE; // PB6 LOW - Switch Bank
|
||||
|
||||
// Standard Carts 4K/8K
|
||||
readSegment_VECTREX(0x0000, 0x0400); // 1K
|
||||
readSegment_VECTREX(0x0400, 0x0800); // +1K = 2K
|
||||
readSegment_VECTREX(0x0800, 0x0C00); // +1K = 3K
|
||||
readSegment_VECTREX(0x0C00, 0x1000); // +1K = 4K
|
||||
readSegment_VECTREX(0x0000, 0x1000); // 4K
|
||||
if (vectrexsize > 0) {
|
||||
readSegment_VECTREX(0x1000, 0x2000); // +4K = 8K
|
||||
// Dark Tower 12K
|
||||
// 12K (Dark Tower)
|
||||
if (vectrexsize > 1)
|
||||
readSegment_VECTREX(0x2000, 0x3000); // +4K = 12K
|
||||
// Oversize 32K Cart
|
||||
// 16K Carts
|
||||
if (vectrexsize > 2)
|
||||
readSegment_VECTREX(0x3000, 0x8000); // +20K = 32K
|
||||
// Oversize 64K Cart - PB6 Bankswitch
|
||||
if (vectrexsize > 3) { // [UNTESTED]
|
||||
readSegment_VECTREX(0x3000, 0x4000); // +4K = 16K
|
||||
// Oversize 32K Carts
|
||||
if (vectrexsize > 3)
|
||||
readSegment_VECTREX(0x4000, 0x8000); // +16K = 32K
|
||||
// Oversize 64K Carts
|
||||
if (vectrexsize > 4) {
|
||||
PB6_ENABLE; // PB6 HIGH - Switch Bank
|
||||
readSegment_VECTREX(0x0000, 0x8000); // +32K = 64K
|
||||
PB6_DISABLE; // Reset PB6
|
||||
|
@ -247,10 +222,9 @@ void readROM_VECTREX() {
|
|||
}
|
||||
myFile.close();
|
||||
|
||||
unsigned long crcsize = VECTREX[vectrexsize] * 0x400;
|
||||
calcCRC(fileName, crcsize, NULL, 0);
|
||||
printCRC(fileName, NULL, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -261,78 +235,28 @@ void readROM_VECTREX() {
|
|||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRomSize_VECTREX(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(VECTREX[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_VECTREX() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte newvectrexsize;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (vectrexlo == vectrexhi)
|
||||
newvectrexsize = vectrexlo;
|
||||
else {
|
||||
int b = 0;
|
||||
int i = vectrexlo;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(VECTREX[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == vectrexlo)
|
||||
i = vectrexhi;
|
||||
else
|
||||
i--;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(VECTREX[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == vectrexhi)
|
||||
i = vectrexlo;
|
||||
else
|
||||
i++;
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(VECTREX[i]);
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newvectrexsize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
newvectrexsize = navigateMenu(vectrexlo, vectrexhi, &printRomSize_VECTREX);
|
||||
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(VECTREX[newvectrexsize]);
|
||||
println_Msg(F("K"));
|
||||
println_Msg(F("KB"));
|
||||
display_Update();
|
||||
delay(1000);
|
||||
#else
|
||||
|
@ -346,7 +270,7 @@ setrom:
|
|||
Serial.print(i);
|
||||
Serial.print(F(" = "));
|
||||
Serial.print(VECTREX[i + vectrexlo]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F("KB"));
|
||||
}
|
||||
Serial.print(F("Enter ROM Size: "));
|
||||
while (Serial.available() == 0) {}
|
||||
|
@ -355,13 +279,13 @@ setrom:
|
|||
newvectrexsize = sizeROM.toInt() + vectrexlo;
|
||||
if (newvectrexsize > vectrexhi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
Serial.print(F("ROM Size = "));
|
||||
Serial.print(VECTREX[newvectrexsize]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F("KB"));
|
||||
#endif
|
||||
EEPROM_writeAnything(8, newvectrexsize);
|
||||
vectrexsize = newvectrexsize;
|
||||
|
@ -374,258 +298,45 @@ void checkStatus_VECTREX() {
|
|||
EEPROM_writeAnything(8, vectrexsize);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("VECTREX READER"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(VECTREX[vectrexsize]);
|
||||
println_Msg(F("K"));
|
||||
println_Msg(F("KB"));
|
||||
display_Update();
|
||||
wait();
|
||||
#else
|
||||
Serial.print(F("ROM SIZE: "));
|
||||
Serial.print(FS(FSTRING_ROM_SIZE));
|
||||
Serial.print(VECTREX[vectrexsize]);
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("KB"));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
|
||||
FsFile vectrexcsvFile;
|
||||
char vectrexgame[25]; // title
|
||||
char vectrexrr[4]; // romsize
|
||||
char vectrexll[4]; // linelength (previous line)
|
||||
unsigned long vectrexcsvpos; // CSV File Position
|
||||
char vectrexcartCSV[] = "vectrexcart.txt"; // CSV List
|
||||
char vectrexcsvEND[] = "EOF"; // CSV End Marker for scrolling
|
||||
|
||||
bool readLine_VECTREX(FsFile& f, char* line, size_t maxLen) {
|
||||
for (size_t n = 0; n < maxLen; n++) {
|
||||
int c = f.read();
|
||||
if (c < 0 && n == 0) return false; // EOF
|
||||
if (c < 0 || c == '\n') {
|
||||
line[n] = 0;
|
||||
return true;
|
||||
}
|
||||
line[n] = c;
|
||||
}
|
||||
return false; // line too long
|
||||
}
|
||||
|
||||
bool readVals_VECTREX(char* vectrexgame, char* vectrexrr, char* vectrexll) {
|
||||
char line[31];
|
||||
vectrexcsvpos = vectrexcsvFile.position();
|
||||
if (!readLine_VECTREX(vectrexcsvFile, line, sizeof(line))) {
|
||||
return false; // EOF or too long
|
||||
}
|
||||
char* comma = strtok(line, ",");
|
||||
int x = 0;
|
||||
while (comma != NULL) {
|
||||
if (x == 0)
|
||||
strcpy(vectrexgame, comma);
|
||||
else if (x == 1)
|
||||
strcpy(vectrexrr, comma);
|
||||
else if (x == 2)
|
||||
strcpy(vectrexll, comma);
|
||||
comma = strtok(NULL, ",");
|
||||
x += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getCartListInfo_VECTREX() {
|
||||
bool buttonreleased = 0;
|
||||
bool cartselected = 0;
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F(" HOLD TO FAST CYCLE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("HOLD BUTTON TO FAST CYCLE"));
|
||||
#endif
|
||||
delay(2000);
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Held - Fast Cycle
|
||||
while (1) { // Scroll Game List
|
||||
while (readVals_VECTREX(vectrexgame, vectrexrr, vectrexll)) {
|
||||
if (strcmp(vectrexcsvEND, vectrexgame) == 0) {
|
||||
vectrexcsvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(vectrexgame);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(vectrexgame);
|
||||
#endif
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
buttonreleased = 1;
|
||||
break;
|
||||
}
|
||||
if (buttonreleased) {
|
||||
buttonreleased = 0; // Reset Flag
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) // Button Released
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("FAST CYCLE OFF"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("FAST CYCLE OFF"));
|
||||
Serial.println(F("PRESS BUTTON TO STEP FORWARD"));
|
||||
Serial.println(F("DOUBLE CLICK TO STEP BACK"));
|
||||
Serial.println(F("HOLD TO SELECT"));
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
while (readVals_VECTREX(vectrexgame, vectrexrr, vectrexll)) {
|
||||
if (strcmp(vectrexcsvEND, vectrexgame) == 0) {
|
||||
vectrexcsvFile.seek(0); // Restart
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART TITLE:"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(vectrexgame);
|
||||
display.setCursor(0, 48);
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
#else
|
||||
Serial.print(F("CART TITLE:"));
|
||||
Serial.println(vectrexgame);
|
||||
#endif
|
||||
while (1) { // Single Step
|
||||
int b = checkButton();
|
||||
if (b == 1) { // Continue (press)
|
||||
break;
|
||||
}
|
||||
if (b == 2) { // Reset to Start of List (doubleclick)
|
||||
byte prevline = strtol(vectrexll, NULL, 10);
|
||||
vectrexcsvpos -= prevline;
|
||||
vectrexcsvFile.seek(vectrexcsvpos);
|
||||
break;
|
||||
}
|
||||
if (b == 3) { // Long Press - Select Cart (hold)
|
||||
newvectrexsize = strtol(vectrexrr, NULL, 10);
|
||||
EEPROM_writeAnything(8, newvectrexsize);
|
||||
cartselected = 1; // SELECTION MADE
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F("SELECTION MADE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("SELECTION MADE"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cartselected) {
|
||||
cartselected = 0; // Reset Flag
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("END OF FILE"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("END OF FILE"));
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkCSV_VECTREX() {
|
||||
if (getCartListInfo_VECTREX()) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CART SELECTED"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(vectrexgame);
|
||||
display_Update();
|
||||
// Display Settings
|
||||
display.setCursor(0, 56);
|
||||
print_Msg(F("CODE: R"));
|
||||
println_Msg(newvectrexsize);
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F(""));
|
||||
Serial.println(F("CART SELECTED"));
|
||||
Serial.println(vectrexgame);
|
||||
// Display Settings
|
||||
Serial.print(F("CODE: R"));
|
||||
Serial.println(newvectrexsize);
|
||||
Serial.println(F(""));
|
||||
#endif
|
||||
} else {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display.setCursor(0, 56);
|
||||
println_Msg(F("NO SELECTION"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("NO SELECTION"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void setCart_VECTREX() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(vectrexcartCSV);
|
||||
display_Update();
|
||||
#endif
|
||||
//go to root
|
||||
sd.chdir();
|
||||
sprintf(folder, "VECTREX/CSV");
|
||||
sd.chdir(folder); // Switch Folder
|
||||
vectrexcsvFile = sd.open(vectrexcartCSV, O_READ);
|
||||
if (!vectrexcsvFile) {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("CSV FILE NOT FOUND!"));
|
||||
display_Update();
|
||||
#else
|
||||
Serial.println(F("CSV FILE NOT FOUND!"));
|
||||
#endif
|
||||
while (1) {
|
||||
if (checkButton() != 0)
|
||||
setup_VECTREX();
|
||||
|
||||
byte gameSize;
|
||||
|
||||
// Select starting letter
|
||||
//byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("vectrexcart.txt", O_READ)) {
|
||||
// seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
if(checkCartSelection(myFile, &readDataLineSingleDigit, &gameSize)) {
|
||||
EEPROM_writeAnything(8, gameSize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
checkCSV_VECTREX();
|
||||
vectrexcsvFile.close();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//*********************************************************
|
||||
// BANDAI WONDERSWAN & BENESSE POCKET CHALLENGE V2 MODULE
|
||||
//*********************************************************
|
||||
#ifdef enable_WS
|
||||
#ifdef ENABLE_WS
|
||||
// Cartridge pinout
|
||||
// 48P 1.25mm pitch connector
|
||||
// C1, C48 : GND
|
||||
|
@ -23,7 +23,7 @@
|
|||
// C46 : INT (for RTC alarm interrupt)
|
||||
// C47 : CLK (384KHz on WS)
|
||||
|
||||
#ifdef ws_adapter_v2
|
||||
#ifdef OPTION_WS_ADAPTER_V2
|
||||
#define WS_CLK_BIT 5 // USE PE5 as CLK
|
||||
#else
|
||||
#define WS_CLK_BIT 3 // USE PE3 as CLK
|
||||
|
@ -32,12 +32,8 @@
|
|||
/******************************************
|
||||
Menu
|
||||
*****************************************/
|
||||
static const char wsMenuItem1[] PROGMEM = "Read Rom";
|
||||
static const char wsMenuItem2[] PROGMEM = "Read Save";
|
||||
static const char wsMenuItem3[] PROGMEM = "Write Save";
|
||||
//static const char wsMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char wsMenuItem5[] PROGMEM = "Write WitchOS";
|
||||
static const char *const menuOptionsWS[] PROGMEM = { wsMenuItem1, wsMenuItem2, wsMenuItem3, string_reset2, wsMenuItem5 };
|
||||
static const char *const menuOptionsWS[] PROGMEM = { FSTRING_READ_ROM, FSTRING_READ_SAVE, FSTRING_WRITE_SAVE, FSTRING_RESET, wsMenuItem5 };
|
||||
static const uint8_t wwLaunchCode[] PROGMEM = { 0xea, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xff, 0xff };
|
||||
static uint8_t wsGameOrientation = 0;
|
||||
static uint8_t wsGameHasRTC = 0;
|
||||
|
@ -183,7 +179,7 @@ void wsMenu() {
|
|||
}
|
||||
}
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
|
||||
|
@ -407,7 +403,7 @@ static void showCartInfo_WS() {
|
|||
print_Msg(F("Version: 1."));
|
||||
println_Msg(romVersion, HEX);
|
||||
|
||||
print_Msg(F("Checksum: "));
|
||||
print_Msg(FS(FSTRING_CHECKSUM));
|
||||
println_Msg(checksumStr);
|
||||
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
|
@ -493,20 +489,12 @@ static uint16_t readROM_WS(char *outPathBuf, size_t bufferSize) {
|
|||
if (outPathBuf != NULL && bufferSize > 0)
|
||||
snprintf(outPathBuf, bufferSize, "%s/%s", folder, fileName);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
printAndIncrementFolder(true);
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
// get correct starting rom bank
|
||||
uint16_t bank = (256 - (cartSize >> 16));
|
||||
uint32_t progress = 0;
|
||||
|
@ -565,25 +553,7 @@ static uint16_t readROM_WS(char *outPathBuf, size_t bufferSize) {
|
|||
|
||||
static void readSRAM_WS() {
|
||||
// generate fullname of rom file
|
||||
snprintf(fileName, FILENAME_LENGTH, "%s.sav", romName);
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
snprintf(folder, sizeof(folder), "WS/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Saving "));
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
createFolderAndOpenFile("WS", "SAVE", romName, "save");
|
||||
|
||||
uint32_t bank_size = (sramSize << 7);
|
||||
uint16_t end_bank = (bank_size >> 16); // 64KB per bank
|
||||
|
@ -658,7 +628,7 @@ static void verifySRAM_WS() {
|
|||
print_Error(did_not_verify_STR);
|
||||
}
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -704,31 +674,13 @@ static void writeSRAM_WS() {
|
|||
println_Msg(F("Writing finished"));
|
||||
display_Update();
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
static void readEEPROM_WS() {
|
||||
// generate fullname of eep file
|
||||
snprintf(fileName, FILENAME_LENGTH, "%s.eep", romName);
|
||||
|
||||
// create a new folder for storing eep file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
snprintf(folder, sizeof(folder), "WS/SAVE/%s/%d", romName, foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Saving "));
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
createFolderAndOpenFile("WS", "SAVE", romName, "eep");
|
||||
|
||||
uint32_t eepromSize = (sramSize << 7);
|
||||
uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512);
|
||||
|
@ -812,7 +764,7 @@ static void verifyEEPROM_WS() {
|
|||
print_Error(did_not_verify_STR);
|
||||
}
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -863,7 +815,7 @@ static void writeEEPROM_WS() {
|
|||
|
||||
print_STR(done_STR, 1);
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -952,7 +904,7 @@ static void writeWitchOS_WS() {
|
|||
|
||||
print_STR(done_STR, 1);
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"));
|
||||
print_Error(FS(FSTRING_FILE_DOESNT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1003,7 +955,7 @@ static boolean compareChecksum_WS(uint16_t checksum) {
|
|||
|
||||
return 1;
|
||||
} else {
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Error(F("Checksum Error"));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//******************************************
|
||||
// WSV MODULE
|
||||
//******************************************
|
||||
#ifdef enable_WSV
|
||||
#ifdef ENABLE_WSV
|
||||
// Watara Supervision
|
||||
// Cartridge Pinout
|
||||
// 40P 2.5mm pitch connector
|
||||
|
@ -43,7 +43,6 @@ byte wsvlo = 0; // Lowest Entry
|
|||
byte wsvhi = 2; // Highest Entry
|
||||
|
||||
byte wsvsize;
|
||||
byte newwsvsize;
|
||||
|
||||
// EEPROM MAPPING
|
||||
// 08 ROM SIZE
|
||||
|
@ -94,7 +93,7 @@ void setup_WSV() {
|
|||
checkStatus_WSV();
|
||||
strcpy(romName, "SUPERVISION");
|
||||
|
||||
mode = mode_WSV;
|
||||
mode = CORE_WSV;
|
||||
}
|
||||
|
||||
//******************************************
|
||||
|
@ -102,11 +101,7 @@ void setup_WSV() {
|
|||
//******************************************
|
||||
|
||||
// Base Menu
|
||||
static const char wsvMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char wsvMenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char wsvMenuItem3[] PROGMEM = "Set Size";
|
||||
//static const char wsvMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
|
||||
static const char* const menuOptionsSV[] PROGMEM = { wsvMenuItem1, wsvMenuItem2, wsvMenuItem3, string_reset2 };
|
||||
static const char* const menuOptionsSV[] PROGMEM = { FSTRING_SELECT_CART, FSTRING_READ_ROM, FSTRING_SET_SIZE, FSTRING_RESET };
|
||||
|
||||
void wsvMenu() {
|
||||
convertPgm(menuOptionsSV, 4);
|
||||
|
@ -190,29 +185,7 @@ uint8_t readByte_WSV(uint32_t addr) {
|
|||
//******************************************
|
||||
|
||||
void readROM_WSV() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".sv");
|
||||
|
||||
// create a new folder for storing rom file
|
||||
EEPROM_readAnything(0, foldern);
|
||||
//sprintf(folder, "WSV/ROM/%s/%d", romName, foldern);
|
||||
sprintf(folder, "WSV/ROM/%d", foldern);
|
||||
sd.mkdir(folder, true);
|
||||
sd.chdir(folder);
|
||||
|
||||
display_Clear();
|
||||
print_STR(saving_to_STR, 0);
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/..."));
|
||||
display_Update();
|
||||
|
||||
// open file on sdcard
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT))
|
||||
print_FatalError(create_file_STR);
|
||||
|
||||
// write new folder number back to EEPROM
|
||||
foldern++;
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
createFolderAndOpenFile("WSV", "ROM", romName, "sv");
|
||||
|
||||
// start reading rom
|
||||
dataIn_WSV();
|
||||
|
@ -235,7 +208,7 @@ void readROM_WSV() {
|
|||
// Arguments: database name, precalculated crc string or 0 to calculate, rename rom or not, starting offset
|
||||
compareCRC("wsv.txt", 0, 1, 0);
|
||||
|
||||
println_Msg(F(""));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
// Prints string out of the common strings array either with or without newline
|
||||
print_STR(press_button_STR, 1);
|
||||
display_Update();
|
||||
|
@ -246,78 +219,26 @@ void readROM_WSV() {
|
|||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
void printRomSize_WSV(int index) {
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_word(&(WSV[index])));
|
||||
}
|
||||
#endif
|
||||
|
||||
void setROMSize_WSV() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
byte newwsvsize;
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
if (wsvlo == wsvhi)
|
||||
newwsvsize = wsvlo;
|
||||
else {
|
||||
int b = 0;
|
||||
int i = wsvlo;
|
||||
newwsvsize = navigateMenu(wsvlo, wsvhi, &printRomSize_WSV);
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_word(&(WSV[i])));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == wsvlo)
|
||||
i = wsvhi;
|
||||
else
|
||||
i--;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_word(&(WSV[i])));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == wsvhi)
|
||||
i = wsvlo;
|
||||
else
|
||||
i++;
|
||||
|
||||
// Only update display after input because of slow LCD library
|
||||
display_Clear();
|
||||
print_Msg(F("ROM Size: "));
|
||||
println_Msg(pgm_read_word(&(WSV[i])));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newwsvsize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(pgm_read_word(&(WSV[newwsvsize])));
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -342,7 +263,7 @@ setrom:
|
|||
newwsvsize = sizeROM.toInt() + wsvlo;
|
||||
if (newwsvsize > wsvhi) {
|
||||
Serial.println(F("SIZE NOT SUPPORTED"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
goto setrom;
|
||||
}
|
||||
}
|
||||
|
@ -361,12 +282,12 @@ void checkStatus_WSV() {
|
|||
EEPROM_writeAnything(8, wsvsize);
|
||||
}
|
||||
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
#if (defined(ENABLE_OLED) || defined(ENABLE_LCD))
|
||||
display_Clear();
|
||||
println_Msg(F("WATARA SUPERVISION"));
|
||||
println_Msg(F("CURRENT SETTINGS"));
|
||||
println_Msg(F(""));
|
||||
print_Msg(F("ROM SIZE: "));
|
||||
println_Msg(FS(FSTRING_CURRENT_SETTINGS));
|
||||
println_Msg(FS(FSTRING_EMPTY));
|
||||
print_Msg(FS(FSTRING_ROM_SIZE));
|
||||
print_Msg(pgm_read_word(&(WSV[wsvsize])));
|
||||
println_Msg(F("K"));
|
||||
display_Update();
|
||||
|
@ -375,151 +296,86 @@ void checkStatus_WSV() {
|
|||
Serial.print(F("CURRENT ROM SIZE: "));
|
||||
Serial.print(pgm_read_word(&(WSV[wsvsize])));
|
||||
Serial.println(F("K"));
|
||||
Serial.println(F(""));
|
||||
Serial.println(FS(FSTRING_EMPTY));
|
||||
#endif
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// CART SELECT CODE
|
||||
//******************************************
|
||||
void setCart_WSV() {
|
||||
char gamename[100];
|
||||
char tempStr2[2];
|
||||
struct database_entry_WSV {
|
||||
char crc_search[9];
|
||||
byte gameSize;
|
||||
};
|
||||
|
||||
void readDataLine_WSV(FsFile& database, void* entry) {
|
||||
struct database_entry_WSV* castEntry = (database_entry_WSV*)entry;
|
||||
// Read CRC32 checksum
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
checksumStr[i] = char(database.read());
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
castEntry->crc_search[i] = char(database.read());
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
database.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
castEntry->gameSize = ((database.read() - 48) * 10) + (database.read() - 48);
|
||||
|
||||
// Skip rest of line
|
||||
database.seekCur(2);
|
||||
}
|
||||
|
||||
void printDataLine_WSV(void* entry) {
|
||||
struct database_entry_WSV* castEntry = (database_entry_WSV*)entry;
|
||||
print_Msg(FS(FSTRING_SIZE));
|
||||
if (castEntry->gameSize == 51)
|
||||
print_Msg(F("512"));
|
||||
else
|
||||
print_Msg(castEntry->gameSize);
|
||||
println_Msg(F("KB"));
|
||||
}
|
||||
|
||||
void setCart_WSV() {
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
||||
struct database_entry_WSV entry;
|
||||
|
||||
// Select starting letter
|
||||
byte myLetter = starting_letter();
|
||||
|
||||
// Open database
|
||||
if (myFile.open("wsv.txt", O_READ)) {
|
||||
// Skip ahead to selected starting letter
|
||||
if ((myLetter > 0) && (myLetter <= 26)) {
|
||||
while (myFile.available()) {
|
||||
// Read current name
|
||||
get_line(gamename, &myFile, 96);
|
||||
seek_first_letter_in_database(myFile, myLetter);
|
||||
|
||||
// Compare selected letter with first letter of current name until match
|
||||
while (gamename[0] != 64 + myLetter) {
|
||||
skip_line(&myFile);
|
||||
skip_line(&myFile);
|
||||
get_line(gamename, &myFile, 96);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(checkCartSelection(myFile, &readDataLine_WSV, &entry, &printDataLine_WSV)) {
|
||||
//word WSV[] = {32,64,512};
|
||||
switch (entry.gameSize) {
|
||||
case 32:
|
||||
wsvsize = 0;
|
||||
break;
|
||||
|
||||
// Rewind one line
|
||||
rewind_line(myFile);
|
||||
}
|
||||
case 64:
|
||||
wsvsize = 1;
|
||||
break;
|
||||
|
||||
// Display database
|
||||
while (myFile.available()) {
|
||||
display_Clear();
|
||||
|
||||
// Read game name
|
||||
get_line(gamename, &myFile, 96);
|
||||
|
||||
// Read CRC32 checksum
|
||||
sprintf(checksumStr, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(checksumStr, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read CRC32 of first 512 bytes
|
||||
sprintf(crc_search, "%c", myFile.read());
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
sprintf(tempStr2, "%c", myFile.read());
|
||||
strcat(crc_search, tempStr2);
|
||||
}
|
||||
|
||||
// Skip over semicolon
|
||||
myFile.seekCur(1);
|
||||
|
||||
// Read rom size
|
||||
// Read the next ascii character and subtract 48 to convert to decimal
|
||||
cartSize = myFile.read() - 48;
|
||||
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
|
||||
// Skip rest of line
|
||||
myFile.seekCur(2);
|
||||
|
||||
// Skip every 3rd line
|
||||
skip_line(&myFile);
|
||||
|
||||
println_Msg(F("Select your cartridge"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(gamename);
|
||||
print_Msg(F("Size: "));
|
||||
if (cartSize == 51)
|
||||
print_Msg(F("512"));
|
||||
else
|
||||
print_Msg(cartSize);
|
||||
println_Msg(F("KB"));
|
||||
println_Msg(F(""));
|
||||
#if defined(enable_OLED)
|
||||
print_STR(press_to_change_STR, 1);
|
||||
print_STR(right_to_select_STR, 1);
|
||||
#elif defined(enable_LCD)
|
||||
print_STR(rotate_to_change_STR, 1);
|
||||
print_STR(press_to_select_STR, 1);
|
||||
#elif defined(SERIAL_MONITOR)
|
||||
println_Msg(F("U/D to Change"));
|
||||
println_Msg(F("Space to Select"));
|
||||
#endif
|
||||
display_Update();
|
||||
|
||||
int b = 0;
|
||||
while (1) {
|
||||
// Check button input
|
||||
b = checkButton();
|
||||
|
||||
// Next
|
||||
if (b == 1) {
|
||||
case 51:
|
||||
wsvsize = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// Previous
|
||||
else if (b == 2) {
|
||||
rewind_line(myFile, 6);
|
||||
break;
|
||||
}
|
||||
|
||||
// Selection
|
||||
else if (b == 3) {
|
||||
//word WSV[] = {32,64,512};
|
||||
switch (cartSize) {
|
||||
case 32:
|
||||
wsvsize = 0;
|
||||
break;
|
||||
|
||||
case 64:
|
||||
wsvsize = 1;
|
||||
break;
|
||||
|
||||
case 51:
|
||||
wsvsize = 2;
|
||||
break;
|
||||
}
|
||||
EEPROM_writeAnything(8, wsvsize);
|
||||
myFile.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
EEPROM_writeAnything(8, wsvsize);
|
||||
}
|
||||
} else {
|
||||
print_FatalError(F("Database file not found"));
|
||||
print_FatalError(FS(FSTRING_DATABASE_FILE_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,7 @@ Happy making. 🔧🔨😊
|
|||
|
||||
#### Supported Systems:
|
||||
- NES/Famicom/Family Basic
|
||||
- Super Nintendo/Super Famicom (including SF Memory and Satellaview)
|
||||
- Super Nintendo/Super Famicom (including SF Memory, Satellaview, Sufami Turbo, and Game Processor RAM Cassettes)
|
||||
- Nintendo 64 (including Controller Pak, Gameshark, and Xplorer 64)
|
||||
- Game Boy Color (including GB Memory, Codebreaker, and Gameshark)
|
||||
- Game Boy Advance
|
||||
|
@ -37,7 +37,7 @@ Happy making. 🔧🔨😊
|
|||
- Sega Mark III
|
||||
- Sega SG-1000/SC-3000
|
||||
- Sega Cards
|
||||
- PC engine/TurboGrafx-16
|
||||
- PC Engine/TurboGrafx-16/SuperGrafx
|
||||
- WonderSwan (Color)
|
||||
- NeoGeo Pocket (Color)
|
||||
- Intellivision
|
||||
|
|
1482
sd/2600.txt
Normal file
1482
sd/2600.txt
Normal file
File diff suppressed because it is too large
Load Diff
225
sd/5200.txt
Normal file
225
sd/5200.txt
Normal file
|
@ -0,0 +1,225 @@
|
|||
Activision Decathlon
|
||||
0,2
|
||||
|
||||
Astro Chase
|
||||
1,2
|
||||
|
||||
Atari PAM - Pete's Test
|
||||
0,1
|
||||
|
||||
Atari PAM Diagnostics
|
||||
1,2
|
||||
|
||||
Atari PAM System Test
|
||||
0,1
|
||||
|
||||
Ballblazer
|
||||
0,3
|
||||
|
||||
Beamrider
|
||||
0,2
|
||||
|
||||
BerZerk
|
||||
0,2
|
||||
|
||||
Blue Print
|
||||
0,2
|
||||
|
||||
Boogie
|
||||
0,0
|
||||
|
||||
Bounty Bob Strikes Back!
|
||||
2,4
|
||||
|
||||
Buck Rogers
|
||||
1,2
|
||||
|
||||
Centipede
|
||||
1,2
|
||||
|
||||
Choplifter!
|
||||
0,2
|
||||
|
||||
Congo Bongo
|
||||
1,2
|
||||
|
||||
Countermeasure
|
||||
1,2
|
||||
|
||||
Defender
|
||||
1,2
|
||||
|
||||
Dig Dug
|
||||
1,2
|
||||
|
||||
Dreadnaught Factor
|
||||
0,1
|
||||
|
||||
Frogger
|
||||
0,1
|
||||
|
||||
Frogger II
|
||||
1,2
|
||||
|
||||
Galaxian
|
||||
0,1
|
||||
|
||||
Gorf
|
||||
0,1
|
||||
|
||||
Gremlins
|
||||
0,3
|
||||
|
||||
Gyruss
|
||||
1,2
|
||||
|
||||
H.E.R.O.
|
||||
0,2
|
||||
|
||||
James Bond 007
|
||||
1,2
|
||||
|
||||
Joust
|
||||
1,2
|
||||
|
||||
Jungle Hunt
|
||||
1,2
|
||||
|
||||
Kaboom!
|
||||
0,0
|
||||
|
||||
Kangaroo
|
||||
1,2
|
||||
|
||||
Keystone Kapers
|
||||
0,1
|
||||
|
||||
K-Razy Shoot-Out
|
||||
0,1
|
||||
|
||||
Mario Bros.
|
||||
0,3
|
||||
|
||||
MegaMania
|
||||
0,1
|
||||
|
||||
Meteorites
|
||||
0,2
|
||||
|
||||
Miner 2049er
|
||||
0,2
|
||||
|
||||
Missile Command
|
||||
0,1
|
||||
|
||||
Montezuma's Revenge
|
||||
1,2
|
||||
|
||||
Moon Patrol
|
||||
0,2
|
||||
|
||||
Mountain King
|
||||
0,1
|
||||
|
||||
Mr. Do!'s Castle
|
||||
0,1
|
||||
|
||||
Ms. Pac-Man
|
||||
1,2
|
||||
|
||||
Pac-Man
|
||||
1,2
|
||||
|
||||
Pengo
|
||||
0,3
|
||||
|
||||
Pitfall II
|
||||
0,2
|
||||
|
||||
Pitfall!
|
||||
0,1
|
||||
|
||||
Pole Position
|
||||
1,2
|
||||
|
||||
Popeye
|
||||
1,2
|
||||
|
||||
Q-bert
|
||||
0,1
|
||||
|
||||
QIX
|
||||
1,2
|
||||
|
||||
Quest for Quintana Roo
|
||||
0,2
|
||||
|
||||
RealSports Baseball
|
||||
0,3
|
||||
|
||||
RealSports Basketball
|
||||
0,3
|
||||
|
||||
RealSports Football
|
||||
1,2
|
||||
|
||||
RealSports Soccer
|
||||
1,2
|
||||
|
||||
RealSports Tennis
|
||||
1,2
|
||||
|
||||
Rescue on Fractalus!
|
||||
0,3
|
||||
|
||||
River Raid
|
||||
0,1
|
||||
|
||||
Robotron 2084
|
||||
0,2
|
||||
|
||||
Space Dungeon
|
||||
1,2
|
||||
|
||||
Space Invaders
|
||||
0,1
|
||||
|
||||
Space Shuttle
|
||||
0,2
|
||||
|
||||
Star Raiders
|
||||
1,2
|
||||
|
||||
Star Trek
|
||||
1,2
|
||||
|
||||
Star Wars - Return of the Jedi
|
||||
0,1
|
||||
|
||||
Star Wars - The Arcade Game
|
||||
1,2
|
||||
|
||||
Super Breakout
|
||||
0,0
|
||||
|
||||
Super Cobra
|
||||
0,1
|
||||
|
||||
Vanguard
|
||||
0,3
|
||||
|
||||
Wizard of Wor
|
||||
0,2
|
||||
|
||||
Yellow Submarine
|
||||
0,0
|
||||
|
||||
Zaxxon
|
||||
0,3
|
||||
|
||||
Zenji
|
||||
0,1
|
||||
|
||||
Zone Ranger
|
||||
0,2
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
Activision Decathlon,0,2,0
|
||||
Astro Chase,1,2,28
|
||||
Atari PAM - Pete's Test,0,1,20
|
||||
Atari PAM Diagnostics,1,2,32
|
||||
Atari PAM System Test,0,1,30
|
||||
Ballblazer,0,3,30
|
||||
Beamrider,0,2,19
|
||||
BerZerk,0,2,18
|
||||
Blue Print,0,2,16
|
||||
Boogie,0,0,19
|
||||
Bounty Bob Strikes Back!,2,4,15
|
||||
Buck Rogers,1,2,33
|
||||
Centipede,1,2,20
|
||||
Choplifter!,0,2,18
|
||||
Congo Bongo,1,2,20
|
||||
Countermeasure,1,2,20
|
||||
Defender,1,2,23
|
||||
Dig Dug,1,2,17
|
||||
Dreadnaught Factor,0,1,16
|
||||
Frogger,0,1,27
|
||||
Frogger II,1,2,16
|
||||
Galaxian,0,1,19
|
||||
Gorf,0,1,17
|
||||
Gremlins,0,3,13
|
||||
Gyruss,1,2,17
|
||||
H.E.R.O.,0,2,15
|
||||
James Bond 007,1,2,17
|
||||
Joust,1,2,23
|
||||
Jungle Hunt,1,2,14
|
||||
Kaboom!,0,0,20
|
||||
Kangaroo,1,2,16
|
||||
Keystone Kapers,0,1,17
|
||||
K-Razy Shoot-Out,0,1,24
|
||||
Mario Bros.,0,3,25
|
||||
MegaMania,0,1,20
|
||||
Meteorites,0,2,18
|
||||
Miner 2049er,0,2,19
|
||||
Missile Command,0,1,21
|
||||
Montezuma's Revenge,1,2,24
|
||||
Moon Patrol,0,2,28
|
||||
Mountain King,0,1,20
|
||||
Mr. Do!'s Castle,0,1,22
|
||||
Ms. Pac-Man,1,2,25
|
||||
Pac-Man,1,2,20
|
||||
Pengo,0,3,16
|
||||
Pitfall II,0,2,14
|
||||
Pitfall!,0,1,19
|
||||
Pole Position,1,2,17
|
||||
Popeye,1,2,22
|
||||
Q-bert,0,1,15
|
||||
QIX,1,2,15
|
||||
Quest for Quintana Roo,0,2,12
|
||||
RealSports Baseball,0,3,31
|
||||
RealSports Basketball,0,3,28
|
||||
RealSports Football,1,2,30
|
||||
RealSports Soccer,1,2,28
|
||||
RealSports Tennis,1,2,26
|
||||
Rescue on Fractalus!,0,3,26
|
||||
River Raid,0,1,29
|
||||
Robotron 2084,0,2,19
|
||||
Space Dungeon,1,2,22
|
||||
Space Invaders,0,1,22
|
||||
Space Shuttle,0,2,23
|
||||
Star Raiders,1,2,22
|
||||
Star Trek,1,2,21
|
||||
Star Wars - Return of the Jedi,0,1,18
|
||||
Star Wars - The Arcade Game,1,2,39
|
||||
Super Breakout,0,0,36
|
||||
Super Cobra,0,1,23
|
||||
Vanguard,0,3,20
|
||||
Wizard of Wor,0,2,17
|
||||
Yellow Submarine,0,0,22
|
||||
Zaxxon,0,3,25
|
||||
Zenji,0,1,15
|
||||
Zone Ranger,0,2,14
|
||||
EOF,0,0,0
|
213
sd/7800.txt
Normal file
213
sd/7800.txt
Normal file
|
@ -0,0 +1,213 @@
|
|||
32 in 1
|
||||
0,3
|
||||
|
||||
Ace of Aces
|
||||
1,4
|
||||
|
||||
Alien Brigade
|
||||
2,5
|
||||
|
||||
Asteroids
|
||||
0,0
|
||||
|
||||
Atari 7800 Development Card
|
||||
0,0
|
||||
|
||||
Attack of the Petscii Robots
|
||||
7,4
|
||||
|
||||
Ballblazer
|
||||
0,1
|
||||
|
||||
Barnyard Blaster
|
||||
1,4
|
||||
|
||||
Baseball
|
||||
0,1
|
||||
|
||||
Basketbrawl
|
||||
1,4
|
||||
|
||||
Centipede
|
||||
0,0
|
||||
|
||||
Choplifter! (Europe)
|
||||
0,2
|
||||
|
||||
Choplifter! (USA)
|
||||
0,1
|
||||
|
||||
Commando
|
||||
1,4
|
||||
|
||||
Crack'ed
|
||||
1,4
|
||||
|
||||
Crossbow
|
||||
2,5
|
||||
|
||||
Dark Chambers
|
||||
1,4
|
||||
|
||||
Desert Falcon
|
||||
0,2
|
||||
|
||||
Diagnostic Test Cartridge
|
||||
0,1
|
||||
|
||||
Dig Dug (Europe)
|
||||
0,1
|
||||
|
||||
Dig Dug (USA)
|
||||
0,0
|
||||
|
||||
Donkey Kong
|
||||
0,2
|
||||
|
||||
Donkey Kong Junior
|
||||
0,2
|
||||
|
||||
Double Dragon
|
||||
4,4
|
||||
|
||||
F-18 Hornet
|
||||
3,3
|
||||
|
||||
Fatal Run
|
||||
1,4
|
||||
|
||||
Fight Night
|
||||
1,4
|
||||
|
||||
Food Fight (Europe)
|
||||
0,2
|
||||
|
||||
Food Fight (USA)
|
||||
0,1
|
||||
|
||||
Galaga (Europe)
|
||||
0,2
|
||||
|
||||
Galaga (USA)
|
||||
0,1
|
||||
|
||||
Hat Trick
|
||||
0,2
|
||||
|
||||
Ikari Warriors
|
||||
1,4
|
||||
|
||||
Impossible Mission
|
||||
1,4
|
||||
|
||||
Jinks
|
||||
1,4
|
||||
|
||||
Joust (Europe)
|
||||
0,2
|
||||
|
||||
Joust (USA)
|
||||
0,1
|
||||
|
||||
Karateka (Europe)
|
||||
6,3
|
||||
|
||||
Karateka (USA)
|
||||
0,2
|
||||
|
||||
Kung-Fu Master
|
||||
0,1
|
||||
|
||||
Mario Bros.
|
||||
0,2
|
||||
|
||||
Mat Mania Challenge
|
||||
1,4
|
||||
|
||||
Mean 18 Ultimate Golf
|
||||
1,4
|
||||
|
||||
Meltdown
|
||||
1,4
|
||||
|
||||
Midnight Mutants
|
||||
1,4
|
||||
|
||||
Motor Psycho
|
||||
1,4
|
||||
|
||||
Ms. Pac-Man (Europe)
|
||||
0,1
|
||||
|
||||
Ms. Pac-Man (USA)
|
||||
0,0
|
||||
|
||||
Ninja Golf
|
||||
1,4
|
||||
|
||||
One-on-One Basketball
|
||||
0,2
|
||||
|
||||
Pete Rose Baseball
|
||||
0,1
|
||||
|
||||
Planet Smashers
|
||||
1,4
|
||||
|
||||
Pole Position II
|
||||
0,1
|
||||
|
||||
Rampage
|
||||
4,4
|
||||
|
||||
RealSports Baseball
|
||||
5,3
|
||||
|
||||
Robotron 2084
|
||||
0,1
|
||||
|
||||
Scrapyard Dog
|
||||
1,4
|
||||
|
||||
Sentinel
|
||||
1,4
|
||||
|
||||
Summer Games
|
||||
1,4
|
||||
|
||||
Super Huey UH-IX
|
||||
0,2
|
||||
|
||||
Super Skateboardin'
|
||||
0,1
|
||||
|
||||
Tank Command
|
||||
5,3
|
||||
|
||||
Title Match Pro Wrestling
|
||||
0,1
|
||||
|
||||
Tomcat
|
||||
0,1
|
||||
|
||||
Touchdown Football
|
||||
1,4
|
||||
|
||||
Tower Toppler
|
||||
5,3
|
||||
|
||||
Water Ski
|
||||
5,3
|
||||
|
||||
Winter Games
|
||||
1,4
|
||||
|
||||
Xenophobe
|
||||
1,4
|
||||
|
||||
Xevious (Europe)
|
||||
0,2
|
||||
|
||||
Xevious (USA)
|
||||
0,1
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
32 in 1,0,3,0
|
||||
Ace of Aces,1,4,15
|
||||
Alien Brigade,2,5,20
|
||||
Asteroids,0,0,22
|
||||
Atari 7800 Development Card,0,0,18
|
||||
Ballblazer,0,1,36
|
||||
Barnyard Blaster,1,4,19
|
||||
Baseball,0,1,25
|
||||
Basketbrawl,1,4,17
|
||||
Centipede,0,0,20
|
||||
Choplifter! (Europe),0,2,18
|
||||
Choplifter! (USA),0,1,29
|
||||
Commando,1,4,26
|
||||
Crack'ed,1,4,17
|
||||
Crossbow,2,5,17
|
||||
Dark Chambers,1,4,17
|
||||
Desert Falcon,0,2,22
|
||||
Diagnostic Test Cartridge,0,1,22
|
||||
Dig Dug (Europe),0,1,34
|
||||
Dig Dug (USA),0,0,25
|
||||
Donkey Kong,0,2,22
|
||||
Donkey Kong Junior,0,2,20
|
||||
Double Dragon,4,4,27
|
||||
F-18 Hornet,3,3,22
|
||||
Fatal Run,1,4,20
|
||||
Fight Night,1,4,18
|
||||
Food Fight (Europe),0,2,20
|
||||
Food Fight (USA),0,1,28
|
||||
Galaga (Europe),0,2,25
|
||||
Galaga (USA),0,1,24
|
||||
Hat Trick,0,2,21
|
||||
Ikari Warriors,1,4,18
|
||||
Impossible Mission,1,4,23
|
||||
Jinks,1,4,27
|
||||
Joust (Europe),0,2,14
|
||||
Joust (USA),0,1,23
|
||||
Karateka (Europe),6,3,20
|
||||
Karateka (USA),0,2,26
|
||||
Kung-Fu Master,0,1,23
|
||||
Mario Bros.,0,2,23
|
||||
Mat Mania Challenge,1,4,20
|
||||
Mean 18 Ultimate Golf,1,4,28
|
||||
Meltdown,1,4,30
|
||||
Midnight Mutants,1,4,17
|
||||
Motor Psycho,1,4,25
|
||||
Ms. Pac-Man (Europe),0,1,21
|
||||
Ms. Pac-Man (USA),0,0,29
|
||||
Ninja Golf,1,4,26
|
||||
One-on-One Basketball,0,2,19
|
||||
Pete Rose Baseball,0,1,30
|
||||
Planet Smashers,1,4,27
|
||||
Pole Position II,0,1,24
|
||||
Rampage,4,4,25
|
||||
RealSports Baseball,5,3,16
|
||||
Robotron 2084,0,1,28
|
||||
Scrapyard Dog,1,4,22
|
||||
Sentinel,1,4,22
|
||||
Summer Games,1,4,17
|
||||
Super Huey UH-IX,0,2,21
|
||||
Super Skateboardin',0,1,25
|
||||
Tank Command,5,3,28
|
||||
Title Match Pro Wrestling,0,1,21
|
||||
Tomcat,0,1,34
|
||||
Touchdown Football,1,4,15
|
||||
Tower Toppler,5,3,27
|
||||
Water Ski,5,3,22
|
||||
Winter Games,1,4,18
|
||||
Xenophobe,1,4,21
|
||||
Xevious (Europe),0,2,18
|
||||
Xevious (USA),0,1,25
|
||||
EOF,0,0,0
|
241
sd/README.md
241
sd/README.md
|
@ -98,3 +98,244 @@ D90FE762
|
|||
|
||||
Name
|
||||
Checksum
|
||||
|
||||
## 2600.txt
|
||||
This file stores known Atari VCS / 2600 games with the required mapping value.
|
||||
|
||||
Example:
|
||||
Wall-Defender
|
||||
064
|
||||
|
||||
Name
|
||||
mapper
|
||||
|
||||
mapper:
|
||||
004 = Atari 32K with RAM [F4SC]
|
||||
006 = Atari 16K with RAM [F6SC]
|
||||
008 = Atari 8K with RAM [F8SC]
|
||||
010 = UA Ltd 8K [UA]
|
||||
032 = Atari 2K
|
||||
063 = Tigervision 8K
|
||||
064 = Atari 4K (Default)
|
||||
192 = Commavid 2K [CV]
|
||||
208 = Pitfall II 10K [DPC]
|
||||
224 = Parker Bros 8K
|
||||
231 = M-Network 16K
|
||||
240 = Megaboy 64K
|
||||
244 = Atari 32K [F4]
|
||||
246 = Atari 16K [F6]
|
||||
248 = Atari 8K [F8]
|
||||
249 = Time Pilot 8K [TP]
|
||||
250 = CBS RAM Plus 12K
|
||||
254 = Activision 8K
|
||||
|
||||
## 5200.txt
|
||||
This file stores known Atari 5200 games with the required mapping value and cart size.
|
||||
|
||||
Example:
|
||||
Defender
|
||||
1,2
|
||||
|
||||
Name
|
||||
mapper, cart size
|
||||
|
||||
mapper:
|
||||
0 = Standard 4K/8K/16K/32K
|
||||
1 = Two Chip 16K
|
||||
2 = Bounty Bob Strikes Back 40K
|
||||
|
||||
cart size:
|
||||
0 = 4K
|
||||
1 = 8K
|
||||
2 = 16K
|
||||
3 = 32K
|
||||
4 = 40K
|
||||
|
||||
## 7800.txt
|
||||
This file stores known Atari 7800 games with the required mapping value and cart size.
|
||||
|
||||
Example:
|
||||
Rampage
|
||||
4,4
|
||||
|
||||
Name
|
||||
mapper, cart size
|
||||
|
||||
mapper:
|
||||
0 = Standard 16K/32K/48K [7816/7832/7848]
|
||||
1 = SuperGame 128K [78SG]
|
||||
2 = SuperGame - Alien Brigade/Crossbow 144K [78S9]
|
||||
3 = F-18 Hornet 64K [78AB]
|
||||
4 = Double Dragon/Rampage 128K [78AC]
|
||||
5 = Realsports Baseball/Tank Command/Tower Toppler/Waterski 64K [78S4]
|
||||
6 = Karateka (PAL) 64K [78S4 Variant]
|
||||
7 = Bankset switching
|
||||
|
||||
cart size:
|
||||
0 = 16K
|
||||
1 = 32K
|
||||
2 = 48K
|
||||
3 = 64K
|
||||
4 = 128K
|
||||
5 = 144K
|
||||
|
||||
## arccart.txt
|
||||
This file stores known Emerson Arcadia 2001 games with the required cart size.
|
||||
|
||||
Example:
|
||||
American Football
|
||||
2
|
||||
|
||||
Name
|
||||
cart size
|
||||
|
||||
cart size:
|
||||
0 = 2K
|
||||
1 = 4K
|
||||
2 = 6K
|
||||
3 = 8K
|
||||
|
||||
## c64cart.txt
|
||||
This file stores known Commodore 64 games with the required mapping value and cart size.
|
||||
|
||||
Example:
|
||||
Donkey Kong
|
||||
00,3
|
||||
|
||||
Name
|
||||
mapper, cart size
|
||||
|
||||
mapper:
|
||||
00 = Normal 4K/8K/16K + Ultimax 8K/16K
|
||||
01 = Action Replay 32K
|
||||
02 = KCS Power Cartridge 16K
|
||||
03 = Final Cartridge III 64K
|
||||
04 = Simons Basic 16K
|
||||
05 = Ocean 128K/256K/512K
|
||||
06 = Expert Cartridge 8K
|
||||
07 = Fun Play, Power Play 128K
|
||||
08 = Super Games 64K
|
||||
09 = Atomic Power 32K
|
||||
10 = Epyx Fastload 8K
|
||||
11 = Westermann Learning 16K
|
||||
12 = Rex Utility 8K
|
||||
13 = Final Cartridge I 16K
|
||||
14 = Magic Formel 64K
|
||||
15 = C64 Game System, System 3 512K
|
||||
16 = WarpSpeed 16K
|
||||
17 = Dinamic 128K
|
||||
18 = Zaxxon, Super Zaxxon (SEGA) 20K
|
||||
19 = Magic Desk, Domark, HES Australia 32K/64K/128K
|
||||
20 = Super Snapshot 5 64K
|
||||
21 = Comal-80 64K
|
||||
|
||||
cart size:
|
||||
0 = 4K
|
||||
1 = 8K
|
||||
2 = 12K
|
||||
3 = 16K
|
||||
4 = 20K
|
||||
5 = 32K
|
||||
6 = 64K
|
||||
7 = 128K
|
||||
8 = 256K
|
||||
9 = 512K
|
||||
|
||||
## fairchildcart.txt
|
||||
This file stores known Fairchild Channel F games with the required cart size.
|
||||
|
||||
Example:
|
||||
Hangman
|
||||
1
|
||||
|
||||
Name
|
||||
cart size
|
||||
|
||||
cart size:
|
||||
0 = 2K
|
||||
1 = 3K
|
||||
2 = 4K
|
||||
3 = 6K
|
||||
|
||||
## msxcart.txt
|
||||
This file stores known MSX games with the required mapper, cart size and ram size.
|
||||
|
||||
Example:
|
||||
Aoki Ookami - Genchou Hishi
|
||||
07,8,4
|
||||
|
||||
Name
|
||||
mapper, cart size, ram size
|
||||
|
||||
mapper:
|
||||
00 = NONE
|
||||
01 = ASCII8
|
||||
02 = ASCII16
|
||||
03 = CROSS BLAIM
|
||||
04 = GAME MASTER 2
|
||||
05 = HAL NOTE
|
||||
06 = HARRY FOX YUKI
|
||||
07 = KOEI
|
||||
08 = KONAMI
|
||||
09 = KONAMI SSC
|
||||
10 = MSX-DOS2
|
||||
11 = PAC/FM-PAC
|
||||
12 = R-TYPE
|
||||
13 = SUPER LODE RUNNER
|
||||
|
||||
cart size:
|
||||
0 = 0K
|
||||
1 = 8K
|
||||
2 = 16K
|
||||
3 = 32K
|
||||
4 = 64K
|
||||
5 = 128K
|
||||
6 = 256K
|
||||
7 = 512K
|
||||
8 = 1024K
|
||||
|
||||
ram size:
|
||||
0 = 0K
|
||||
1 = 2K
|
||||
2 = 8K
|
||||
3 = 16K
|
||||
4 = 32K
|
||||
|
||||
## ody2cart.txt
|
||||
This file stores known Magnavox Odyssey 2 games with the required mapper and cart size.
|
||||
|
||||
Example:
|
||||
Baseball
|
||||
0,0
|
||||
|
||||
Name
|
||||
mapper, cart size
|
||||
|
||||
mapper:
|
||||
0 = STANDARD
|
||||
1 = A10
|
||||
|
||||
cart size:
|
||||
0 = 2K
|
||||
1 = 4K
|
||||
2 = 8K
|
||||
3 = 12K
|
||||
4 = 16K
|
||||
|
||||
## vectrexcart.txt
|
||||
This file stores known Vectrex games with the required cart size.
|
||||
|
||||
Example:
|
||||
Mine Storm II
|
||||
0
|
||||
|
||||
Name
|
||||
cart size
|
||||
|
||||
cart size:
|
||||
0 = 4K
|
||||
1 = 8K
|
||||
2 = 12K
|
||||
3 = 16K
|
||||
4 = 32K
|
||||
5 = 64K
|
||||
|
|
193
sd/arccart.txt
193
sd/arccart.txt
|
@ -1,49 +1,144 @@
|
|||
3D Bowling,1,0
|
||||
3D Soccer,3,16
|
||||
Alien Invaders,1,16
|
||||
American Football,2,21
|
||||
Astro Invader,3,24
|
||||
Autorace,3,20
|
||||
Baseball,1,15
|
||||
Basketball,1,15
|
||||
Blackjack and Poker,1,17
|
||||
Boxing,1,26
|
||||
Brain Quiz,1,13
|
||||
Breakaway,1,17
|
||||
Capture,0,16
|
||||
Cat Trax,1,14
|
||||
Circus,1,15
|
||||
Combat,3,13
|
||||
Crazy Climber,1,13
|
||||
Crazy Gobbler,0,20
|
||||
Escape,1,20
|
||||
Funky Fish,3,13
|
||||
Golf,3,17
|
||||
Grand Slam Tennis,3,11
|
||||
Hobo,3,24
|
||||
Horse Racing,1,11
|
||||
Jump Bug,3,19
|
||||
Jungler,3,15
|
||||
Missile War,1,14
|
||||
Monaco Grand Prix,1,18
|
||||
Nibblemen,1,24
|
||||
Ocean Battle,1,16
|
||||
Parashooter,1,19
|
||||
Pleiades,3,18
|
||||
R2D Tank,1,15
|
||||
Red Clash,3,15
|
||||
Robot Killer,1,16
|
||||
Route 16,3,19
|
||||
Soccer,3,15
|
||||
Space Attack,1,13
|
||||
Space Mission,1,19
|
||||
Space Raiders,1,20
|
||||
Space Squadron,1,20
|
||||
Space Vultures,2,21
|
||||
Spiders,3,21
|
||||
Star Chess,1,14
|
||||
Super Gobbler,1,17
|
||||
Tanks a Lot,1,20
|
||||
The End,1,18
|
||||
Turtles,3,14
|
||||
EOF,0,0
|
||||
3D Bowling
|
||||
1
|
||||
|
||||
3D Soccer
|
||||
3
|
||||
|
||||
Alien Invaders
|
||||
1
|
||||
|
||||
American Football
|
||||
2
|
||||
|
||||
Astro Invader
|
||||
3
|
||||
|
||||
Autorace
|
||||
3
|
||||
|
||||
Baseball
|
||||
1
|
||||
|
||||
Basketball
|
||||
1
|
||||
|
||||
Blackjack and Poker
|
||||
1
|
||||
|
||||
Boxing
|
||||
1
|
||||
|
||||
Brain Quiz
|
||||
1
|
||||
|
||||
Breakaway
|
||||
1
|
||||
|
||||
Capture
|
||||
0
|
||||
|
||||
Cat Trax
|
||||
1
|
||||
|
||||
Circus
|
||||
1
|
||||
|
||||
Combat
|
||||
3
|
||||
|
||||
Crazy Climber
|
||||
1
|
||||
|
||||
Crazy Gobbler
|
||||
0
|
||||
|
||||
Escape
|
||||
1
|
||||
|
||||
Funky Fish
|
||||
3
|
||||
|
||||
Golf
|
||||
3
|
||||
|
||||
Grand Slam Tennis
|
||||
3
|
||||
|
||||
Hobo
|
||||
3
|
||||
|
||||
Horse Racing
|
||||
1
|
||||
|
||||
Jump Bug
|
||||
3
|
||||
|
||||
Jungler
|
||||
3
|
||||
|
||||
Missile War
|
||||
1
|
||||
|
||||
Monaco Grand Prix
|
||||
1
|
||||
|
||||
Nibblemen
|
||||
1
|
||||
|
||||
Ocean Battle
|
||||
1
|
||||
|
||||
Parashooter
|
||||
1
|
||||
|
||||
Pleiades
|
||||
3
|
||||
|
||||
R2D Tank
|
||||
1
|
||||
|
||||
Red Clash
|
||||
3
|
||||
|
||||
Robot Killer
|
||||
1
|
||||
|
||||
Route 16
|
||||
3
|
||||
|
||||
Soccer
|
||||
3
|
||||
|
||||
Space Attack
|
||||
1
|
||||
|
||||
Space Mission
|
||||
1
|
||||
|
||||
Space Raiders
|
||||
1
|
||||
|
||||
Space Squadron
|
||||
1
|
||||
|
||||
Space Vultures
|
||||
2
|
||||
|
||||
Spiders
|
||||
3
|
||||
|
||||
Star Chess
|
||||
1
|
||||
|
||||
Super Gobbler
|
||||
1
|
||||
|
||||
Tanks a Lot
|
||||
1
|
||||
|
||||
The End
|
||||
1
|
||||
|
||||
Turtles
|
||||
3
|
||||
|
||||
|
|
494
sd/ataricart.txt
494
sd/ataricart.txt
|
@ -1,494 +0,0 @@
|
|||
32 in 1,240,0
|
||||
3-D Tic-Tac-Toe,32,15
|
||||
Acid Drop,246,23
|
||||
Action Force,64,18
|
||||
Adventure,64,20
|
||||
Adventures of TRON,64,17
|
||||
Air Raid,64,26
|
||||
Air Raiders,64,16
|
||||
Airlock,64,19
|
||||
Air-Sea Battle,32,15
|
||||
AKA Space Adventure,64,22
|
||||
Alien,64,27
|
||||
Alpha Beam with Ernie,248,13
|
||||
Amidar,64,30
|
||||
Armor Ambush,64,14
|
||||
Artillery Duel,248,20
|
||||
Assault,64,23
|
||||
Asterix,248,15
|
||||
Asteroids,248,16
|
||||
Astroblast,64,18
|
||||
Atari Video Cube,64,18
|
||||
Atlantis,64,24
|
||||
Atlantis II,64,16
|
||||
Bachelor Party,64,19
|
||||
Bachelorette Party,64,22
|
||||
Backgammon,64,26
|
||||
Bank Heist,64,18
|
||||
Barnstorming,64,18
|
||||
Base Attack,64,20
|
||||
Basic Math,32,19
|
||||
BASIC Programming,64,18
|
||||
Basketball,32,25
|
||||
Battlezone,248,18
|
||||
Beamrider,248,19
|
||||
Beany Bopper,64,18
|
||||
Beat 'Em & Eat 'Em,64,20
|
||||
Berenstain Bears,248,26
|
||||
Bermuda,64,25
|
||||
Bermuda Triangle,64,15
|
||||
Berzerk,64,24
|
||||
Big Bird's Egg Catch,248,15
|
||||
Blackjack,32,29
|
||||
Blueprint,248,17
|
||||
BMX Air Master,246,18
|
||||
Bobby Is Going Home,64,23
|
||||
Boing!,64,27
|
||||
Bowling,32,14
|
||||
Boxing,32,15
|
||||
Brain Games,32,14
|
||||
Breakout,32,19
|
||||
Bridge,64,16
|
||||
Buck Rogers - Planet of Zoom,248,14
|
||||
Bugs,64,37
|
||||
Bump 'n' Jump,231,12
|
||||
Bumper Bash,64,22
|
||||
BurgerTime,231,19
|
||||
Burning Desire,64,19
|
||||
Cakewalk,64,22
|
||||
California Games,246,16
|
||||
Canyon Bomber,32,25
|
||||
Carnival,64,21
|
||||
Casino,64,16
|
||||
Cat Trax,64,14
|
||||
Cathouse Blues,64,16
|
||||
Centipede,248,22
|
||||
Challenge,248,18
|
||||
Challenge of.... Nexar,64,18
|
||||
Chase the Chuckwagon,64,30
|
||||
Checkers,32,28
|
||||
China Syndrome,64,16
|
||||
Chopper Command,64,22
|
||||
Chuck Norris Superkicks,248,23
|
||||
Circus Atari,64,32
|
||||
Coco Nuts,64,20
|
||||
Codebreaker,32,17
|
||||
Combat,32,19
|
||||
Commando,246,14
|
||||
Commando Raid,64,17
|
||||
Condor Attack,64,21
|
||||
Confrontation,64,21
|
||||
Congo Bongo,248,21
|
||||
Cookie Monster Munch,248,20
|
||||
Cosmic Ark,64,29
|
||||
Cosmic Commuter,64,18
|
||||
Cosmic Corridor,64,23
|
||||
Cosmic Creeps,64,23
|
||||
Cosmic Swarm,32,21
|
||||
Crackpots,64,20
|
||||
Crash Dive,64,17
|
||||
Crazy Climber,248,18
|
||||
Cross Force,64,22
|
||||
Crossbow,246,19
|
||||
Crypts of Chaos,64,17
|
||||
Crystal Castles,246,23
|
||||
Cubicolor,64,24
|
||||
Cubo Magico,64,17
|
||||
Custer's Revenge,64,19
|
||||
Dancing Plate,64,24
|
||||
Dark Cavern,64,21
|
||||
Dark Chambers,246,19
|
||||
Dark Mage,248,22
|
||||
Deadly Duck,64,18
|
||||
Death Trap,64,19
|
||||
Decathlon,254,18
|
||||
Defender,64,18
|
||||
Defender II,248,16
|
||||
Demolition Herby,64,20
|
||||
Demon Attack,64,24
|
||||
Demons to Diamonds,64,20
|
||||
Desert Falcon,246,26
|
||||
Dice Puzzle,64,22
|
||||
Dig Dug,246,19
|
||||
Dishaster,64,16
|
||||
Dodge 'Em,64,17
|
||||
Dolphin,64,17
|
||||
Donald Duck's Speedboat,248,15
|
||||
Donkey Kong,64,32
|
||||
Donkey Kong Jr,248,19
|
||||
Double Dragon,246,23
|
||||
Double Dunk,246,22
|
||||
Dragon Defender,64,20
|
||||
Dragonfire,64,23
|
||||
Dragster,32,18
|
||||
Dukes of Hazzard,246,16
|
||||
E.T.,248,25
|
||||
Earth Dies Screaming,64,13
|
||||
Eggomania,64,28
|
||||
Elevator Action,248,17
|
||||
Eli's Ladder,64,24
|
||||
Encounter at L-5,64,20
|
||||
Enduro,64,24
|
||||
Entombed,64,14
|
||||
Espial,63,16
|
||||
Exocet,64,14
|
||||
Extra Terrestrials,64,14
|
||||
Fantastic Voyage,64,26
|
||||
Farmyard Fun,64,24
|
||||
Fast Eddie,64,20
|
||||
Fast Food,64,18
|
||||
Fatal Run,244,17
|
||||
Fathom,248,18
|
||||
Fighter Pilot,246,15
|
||||
Final Approach,64,22
|
||||
Fire Fighter,64,22
|
||||
Fire Fly,64,20
|
||||
Fishing Derby,32,16
|
||||
Flag Capture,32,21
|
||||
Flash Gordon,64,20
|
||||
Football,32,20
|
||||
Forest,64,16
|
||||
Frankenstein's Monster,64,14
|
||||
Freeway,32,30
|
||||
Frisco,64,15
|
||||
Frog Pond,248,14
|
||||
Frogger,64,18
|
||||
Frogger II,224,15
|
||||
Frogs and Flies,64,19
|
||||
Front Line,248,23
|
||||
Frostbite,64,19
|
||||
G.I. Joe,64,17
|
||||
Galaxian,248,16
|
||||
Gamma Attack,32,17
|
||||
Gangster Alley,64,20
|
||||
Gas Hog,64,22
|
||||
Gauntlet,64,15
|
||||
Ghost Manor,248,16
|
||||
Ghostbusters,248,20
|
||||
Ghostbusters II,246,21
|
||||
Gigolo,64,24
|
||||
Glacier Patrol,64,14
|
||||
Glib,64,22
|
||||
Golf,32,12
|
||||
Gopher,64,12
|
||||
Gorf,64,14
|
||||
Grand Prix,246,12
|
||||
Gravitar,248,19
|
||||
Great Escape,64,17
|
||||
Gremlins,248,20
|
||||
Guardian,64,17
|
||||
Gyruss,224,16
|
||||
H.E.R.O.,248,15
|
||||
Halloween,64,17
|
||||
Hangman,64,17
|
||||
Harbor Escape,64,15
|
||||
Haunted House,64,21
|
||||
Hole Hunter,64,21
|
||||
Home Run,32,19
|
||||
Human Cannonball,32,16
|
||||
Hunt & Score,32,24
|
||||
I Want My Mommy,64,20
|
||||
Ice Hockey,64,23
|
||||
Ikari Warriors,246,18
|
||||
Indy 500,32,23
|
||||
Infiltrate,64,16
|
||||
International Soccer,64,18
|
||||
IQ 180,64,28
|
||||
James Bond 007,224,14
|
||||
Jaw Breaker,64,23
|
||||
Journey Escape,64,19
|
||||
Joust,248,22
|
||||
JoustPong,64,14
|
||||
Jr. Pac-Man,246,17
|
||||
Jungle Fever,64,20
|
||||
Jungle Hunt,248,20
|
||||
Kaboom!,32,20
|
||||
Kangaroo,248,15
|
||||
Karate,64,17
|
||||
Keystone Kapers,64,14
|
||||
King Kong,64,23
|
||||
Klax,246,17
|
||||
Knight on the Town,64,13
|
||||
Kool-Aid Man,64,26
|
||||
Krull,248,20
|
||||
Kung Fu Superkicks,248,14
|
||||
Kung-Fu Master,248,27
|
||||
Lady in Wading,64,23
|
||||
Laser Blast,32,22
|
||||
Laser Gates,64,19
|
||||
Lilly Advenure,64,19
|
||||
Lochjaw,64,22
|
||||
Lock 'n' Chase,64,15
|
||||
London Blitz,64,22
|
||||
Lost Luggage,64,20
|
||||
M.A.D.,64,20
|
||||
M.A.S.H,64,14
|
||||
MagiCard,192,15
|
||||
Malagai,64,17
|
||||
Mangia',64,15
|
||||
Marauder,64,15
|
||||
Marine Wars,64,16
|
||||
Mario Bros.,248,19
|
||||
Master Builder,64,20
|
||||
Masters of the Universe,231,22
|
||||
Math Gran Prix,64,32
|
||||
Maze Craze,64,22
|
||||
Mega Force,64,18
|
||||
MegaBoy,240,18
|
||||
MegaMania,64,16
|
||||
Midnight Magic,246,17
|
||||
Millipede,246,23
|
||||
Mind Maze,248,18
|
||||
Miner 2049er,63,18
|
||||
Miner 2049er Volume II,63,20
|
||||
Mines of Minos,64,30
|
||||
Miniature Golf,32,22
|
||||
Miss Piggy's Wedding,248,22
|
||||
Missile Command,64,29
|
||||
Missile Control,64,23
|
||||
Mission 3000 A.D.,64,23
|
||||
Mission Survive,64,25
|
||||
Mogul Maniac,64,23
|
||||
Montezuma's Revenge,224,20
|
||||
Moon Patrol,248,28
|
||||
Moonsweeper,248,20
|
||||
Motocross,64,20
|
||||
Motocross Racer,248,17
|
||||
MotoRodeo,246,24
|
||||
Mountain King,250,18
|
||||
Mouse Trap,64,22
|
||||
Mr. Do!,248,18
|
||||
Mr. Do!'s Castle,224,16
|
||||
Mr. Postman,64,25
|
||||
Ms. Pac-Man,248,19
|
||||
Music Machine,64,20
|
||||
My Golf,248,21
|
||||
Name This Game,64,16
|
||||
Night Driver,32,22
|
||||
Night Stalker,64,20
|
||||
Nightmare,64,21
|
||||
No Escape!,64,17
|
||||
Nuts,64,18
|
||||
Obelix,248,12
|
||||
Off the Wall,246,15
|
||||
Oink!,64,21
|
||||
Omega Race,250,13
|
||||
Open Sesame,64,19
|
||||
Oscar's Trash Race,248,19
|
||||
Othello,32,27
|
||||
Out of Control,64,15
|
||||
Outlaw,32,22
|
||||
Pac-Kong,64,14
|
||||
Pac-Man,64,16
|
||||
Panda Chase,64,15
|
||||
Parachute,64,19
|
||||
Pele's Soccer,64,17
|
||||
Pengo,248,21
|
||||
Pepsi Invaders,64,14
|
||||
Pete Rose Baseball,246,22
|
||||
Phantom Tank,64,27
|
||||
Pharaoh's Curse,64,20
|
||||
Philly Flasher,64,23
|
||||
Phoenix,248,22
|
||||
Pick 'n' Pile,246,16
|
||||
Picnic,64,22
|
||||
Piece o' Cake,64,14
|
||||
Pigs in Space,248,21
|
||||
Pitfall II,208,22
|
||||
Pitfall!,64,19
|
||||
Planet Patrol,64,16
|
||||
Plaque Attack,64,21
|
||||
Polaris,63,21
|
||||
Pole Position,248,15
|
||||
Polo,32,22
|
||||
Pompeii,64,12
|
||||
Pooyan,64,15
|
||||
Popeye,224,14
|
||||
Porky's,248,15
|
||||
Pressure Cooker,248,16
|
||||
Private Eye,248,24
|
||||
Pyramid War,64,20
|
||||
Q-bert,64,19
|
||||
Q-bert's Qubes,224,14
|
||||
Quadrun,248,23
|
||||
Quest for Quintana Roo,248,16
|
||||
Quick Step!,64,31
|
||||
Rabbit Transit,248,19
|
||||
Racing Car,64,23
|
||||
Racquetball,64,18
|
||||
Radar Lock,246,19
|
||||
Raft Rider,64,19
|
||||
Raiders of the Lost Ark,248,18
|
||||
Ram It,64,32
|
||||
Rampage!,246,14
|
||||
Raumpatrouille,64,17
|
||||
Reactor,64,22
|
||||
RealSports Baseball,248,15
|
||||
RealSports Boxing,246,28
|
||||
RealSports Football,248,26
|
||||
RealSports Soccer,248,28
|
||||
RealSports Tennis,248,26
|
||||
RealSports Volleyball,64,26
|
||||
Rescue Terra I,64,29
|
||||
Resgate Espacial,248,22
|
||||
Revenge of the Beefsteak Tomatoes,64,25
|
||||
Riddle of the Sphinx,64,41
|
||||
River Patrol,63,28
|
||||
River Raid,64,20
|
||||
River Raid II,246,18
|
||||
Road Runner,246,22
|
||||
Robin Hood,248,20
|
||||
Robot Tank,254,19
|
||||
Roc 'n Rope,248,19
|
||||
Room of Doom,64,20
|
||||
Rubik's Cube,64,20
|
||||
Save Our Ship,64,20
|
||||
Scuba Diver,64,21
|
||||
Sea Hawk,64,19
|
||||
Sea Hunt,64,16
|
||||
Sea Monster,64,16
|
||||
Seaquest,64,19
|
||||
Secret Quest,246,16
|
||||
Sentinel,246,21
|
||||
Shark Attack,64,17
|
||||
Shootin' Gallery,64,20
|
||||
Shuttle Orbiter,64,24
|
||||
Sir Lancelot,248,23
|
||||
Skate Boardin',248,21
|
||||
Skeet Shoot,32,23
|
||||
Ski Hunt,64,19
|
||||
Ski Run,64,16
|
||||
Skiing,32,15
|
||||
Sky Diver,32,14
|
||||
Sky Jinks,32,17
|
||||
Sky Skipper,64,17
|
||||
Slot Machine,32,19
|
||||
Slot Racers,32,20
|
||||
Smurf Rescue in Gargamels Castle,248,19
|
||||
Smurfs Save the Day,248,41
|
||||
Sneak 'n Peek,64,28
|
||||
Snoopy and the Red Baron,248,21
|
||||
Solar Fox,248,33
|
||||
Solar Storm,64,18
|
||||
Solaris,246,19
|
||||
Sorcerer,64,16
|
||||
Sorcerer's Apprentice,248,16
|
||||
Space Attack,64,30
|
||||
Space Canyon,64,20
|
||||
Space Cavern,64,20
|
||||
Space Invaders,64,20
|
||||
Space Jockey,32,22
|
||||
Space Shuttle,248,20
|
||||
Space Tunnel,64,22
|
||||
Space War,32,20
|
||||
Spacechase,64,17
|
||||
SpaceMaster X-7,64,18
|
||||
Spider Fighter,64,23
|
||||
Spider Maze,64,22
|
||||
Spider-Man,64,19
|
||||
Spike's Peak,248,18
|
||||
Spitfire Attack,64,21
|
||||
Springer,63,23
|
||||
Sprint Master,246,16
|
||||
Spy Hunter,248,22
|
||||
Squeeze Box,64,19
|
||||
Squirrel,64,19
|
||||
Sssnake,64,16
|
||||
Stampede,32,15
|
||||
Star Fox,64,16
|
||||
Star Raiders,248,16
|
||||
Star Ship,32,21
|
||||
Star Strike,64,17
|
||||
Star Trek,248,19
|
||||
Star Voyager,64,18
|
||||
Star Wars - Arcade Game,224,20
|
||||
Star Wars - Death Star Battle,224,32
|
||||
Star Wars - Empire Strikes Back,64,38
|
||||
Star Wars - Jedi Arena,64,39
|
||||
Stargate,246,30
|
||||
Stargunner,64,17
|
||||
StarMaster,64,18
|
||||
Steeplechase,32,18
|
||||
Stellar Track,64,20
|
||||
Strategy X,64,21
|
||||
Strawberry Shortcake,64,18
|
||||
Street Racer,32,28
|
||||
Stronghold,64,20
|
||||
Stunt Man,64,18
|
||||
Submarine Commander,64,17
|
||||
Sub-Scan,64,27
|
||||
Subterranea,248,16
|
||||
Summer Games,246,20
|
||||
Super Baseball,246,21
|
||||
Super Breakout,64,23
|
||||
Super Challenge Baseball,64,22
|
||||
Super Challenge Football,64,32
|
||||
Super Cobra,224,32
|
||||
Super Football,248,20
|
||||
Superman,64,23
|
||||
Surfer's Paradise,64,16
|
||||
Surround,32,25
|
||||
Survival Run,64,16
|
||||
SwordQuest - EarthWorld,248,20
|
||||
SwordQuest - FireWorld,248,32
|
||||
SwordQuest - WaterWorld,248,31
|
||||
Tac-Scan,64,32
|
||||
Tanks But No Tanks,64,16
|
||||
Tapeworm,64,26
|
||||
Tapper,248,16
|
||||
Tax Avoiders,248,15
|
||||
Taz,248,21
|
||||
Tempest,248,12
|
||||
Tennis,32,16
|
||||
Texas Chainsaw Massacre,64,14
|
||||
Threshold,64,31
|
||||
Thunderground,64,17
|
||||
Time Pilot,249,21
|
||||
Time Warp,64,19
|
||||
Title Match Pro Wrestling,248,17
|
||||
Tomarc the Barbarian,248,34
|
||||
Tomcat,246,29
|
||||
Tooth Protectors,224,15
|
||||
Towering Inferno,64,25
|
||||
Track and Field,246,24
|
||||
Treasure Below,64,24
|
||||
Treasure Island,64,22
|
||||
Trick Shot,64,23
|
||||
TRON - Deadly Discs,64,18
|
||||
Tunnel Runner,250,27
|
||||
Turmoil,64,22
|
||||
Tutankham,224,15
|
||||
Universal Chaos,64,18
|
||||
Up 'n Down,248,23
|
||||
Vanguard,248,19
|
||||
Venture,64,17
|
||||
Video Checkers,64,15
|
||||
Video Chess,64,22
|
||||
Video Jogger,64,19
|
||||
Video Life,32,20
|
||||
Video Olympics,32,18
|
||||
Video Pinball,64,22
|
||||
Video Reflex,64,21
|
||||
Vogel Flieh,64,20
|
||||
Vulture Attack,64,19
|
||||
Wabbit,64,22
|
||||
Walker,64,14
|
||||
Wall Ball,64,14
|
||||
Wall Break,64,17
|
||||
Wall-Defender,64,18
|
||||
Warlords,64,21
|
||||
Warplock,64,16
|
||||
Wing War,248,16
|
||||
Wings,250,17
|
||||
Winter Games,246,14
|
||||
Wizard of Wor,64,21
|
||||
Word Zapper,64,21
|
||||
World End,64,19
|
||||
Worm War I,64,17
|
||||
Xenophobe,246,18
|
||||
X-Man,64,18
|
||||
Yars' Revenge,64,13
|
||||
Zaxxon,248,21
|
||||
Zoo Fun,64,15
|
||||
Z-Tack,64,15
|
||||
EOF,0,0
|
1096
sd/c64cart.txt
1096
sd/c64cart.txt
File diff suppressed because it is too large
Load Diff
6
sd/config.txt
Normal file
6
sd/config.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
oscr.logging=1
|
||||
lcd.confColor=0
|
||||
lcd.red=0
|
||||
lcd.green=100
|
||||
lcd.blue=0
|
||||
md.saveType=0
|
|
@ -1,33 +1,96 @@
|
|||
Alien Invasion,2,0
|
||||
Backgammon/Acey-Deucey,0,20
|
||||
Baseball,0,29
|
||||
Bowling,0,15
|
||||
Casino Poker,2,14
|
||||
Checkers,0,19
|
||||
Demonstration Cartridge,0,15
|
||||
Demonstration Cartridge 2,0,30
|
||||
Desert Fox/Shooting Gallery,0,32
|
||||
Dodge It,0,34
|
||||
Drag Race,0,15
|
||||
Galactic Space Wars/Lunar Lander,0,16
|
||||
Hangman,1,39
|
||||
Magic Numbers,0,14
|
||||
Math Quiz I,0,20
|
||||
Math Quiz II,0,18
|
||||
Maze (Multi),0,19
|
||||
Memory Match 1 & 2,0,19
|
||||
Muehle (Multi),0,25
|
||||
Ordtaevling,1,21
|
||||
Pinball Challenge,0,18
|
||||
Pro Football,2,24
|
||||
Rat' Mal,1,19
|
||||
Robot War/Torpedo Alley,0,15
|
||||
Schach,3,30
|
||||
Slot Machine,0,13
|
||||
Sonar Search,0,19
|
||||
Space War,0,19
|
||||
Spitfire,0,16
|
||||
Tic-Tac-Toe (Multi),0,15
|
||||
Video Blackjack,0,26
|
||||
Video Whizball,1,22
|
||||
EOF,0,0
|
||||
Alien Invasion
|
||||
2
|
||||
|
||||
Backgammon/Acey-Deucey
|
||||
0
|
||||
|
||||
Baseball
|
||||
0
|
||||
|
||||
Bowling
|
||||
0
|
||||
|
||||
Casino Poker
|
||||
2
|
||||
|
||||
Checkers
|
||||
0
|
||||
|
||||
Demonstration Cartridge
|
||||
0
|
||||
|
||||
Demonstration Cartridge 2
|
||||
0
|
||||
|
||||
Desert Fox/Shooting Gallery
|
||||
0
|
||||
|
||||
Dodge It
|
||||
0
|
||||
|
||||
Drag Race
|
||||
0
|
||||
|
||||
Galactic Space Wars/Lunar Lander
|
||||
0
|
||||
|
||||
Hangman
|
||||
1
|
||||
|
||||
Magic Numbers
|
||||
0
|
||||
|
||||
Math Quiz I
|
||||
0
|
||||
|
||||
Math Quiz II
|
||||
0
|
||||
|
||||
Maze (Multi)
|
||||
0
|
||||
|
||||
Memory Match 1 & 2
|
||||
0
|
||||
|
||||
Muehle (Multi)
|
||||
0
|
||||
|
||||
Ordtaevling
|
||||
1
|
||||
|
||||
Pinball Challenge
|
||||
0
|
||||
|
||||
Pro Football
|
||||
2
|
||||
|
||||
Rat' Mal
|
||||
1
|
||||
|
||||
Robot War/Torpedo Alley
|
||||
0
|
||||
|
||||
Schach
|
||||
3
|
||||
|
||||
Slot Machine
|
||||
0
|
||||
|
||||
Sonar Search
|
||||
0
|
||||
|
||||
Space War
|
||||
0
|
||||
|
||||
Spitfire
|
||||
0
|
||||
|
||||
Tic-Tac-Toe (Multi)
|
||||
0
|
||||
|
||||
Video Blackjack
|
||||
0
|
||||
|
||||
Video Whizball
|
||||
1
|
||||
|
||||
|
|
18342
sd/gba.txt
18342
sd/gba.txt
File diff suppressed because it is too large
Load Diff
17
sd/md.txt
17
sd/md.txt
|
@ -2116,6 +2116,9 @@ Elitserien 96 (Sweden).md
|
|||
Empire of Steel (Europe).md
|
||||
E5517B77
|
||||
|
||||
Enryuu Seiken Xiao-Mei (Japan) (Aftermarket) (Unl).md
|
||||
D7DD3791
|
||||
|
||||
Escape 2042 - The Truth Defenders (World) (En,Ja,Fr,Es) (Preview) (Aftermarket) (Unl).md
|
||||
0D81511C
|
||||
|
||||
|
@ -2159,7 +2162,7 @@ ESPN Baseball Tonight (USA).md
|
|||
96D8440C
|
||||
|
||||
ESPN National Hockey Night (USA).md
|
||||
1D08828C
|
||||
401DC618
|
||||
|
||||
ESPN National Hockey Night (USA) (Beta).md
|
||||
A427814A
|
||||
|
@ -3463,6 +3466,9 @@ LHX Attack Chopper (USA, Europe).md
|
|||
Liberty or Death (USA).md
|
||||
2ADB0364
|
||||
|
||||
Life on Earth - Reimagined (World) (Aftermarket) (Unl).md
|
||||
883552AD
|
||||
|
||||
Life on Mars (World) (Aftermarket) (Unl).md
|
||||
FD214116
|
||||
|
||||
|
@ -5494,8 +5500,8 @@ Runes (World) (Aftermarket) (Homebrew).bin
|
|||
Ryuuko no Ken (Japan).md
|
||||
054CF5F6
|
||||
|
||||
Sacred Line Genesis (World) (1.1.9) (Aftermarket) (Unl).md
|
||||
2E029AB4
|
||||
Sacred Line Genesis (World) (v1.1.9) (Aftermarket) (Unl).md
|
||||
80D8F0CC
|
||||
|
||||
Sacred Line Genesis (World) (Aftermarket) (Unl).md
|
||||
AFF86301
|
||||
|
@ -5503,6 +5509,9 @@ AFF86301
|
|||
Sacred Line Zero (World) (Proto) (Aftermarket) (Unl).md
|
||||
D8A662AF
|
||||
|
||||
Sacred Line II (World) (v1.02) (Aftermarket) (Unl).md
|
||||
C03ABCED
|
||||
|
||||
Sagaia (USA).md
|
||||
F1E22F43
|
||||
|
||||
|
@ -5834,7 +5843,7 @@ Slap Fight MD (Japan) (En) (Beta).md
|
|||
DBB62949
|
||||
|
||||
Slaughter Sport (USA).md
|
||||
AF9F9D9C
|
||||
AAB2C6C4
|
||||
|
||||
Slime World (Japan).md
|
||||
7FF5529F
|
||||
|
|
2905
sd/msxcart.txt
2905
sd/msxcart.txt
File diff suppressed because it is too large
Load Diff
|
@ -1069,6 +1069,9 @@ B683A856,368C1B65,4E45531A081010080000000000000001
|
|||
Blaster Master (USA).nes
|
||||
3F0FD764,368C1B65,4E45531A081010080000000000000001
|
||||
|
||||
Blazing Rangers (World) (Homebrew).nes
|
||||
030D9844,C9DA7A15,4E45531A2000E0B81100000C00000001
|
||||
|
||||
Block Out (USA) (Proto).nes
|
||||
CF992E34,E3183FD1,4E45531A080040080000070700000001
|
||||
|
||||
|
|
533
sd/ody2cart.txt
533
sd/ody2cart.txt
|
@ -1,134 +1,399 @@
|
|||
4 en 1 Ligne,1,1,0
|
||||
4 in 1 Row,1,1,20
|
||||
Air Battle (V+),0,3,19
|
||||
Alien Invaders - Plus,0,0,24
|
||||
Alpine Skiing,0,0,30
|
||||
Armored Encounter + Sub Chase,0,0,22
|
||||
Atlantis,0,1,38
|
||||
Attack of the Timelord,0,1,17
|
||||
Baseball,0,0,31
|
||||
Billard Americain,0,0,17
|
||||
Billard Americain (V+),0,2,26
|
||||
Billard Electrique,0,0,31
|
||||
Billard Electrique (V+),0,2,27
|
||||
Blackjack,0,0,32
|
||||
Blobbers,0,2,18
|
||||
Blockout + Breakdown,0,0,17
|
||||
Bombardeio Submarino + Tiro ao Alvo,0,0,29
|
||||
Bowling + Basketball,0,0,44
|
||||
Buraco Negro,0,2,29
|
||||
Casino Slot Machine,0,0,21
|
||||
Catch the Ball + Noughts and Crosses,0,0,28
|
||||
Chat et Souris,0,1,45
|
||||
Chess,0,0,23
|
||||
Chez Maxime (V+),0,1,14
|
||||
Chinese Logic,0,0,25
|
||||
Clay Pigeon,0,1,22
|
||||
Comando Noturno,0,2,20
|
||||
Computer Golf,0,0,24
|
||||
Computer Intro,0,0,22
|
||||
Computer Programmer,0,0,23
|
||||
Conflit Cosmique,0,0,28
|
||||
Conquest of the World,0,1,25
|
||||
Cosmic Conflict,0,0,30
|
||||
Cosmic Conflict (V+),0,2,24
|
||||
Course de Voitures + Autodrome + Cryptogramme,0,0,29
|
||||
Course de Voitures + Autodrome + Cryptogramme (V+),0,2,54
|
||||
Demon Attack,0,1,59
|
||||
Demon Attack (V+),0,2,21
|
||||
Depth Charge + Marksman,0,0,26
|
||||
Desafio Chines,0,0,32
|
||||
Dynasty,0,0,23
|
||||
Electronic Table Soccer,0,0,16
|
||||
Exojet (V+),0,2,32
|
||||
Football,0,0,20
|
||||
Football Electronique + Hockey Electronique,0,0,17
|
||||
Freedom Fighters,0,1,52
|
||||
Freedom Fighters (V+),0,2,25
|
||||
Frogger,0,2,30
|
||||
Golf,0,0,16
|
||||
Great Wall Street Fortune Hunt,0,1,13
|
||||
Guerre de l'Espace (V+),0,2,39
|
||||
Guerre Laser,0,0,32
|
||||
Gunfighter,0,0,21
|
||||
Helicopter Rescue (V+),0,4,19
|
||||
Hockey + Soccer,0,0,31
|
||||
I've Got Your Number,0,0,24
|
||||
Invaders from Hyperspace,0,0,29
|
||||
Jeu de Quilles + Basketball,0,0,33
|
||||
Jeu de Quilles + Basketball (V+),0,2,36
|
||||
Jumping Acrobats,0,0,41
|
||||
K.C. Munchkin,0,1,25
|
||||
K.C.'s Krazy Chase,0,1,22
|
||||
Keyboard Creations,0,0,27
|
||||
Killer Bees,0,2,27
|
||||
Killer Bees (V+),0,2,20
|
||||
Kinder im Verkehr 1,0,0,25
|
||||
La Quete des Anneaux,0,1,28
|
||||
La Ruche Infernale (V+),0,2,29
|
||||
Labyrinth Game + Supermind,0,0,32
|
||||
Las Vegas,0,0,35
|
||||
Las Vegas Blackjack,0,0,18
|
||||
Laser War,0,0,28
|
||||
Le Mur Magique,0,0,18
|
||||
Le Tresor Englouti (V+),0,2,23
|
||||
Loony Balloon (V+),0,2,32
|
||||
Matchmaker + Logix + Buzzword,0,0,27
|
||||
Math-A-Magic + Echo,0,0,38
|
||||
Mathematicien + Echo,0,0,28
|
||||
Monkeyshines,0,1,29
|
||||
Morse,0,0,21
|
||||
Moto-Crash (V+),0,2,14
|
||||
Mousing Cat,0,1,24
|
||||
Munchkin,0,1,20
|
||||
Musician,1,1,17
|
||||
Neutron Star (V+),0,3,17
|
||||
Newscaster,0,0,26
|
||||
Nightmare,0,2,19
|
||||
Nightmare (V+),0,2,18
|
||||
Nimble Numbers Ned,0,1,23
|
||||
Norseman (V+),0,2,27
|
||||
O Malabarista + Jogo da Velha,0,0,22
|
||||
O Segredo do Farao,0,1,38
|
||||
Out of this World + Helicopter Rescue,0,0,27
|
||||
P.T. Barnum's Acrobats,0,1,46
|
||||
Pachinko,0,0,31
|
||||
Pairs + Space Rendezvous + Logic,0,0,17
|
||||
Pick Axe Pete,0,1,41
|
||||
Pickaxe Pete (V+),0,2,22
|
||||
Pocket Billiards,0,0,26
|
||||
Popeye,0,2,25
|
||||
Power Lords,0,1,15
|
||||
Power Lords (Alt),0,2,20
|
||||
Prendre l'Argent et Fuir,0,0,26
|
||||
Q-Bert,0,2,33
|
||||
Quest for the Rings,0,1,15
|
||||
Race + Spin-out + Cryptogram (V+),0,2,28
|
||||
Samurai,0,0,42
|
||||
Satellite Attack,0,0,16
|
||||
Satellite Attack (V+),0,2,25
|
||||
Secret of the Pharaohs,0,0,30
|
||||
Showdown in 2100 A.D.,0,0,31
|
||||
Sid the Spellbinder,0,1,30
|
||||
Skiing,0,0,28
|
||||
Smithereens,0,1,15
|
||||
Speedway + Spin-out + Crypto-logic,0,0,20
|
||||
Stone Sling,0,0,43
|
||||
Stone Sling (V+),0,2,20
|
||||
Super Bee,0,1,25
|
||||
Super Cobra,0,2,18
|
||||
Syracuse (V+),0,1,20
|
||||
Take the Money and Run,0,0,22
|
||||
Terrahawks (V+),0,2,31
|
||||
Thunderball,0,0,24
|
||||
Trans American Rally (V+),0,4,20
|
||||
Turtles,0,2,34
|
||||
Type & Tell,0,1,16
|
||||
UFO,0,0,20
|
||||
Verkehrsspiele 1,0,0,12
|
||||
Verkehrsspiele 2,0,0,25
|
||||
Volleyball,0,0,25
|
||||
Volleyball Electronique,0,0,19
|
||||
Wall Street,0,1,32
|
||||
War of Nerves,0,0,20
|
||||
EOF,0,0,22
|
||||
4 en 1 Ligne
|
||||
1,1
|
||||
|
||||
4 in 1 Row
|
||||
1,1
|
||||
|
||||
Air Battle (V+)
|
||||
0,3
|
||||
|
||||
Alien Invaders - Plus
|
||||
0,0
|
||||
|
||||
Alpine Skiing
|
||||
0,0
|
||||
|
||||
Armored Encounter + Sub Chase
|
||||
0,0
|
||||
|
||||
Atlantis
|
||||
0,1
|
||||
|
||||
Attack of the Timelord
|
||||
0,1
|
||||
|
||||
Baseball
|
||||
0,0
|
||||
|
||||
Billard Americain
|
||||
0,0
|
||||
|
||||
Billard Americain (V+)
|
||||
0,2
|
||||
|
||||
Billard Electrique
|
||||
0,0
|
||||
|
||||
Billard Electrique (V+)
|
||||
0,2
|
||||
|
||||
Blackjack
|
||||
0,0
|
||||
|
||||
Blobbers
|
||||
0,2
|
||||
|
||||
Blockout + Breakdown
|
||||
0,0
|
||||
|
||||
Bombardeio Submarino + Tiro ao Alvo
|
||||
0,0
|
||||
|
||||
Bowling + Basketball
|
||||
0,0
|
||||
|
||||
Buraco Negro
|
||||
0,2
|
||||
|
||||
Casino Slot Machine
|
||||
0,0
|
||||
|
||||
Catch the Ball + Noughts and Crosses
|
||||
0,0
|
||||
|
||||
Chat et Souris
|
||||
0,1
|
||||
|
||||
Chess
|
||||
0,0
|
||||
|
||||
Chez Maxime (V+)
|
||||
0,1
|
||||
|
||||
Chinese Logic
|
||||
0,0
|
||||
|
||||
Clay Pigeon
|
||||
0,1
|
||||
|
||||
Comando Noturno
|
||||
0,2
|
||||
|
||||
Computer Golf
|
||||
0,0
|
||||
|
||||
Computer Intro
|
||||
0,0
|
||||
|
||||
Computer Programmer
|
||||
0,0
|
||||
|
||||
Conflit Cosmique
|
||||
0,0
|
||||
|
||||
Conquest of the World
|
||||
0,1
|
||||
|
||||
Cosmic Conflict
|
||||
0,0
|
||||
|
||||
Cosmic Conflict (V+)
|
||||
0,2
|
||||
|
||||
Course de Voitures + Autodrome + Cryptogramme
|
||||
0,0
|
||||
|
||||
Course de Voitures + Autodrome + Cryptogramme (V+)
|
||||
0,2
|
||||
|
||||
Demon Attack
|
||||
0,1
|
||||
|
||||
Demon Attack (V+)
|
||||
0,2
|
||||
|
||||
Depth Charge + Marksman
|
||||
0,0
|
||||
|
||||
Desafio Chines
|
||||
0,0
|
||||
|
||||
Dynasty
|
||||
0,0
|
||||
|
||||
Electronic Table Soccer
|
||||
0,0
|
||||
|
||||
Exojet (V+)
|
||||
0,2
|
||||
|
||||
Football
|
||||
0,0
|
||||
|
||||
Football Electronique + Hockey Electronique
|
||||
0,0
|
||||
|
||||
Freedom Fighters
|
||||
0,1
|
||||
|
||||
Freedom Fighters (V+)
|
||||
0,2
|
||||
|
||||
Frogger
|
||||
0,2
|
||||
|
||||
Golf
|
||||
0,0
|
||||
|
||||
Great Wall Street Fortune Hunt
|
||||
0,1
|
||||
|
||||
Guerre de l'Espace (V+)
|
||||
0,2
|
||||
|
||||
Guerre Laser
|
||||
0,0
|
||||
|
||||
Gunfighter
|
||||
0,0
|
||||
|
||||
Helicopter Rescue (V+)
|
||||
0,4
|
||||
|
||||
Hockey + Soccer
|
||||
0,0
|
||||
|
||||
I've Got Your Number
|
||||
0,0
|
||||
|
||||
Invaders from Hyperspace
|
||||
0,0
|
||||
|
||||
Jeu de Quilles + Basketball
|
||||
0,0
|
||||
|
||||
Jeu de Quilles + Basketball (V+)
|
||||
0,2
|
||||
|
||||
Jumping Acrobats
|
||||
0,0
|
||||
|
||||
K.C. Munchkin
|
||||
0,1
|
||||
|
||||
K.C.'s Krazy Chase
|
||||
0,1
|
||||
|
||||
Keyboard Creations
|
||||
0,0
|
||||
|
||||
Killer Bees
|
||||
0,2
|
||||
|
||||
Killer Bees (V+)
|
||||
0,2
|
||||
|
||||
Kinder im Verkehr 1
|
||||
0,0
|
||||
|
||||
La Quete des Anneaux
|
||||
0,1
|
||||
|
||||
La Ruche Infernale (V+)
|
||||
0,2
|
||||
|
||||
Labyrinth Game + Supermind
|
||||
0,0
|
||||
|
||||
Las Vegas
|
||||
0,0
|
||||
|
||||
Las Vegas Blackjack
|
||||
0,0
|
||||
|
||||
Laser War
|
||||
0,0
|
||||
|
||||
Le Mur Magique
|
||||
0,0
|
||||
|
||||
Le Tresor Englouti (V+)
|
||||
0,2
|
||||
|
||||
Loony Balloon (V+)
|
||||
0,2
|
||||
|
||||
Matchmaker + Logix + Buzzword
|
||||
0,0
|
||||
|
||||
Math-A-Magic + Echo
|
||||
0,0
|
||||
|
||||
Mathematicien + Echo
|
||||
0,0
|
||||
|
||||
Monkeyshines
|
||||
0,1
|
||||
|
||||
Morse
|
||||
0,0
|
||||
|
||||
Moto-Crash (V+)
|
||||
0,2
|
||||
|
||||
Mousing Cat
|
||||
0,1
|
||||
|
||||
Munchkin
|
||||
0,1
|
||||
|
||||
Musician
|
||||
1,1
|
||||
|
||||
Neutron Star (V+)
|
||||
0,3
|
||||
|
||||
Newscaster
|
||||
0,0
|
||||
|
||||
Nightmare
|
||||
0,2
|
||||
|
||||
Nightmare (V+)
|
||||
0,2
|
||||
|
||||
Nimble Numbers Ned
|
||||
0,1
|
||||
|
||||
Norseman (V+)
|
||||
0,2
|
||||
|
||||
O Malabarista + Jogo da Velha
|
||||
0,0
|
||||
|
||||
O Segredo do Farao
|
||||
0,1
|
||||
|
||||
Out of this World + Helicopter Rescue
|
||||
0,0
|
||||
|
||||
P.T. Barnum's Acrobats
|
||||
0,1
|
||||
|
||||
Pachinko
|
||||
0,0
|
||||
|
||||
Pairs + Space Rendezvous + Logic
|
||||
0,0
|
||||
|
||||
Pick Axe Pete
|
||||
0,1
|
||||
|
||||
Pickaxe Pete (V+)
|
||||
0,2
|
||||
|
||||
Pocket Billiards
|
||||
0,0
|
||||
|
||||
Popeye
|
||||
0,2
|
||||
|
||||
Power Lords
|
||||
0,1
|
||||
|
||||
Power Lords (Alt)
|
||||
0,2
|
||||
|
||||
Prendre l'Argent et Fuir
|
||||
0,0
|
||||
|
||||
Q-Bert
|
||||
0,2
|
||||
|
||||
Quest for the Rings
|
||||
0,1
|
||||
|
||||
Race + Spin-out + Cryptogram (V+)
|
||||
0,2
|
||||
|
||||
Samurai
|
||||
0,0
|
||||
|
||||
Satellite Attack
|
||||
0,0
|
||||
|
||||
Satellite Attack (V+)
|
||||
0,2
|
||||
|
||||
Secret of the Pharaohs
|
||||
0,0
|
||||
|
||||
Showdown in 2100 A.D.
|
||||
0,0
|
||||
|
||||
Sid the Spellbinder
|
||||
0,1
|
||||
|
||||
Skiing
|
||||
0,0
|
||||
|
||||
Smithereens
|
||||
0,1
|
||||
|
||||
Speedway + Spin-out + Crypto-logic
|
||||
0,0
|
||||
|
||||
Stone Sling
|
||||
0,0
|
||||
|
||||
Stone Sling (V+)
|
||||
0,2
|
||||
|
||||
Super Bee
|
||||
0,1
|
||||
|
||||
Super Cobra
|
||||
0,2
|
||||
|
||||
Syracuse (V+)
|
||||
0,1
|
||||
|
||||
Take the Money and Run
|
||||
0,0
|
||||
|
||||
Terrahawks (V+)
|
||||
0,2
|
||||
|
||||
Thunderball
|
||||
0,0
|
||||
|
||||
Trans American Rally (V+)
|
||||
0,4
|
||||
|
||||
Turtles
|
||||
0,2
|
||||
|
||||
Type & Tell
|
||||
0,1
|
||||
|
||||
UFO
|
||||
0,0
|
||||
|
||||
Verkehrsspiele 1
|
||||
0,0
|
||||
|
||||
Verkehrsspiele 2
|
||||
0,0
|
||||
|
||||
Volleyball
|
||||
0,0
|
||||
|
||||
Volleyball Electronique
|
||||
0,0
|
||||
|
||||
Wall Street
|
||||
0,1
|
||||
|
||||
War of Nerves
|
||||
0,0
|
||||
|
||||
|
|
22
sd/pce.txt
22
sd/pce.txt
|
@ -22,6 +22,9 @@
|
|||
[BIOS] TurboGrafx CD System Card (USA) (v2.0).pce
|
||||
FF2A5EC3
|
||||
|
||||
1941 - Counter Attack (Japan).sgx
|
||||
8C4588E2
|
||||
|
||||
1943 Kai (Japan).pce
|
||||
FDE08D6D
|
||||
|
||||
|
@ -49,6 +52,9 @@ Air Zonk (USA).pce
|
|||
Air Zonk (USA, Europe) (WiiU Virtual Console).pce
|
||||
D76C4169
|
||||
|
||||
Aldynes - The Misson Code for Rage Crisis (Japan).sgx
|
||||
4C2126B0
|
||||
|
||||
Alien Crush (USA, Europe).pce
|
||||
EA488494
|
||||
|
||||
|
@ -100,6 +106,9 @@ Barunba (Japan).pce
|
|||
Batman (Japan).pce
|
||||
106BB7B2
|
||||
|
||||
Battle Ace (Japan).sgx
|
||||
3B13AF61
|
||||
|
||||
Battle Chopper (World) (En,Ja).pce
|
||||
2CB92290
|
||||
|
||||
|
@ -181,10 +190,13 @@ Bonk's Adventure (USA).pce
|
|||
Bonk's Adventure (USA, Europe) (WiiU Virtual Console).pce
|
||||
704C801E
|
||||
|
||||
Bonk's Revenge (USA, Europe) (Virtual Console).pce
|
||||
Bonk's Revenge (USA).pce
|
||||
F36FFEE1
|
||||
|
||||
Bonk's Revenge (USA).pce
|
||||
Bonk's Revenge (USA) (Alt).pce
|
||||
68782A2F
|
||||
|
||||
Bonk's Revenge (USA) (Alt 2).pce
|
||||
14250F9A
|
||||
|
||||
Bonk's Revenge (USA, Europe) (WiiU Virtual Console).pce
|
||||
|
@ -277,6 +289,9 @@ A594FAC0
|
|||
Daichi-kun Crisis - Do Natural (Japan).pce
|
||||
61A2935F
|
||||
|
||||
Daimakaimura (Japan).sgx
|
||||
B486A8ED
|
||||
|
||||
Daisenpuu (Japan).pce
|
||||
9107BCC8
|
||||
|
||||
|
@ -658,6 +673,9 @@ Legendary Axe, The (USA).pce
|
|||
Lode Runner - Lost Labyrinth (Japan).pce
|
||||
E6EE1468
|
||||
|
||||
Madou King Granzort (Japan).sgx
|
||||
1F041166
|
||||
|
||||
Maerchen Maze (Japan).pce
|
||||
A15A1F37
|
||||
|
||||
|
|
18
sd/pcw.txt
18
sd/pcw.txt
|
@ -22,7 +22,7 @@ Shinkenzemi 'Chuugaku Kouza' - Chuu 3 Eigo (Japan) (6BB311NH).pcw
|
|||
Shinkenzemi 'Chuugaku Kouza' - Chuugaku Chiri (Japan) (6BD410).pcw
|
||||
AD5136AE
|
||||
|
||||
Shinkenzemi 'Chuugaku Kouza' - Chuugaku Chiri (Alt) (Japan) (6BD410).pcw
|
||||
Shinkenzemi 'Chuugaku Kouza' - Chuugaku Chiri (Japan) (6BD410) (Alt).pcw
|
||||
32A902B8
|
||||
|
||||
Shinkenzemi 'Chuugaku Kouza' - Chuugaku Koumin (Japan) (6BE310).pcw
|
||||
|
@ -31,16 +31,19 @@ Shinkenzemi 'Chuugaku Kouza' - Chuugaku Koumin (Japan) (6BE310).pcw
|
|||
Shinkenzemi 'Chuugaku Kouza' - Chuugaku Rekishi (Japan) (5BC410).pcw
|
||||
7865BE62
|
||||
|
||||
Shinkenzemi 'Chuugaku Kouza' - Chuugaku Rekishi (Alt) (Japan) (5BC410).pcw
|
||||
Shinkenzemi 'Chuugaku Kouza' - Chuugaku Rekishi (Japan) (5BC410) (Alt).pcw
|
||||
44AFEBAD
|
||||
|
||||
Shinkenzemi 'Chuugaku Kouza' - Chuugaku Rekishi (Japan) (5BC410) (Alt 2).pcw
|
||||
A5EEC22E
|
||||
|
||||
Shinkenzemi 'Chuugaku Kouza' - Koukou Juken (Ei - Sha - Ri) (Japan) (6BI711).pcw
|
||||
B9831924
|
||||
|
||||
Shinkenzemi 'Chuugaku Kouza' - Koukou Juken (Koku - Suu) (Japan) (6BI712).pcw
|
||||
AEEC5776
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Chuu 1 Eigo (Japan) (0BB113NC).pcw
|
||||
Shinkenzemi Chuugaku Kouza - Chuu 1 Eigo (Japan) (0BB113NC - 7BB113NC).pcw
|
||||
775E1A65
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Chuu 1 Eigo (Japan) (0BB111NH - 7BB111NH).pcw
|
||||
|
@ -73,16 +76,13 @@ Shinkenzemi Chuugaku Kouza - Chuu 2 Eigo (Japan) (7BB215OW).pcw
|
|||
Shinkenzemi Chuugaku Kouza - Chuu 2 Eigo (New Horizon, Columbus 21) (Japan) (2BB211).pcw
|
||||
0B20B2D4
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Chuu 3 Eigo (Japan) (0BB311NH).pcw
|
||||
A18685A5
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Chuu 3 Eigo (Japan) (0BB313NC - 7BB313NC).pcw
|
||||
DDE96468
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Chuu 3 Eigo (Japan) (0BB314TE).pcw
|
||||
D87A661F
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Chuu 3 Eigo (Japan) (7BB311NH).pcw
|
||||
Shinkenzemi Chuugaku Kouza - Chuu 3 Eigo (Japan) (0BB311NH - 7BB311NH).pcw
|
||||
A18685A5
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Chuu 3 Eigo (Japan) (7BB312SS).pcw
|
||||
|
@ -133,7 +133,7 @@ BF9DA3EA
|
|||
Shinkenzemi Chuugaku Kouza - Chuugaku Koumin (Japan) (2BE310).pcw
|
||||
48A3B1B7
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Chuugaku Koumin (Japan) (7BE310).pcw
|
||||
Shinkenzemi Chuugaku Kouza - Chuugaku Koumin (Japan) (0BE310 - 7BE310).pcw
|
||||
EFEF730E
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Chuugaku Rekishi (Japan) (0BC410).pcw
|
||||
|
@ -199,7 +199,7 @@ Shinkenzemi Chuugaku Kouza - Koukou Juken (Koku - Suu) (Japan) (7BI712).pcw
|
|||
Shinkenzemi Chuugaku Kouza - Koukou Juken (Koku - Suu) (Japan) (9BI712).pcw
|
||||
0FCDC311
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Koukou Juken (Koku - Suu) (Alt) (Japan) (9BI712).pcw
|
||||
Shinkenzemi Chuugaku Kouza - Koukou Juken (Koku - Suu) (Japan) (9BI712) (Alt).pcw
|
||||
C35A53A4
|
||||
|
||||
Shinkenzemi Chuugaku Kouza - Koukou Juken EX (Yuugou - Shiryou Mondai Kouryaku) Rika Shakai (Japan) (3BI710).pcw
|
||||
|
|
40
sd/st.txt
Normal file
40
sd/st.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
Bishoujo Senshi Sailor Moon Sailor Stars - Fuwafuwa Panic 2 (Japan).st
|
||||
BB5C4238
|
||||
|
||||
Crayon Shin-chan - Nagagutsu Dobon!! (Japan).st
|
||||
8EB753F3
|
||||
|
||||
Gegege no Kitarou - Youkai Donjara (Japan).st
|
||||
4296500D
|
||||
|
||||
Gekisou Sentai Carranger - Zenkai! Racer Senshi (Japan).st
|
||||
14C66FCA
|
||||
|
||||
Poi Poi Ninja World (Japan).st
|
||||
32B2B3DD
|
||||
|
||||
SD Gundam Generation - Axis Senki (Japan).st
|
||||
72B4235F
|
||||
|
||||
SD Gundam Generation - Babylonia Kenkoku Senki (Japan).st
|
||||
792D884C
|
||||
|
||||
SD Gundam Generation - Colony Kakutouki (Japan).st
|
||||
C5DFA8FD
|
||||
|
||||
SD Gundam Generation - Gryps Senki (Japan).st
|
||||
48ECAE44
|
||||
|
||||
SD Gundam Generation - Ichinen Sensouki (Japan).st
|
||||
AFD74DCB
|
||||
|
||||
SD Gundam Generation - Zanscare Senki (Japan).st
|
||||
EFD3A865
|
||||
|
||||
SD Ultra Battle - Seven Densetsu (Japan).st
|
||||
43AD5A45
|
||||
|
||||
SD Ultra Battle - Ultraman Densetsu (Japan).st
|
||||
04939D14
|
||||
|
||||
|
|
@ -1,32 +1,94 @@
|
|||
3D Crazy Coaster,1,0
|
||||
3D Mine Storm,1,22
|
||||
3D Narrow Escape,1,20
|
||||
AnimAction,1,23
|
||||
Armor..Attack,0,17
|
||||
Art Master,0,20
|
||||
Bedlam,0,17
|
||||
Berzerk,0,13
|
||||
Blitz!,1,14
|
||||
Clean Sweep,0,13
|
||||
Cosmic Chasm,0,18
|
||||
Fortress of Narzod,1,19
|
||||
Heads-Up,1,25
|
||||
HyperChase,0,15
|
||||
Melody Master,1,17
|
||||
Mine Storm,0,20
|
||||
Mine Storm II,0,17
|
||||
Polar Rescue,1,20
|
||||
Pole Position,1,19
|
||||
Rip Off,0,20
|
||||
Scramble,0,14
|
||||
Solar Quest,0,15
|
||||
Space Wars,0,18
|
||||
Spike,1,17
|
||||
Spin ball,1,12
|
||||
Star Castle,0,16
|
||||
Star Ship,0,18
|
||||
Star Trek,0,16
|
||||
StarHawk,0,16
|
||||
WebWarp,1,15
|
||||
WebWars,1,14
|
||||
EOF,0,0
|
||||
3D Crazy Coaster
|
||||
1
|
||||
|
||||
3D Mine Storm
|
||||
1
|
||||
|
||||
3D Narrow Escape
|
||||
1
|
||||
|
||||
AnimAction
|
||||
1
|
||||
|
||||
Armor..Attack
|
||||
0
|
||||
|
||||
Art Master
|
||||
0
|
||||
|
||||
Bedlam
|
||||
0
|
||||
|
||||
Berzerk
|
||||
0
|
||||
|
||||
Blitz!
|
||||
1
|
||||
|
||||
Clean Sweep
|
||||
0
|
||||
|
||||
Cosmic Chasm
|
||||
0
|
||||
|
||||
Fortress of Narzod
|
||||
1
|
||||
|
||||
Heads-Up
|
||||
1
|
||||
|
||||
HyperChase
|
||||
0
|
||||
|
||||
Melody Master
|
||||
1
|
||||
|
||||
Mine Storm
|
||||
0
|
||||
|
||||
Mine Storm II
|
||||
0
|
||||
|
||||
Polar Rescue
|
||||
1
|
||||
|
||||
Pole Position
|
||||
1
|
||||
|
||||
Rip Off
|
||||
0
|
||||
|
||||
Scramble
|
||||
0
|
||||
|
||||
Solar Quest
|
||||
0
|
||||
|
||||
Space Wars
|
||||
0
|
||||
|
||||
Spike
|
||||
1
|
||||
|
||||
Spin ball
|
||||
1
|
||||
|
||||
Star Castle
|
||||
0
|
||||
|
||||
Star Ship
|
||||
0
|
||||
|
||||
Star Trek
|
||||
0
|
||||
|
||||
StarHawk
|
||||
0
|
||||
|
||||
WebWarp
|
||||
1
|
||||
|
||||
WebWars
|
||||
1
|
||||
|
||||
|
||||
|
|
|
@ -188,6 +188,9 @@ Tasac 2010 (USA, Europe).sv
|
|||
3D5F3964,9B451BB4,64
|
||||
|
||||
Tennis Pro '92 (USA, Europe).sv
|
||||
EAA08104,22802ED1,64
|
||||
|
||||
Tennis Pro '92 (USA, Europe) (Alt).sv
|
||||
BD004CB7,22802ED1,64
|
||||
|
||||
Thunder Shooting (USA, Europe).sv
|
||||
|
|
Loading…
Reference in New Issue
Block a user