diff --git a/Cart_Reader/Cart_Reader.ino b/Cart_Reader/Cart_Reader.ino index 1e39524..1a6b642 100644 --- a/Cart_Reader/Cart_Reader.ino +++ b/Cart_Reader/Cart_Reader.ino @@ -2,8 +2,8 @@ Cartridge Reader for Arduino Mega2560 Author: sanni - Date: 2018-05-04 - Version: V32A + Date: 04-18-2018 + Version: V33 SD lib: https://github.com/greiman/SdFat LCD lib: https://github.com/adafruit/Adafruit_SSD1306 @@ -25,7 +25,7 @@ bryc - mempak Shaun Taylor - N64 controller CRC functions Angus Gratton - CRC32 - Tamanegi_taro - SA1 fix + Tamanegi_taro - SA1 fix and PCE support Snes9x - SuperFX sram fix zzattack - multigame pcb fix Pickle - SDD1 fix @@ -35,7 +35,7 @@ infinest - help with GB Memory cart **********************************************************************************/ -char ver[5] = "V32A"; +char ver[5] = "V33"; /****************************************** Define Starting Point @@ -135,6 +135,7 @@ SdFile myFile; #define mode_GBM 10 #define mode_MD 11 #define mode_EPROM 12 +#define mode_PCE 13 /****************************************** Variables @@ -327,6 +328,10 @@ static const unsigned char PROGMEM sig [] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +//For PC Engine +extern void pcsMenu(void); +extern void pceMenu(void); + /****************************************** Menu *****************************************/ @@ -336,8 +341,9 @@ static const char modeItem2[] PROGMEM = "Super Nintendo"; static const char modeItem3[] PROGMEM = "Game Boy"; static const char modeItem4[] PROGMEM = "Mega Drive"; static const char modeItem5[] PROGMEM = "Flashrom Programmer"; -static const char modeItem6[] PROGMEM = "About"; -static const char* const modeOptions[] PROGMEM = {modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6}; +static const char modeItem6[] PROGMEM = "PC Engine/TG16"; +static const char modeItem7[] PROGMEM = "About"; +static const char* const modeOptions[] PROGMEM = {modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6, modeItem7}; void aboutScreen() { display_Clear(); @@ -393,8 +399,8 @@ void mainMenu() { // create menu with title and 6 options to choose from unsigned char modeMenu; // Copy menuOptions out of progmem - convertPgm(modeOptions, 6); - modeMenu = question_box("Cartridge Reader", menuOptions, 6, 0); + convertPgm(modeOptions, 7); + modeMenu = question_box("Cartridge Reader", menuOptions, 7, 0); // wait for user choice to come back from the question box menu switch (modeMenu) @@ -418,8 +424,10 @@ void mainMenu() { case 4: flashMenu(); break; - case 5: + pcsMenu(); + break; + case 6: aboutScreen(); break; } @@ -1311,6 +1319,9 @@ void loop() { else if (mode == mode_MD) { mdMenu(); } + else if (mode == mode_PCE) { + pceMenu(); + } else { display_Clear(); println_Msg(F("Menu Error")); diff --git a/Cart_Reader/PCE.ino b/Cart_Reader/PCE.ino new file mode 100644 index 0000000..883b7c0 --- /dev/null +++ b/Cart_Reader/PCE.ino @@ -0,0 +1,710 @@ +//****************************************** +// PC Engine & TurboGrafx dump code by tamanegi_taro +// Revision 1.0.1 April 18th 2018 +// +// Special thanks +// sanni - Arduino cart reader +// skaman - ROM size detection +// NO-INTRO - CRC list for game name detection +// +//****************************************** + +/****************************************** + Defines + *****************************************/ +#define HUCARD 0 +#define TURBOCHIP 1 + +#define DETECTION_SIZE 64 +#define CHKSUM_SKIP 0 +#define CHKSUM_OK 1 +#define CHKSUM_ERROR 2 + +/****************************************** + Prototype Declarations + *****************************************/ +/* Hoping that sanni will use this progressbar function */ +void draw_progressbar(uint32_t processedsize, uint32_t totalsize); +void pcsMenu(void); +void pceMenu(void); + +/* Several PCE dedicated functions */ +void pin_read_write_PCE(void); +void pin_init_PCE(void); +void setup_cart_PCE(void); +void reset_cart_PCE(void); +uint8_t read_byte_PCE(uint32_t address); +uint8_t write_byte_PCE(uint32_t address, uint8_t data); +uint32_t detect_rom_size_PCE(void); +void read_bank_PCE(uint32_t address_start, uint32_t address_end, uint32_t *processed_size, uint32_t total_size); +void read_rom_PCE(void); + +/****************************************** + Variables + *****************************************/ +uint8_t pce_internal_mode; //0 - HuCARD, 1 - TurboChip + +/****************************************** + Menu +*****************************************/ +// PCE start menu +static const char pceMenuItem1[] PROGMEM = "HuCARD"; +static const char pceMenuItem2[] PROGMEM = "Turbochip"; +static const char* const menuOptionspce[] PROGMEM = {pceMenuItem1, pceMenuItem2}; + +// PCE card menu items +static const char pceCartMenuItem1[] PROGMEM = "Read Rom"; +static const char pceCartMenuItem2[] PROGMEM = "Reset"; +static const char* const menuOptionspceCart[] PROGMEM = {pceCartMenuItem1, pceCartMenuItem2}; + +void draw_progressbar(uint32_t processedsize, uint32_t totalsize) +{ + uint8_t currentstatus, i; + static uint8_t previousstatus; + + //Find progressbar length and draw if processed size is not 0 + if(processedsize != 0) + { + + // Progress bar + if (processedsize >= totalsize) + { + //if processed size is equal to total process size, finish drawing progress bar + currentstatus = 20; + } + else + { + //if processed size did not reach total process size, find how many "*" should be drawn + currentstatus = processedsize / (totalsize / 20); + } + + //Draw "*" if needed + if (currentstatus > previousstatus) + { + for (i = previousstatus; i < currentstatus; i++) + { + if (i == 19) + { + //If end of progress bar, finish progress bar by drawing "]" + print_Msg(F("]")); + } + else + { + print_Msg(F("*")); + } + //Update display + display_Update(); + } + //update previous "*" status + previousstatus = currentstatus; + } + } + else + { + //If processed size is 0, initialize and draw "[" + previousstatus = 0; + print_Msg(F("[")); + display_Update(); + } +} + +// PCE start menu +void pcsMenu(void) { + // create menu with title and 3 options to choose from + unsigned char pceDev; + // Copy menuOptions out of progmem + convertPgm(menuOptionspce, 2); + pceDev = question_box("Select device", menuOptions, 2, 0); + + // wait for user choice to come back from the question box menu + switch (pceDev) + { + case 0: + //Hucard + display_Clear(); + display_Update(); + pce_internal_mode = HUCARD; + setup_cart_PCE(); + mode = mode_PCE; + break; + + case 1: + //Turbografx + display_Clear(); + display_Update(); + pce_internal_mode = TURBOCHIP; + setup_cart_PCE(); + mode = mode_PCE; + break; + } +} + +void pin_read_write_PCE(void) +{ + // Set Address Pins to Output + //A0-A7 + DDRF = 0xFF; + //A8-A15 + DDRK = 0xFF; + //A16-A19 + DDRL = (DDRL & 0xF0) | 0x0F; + + //Set Control Pin to Output CS(PL4) + DDRL |= (1 << 4); + + //Set CS(PL4) to HIGH + PORTL |= (1 << 4); + + // Set Control Pins to Output RST(PH0) RD(PH3) WR(PH5) + DDRH |= (1 << 0) | (1 << 3) | (1 << 5); + // Switch all of above to HIGH + PORTH |= (1 << 0) | (1 << 3) | (1 << 5); + + // Set IRQ(PH4) to Input + DDRH &= ~(1 << 4); + // Activate Internal Pullup Resistors + PORTH |= (1 << 4); + + // Set Data Pins (D0-D7) to Input + DDRC = 0x00; + + // Enable Internal Pullups + PORTC = 0xFF; + + reset_cart_PCE(); +} + +void pin_init_PCE(void) +{ + + //Set Address Pins to input and pull up + DDRF = 0x00; + PORTF = 0xFF; + DDRK = 0x00; + PORTK = 0xFF; + DDRL = 0x00; + PORTL = 0xFF; + DDRH &= ~((1 << 0) | (1 << 3) | (1 << 5) | (1 << 6)); + PORTH = (1 << 0) | (1 << 3) | (1 << 5) | (1 << 6); + + // Set IRQ(PH4) to Input + DDRH &= ~(1 << 4); + // Activate Internal Pullup Resistors + PORTH |= (1 << 4); + + // Set Data Pins (D0-D7) to Input + DDRC = 0x00; + // Enable Internal Pullups + PORTC = 0xFF; + +} + +void setup_cart_PCE(void) +{ + // Set cicrstPin(PG1) to Output + DDRG |= (1 << 1); + // Output a high to disable CIC + PORTG |= (1 << 1); + + pin_init_PCE(); + +} + +void reset_cart_PCE(void) +{ + //Set RESET as Low + PORTH &= ~(1 << 0); + delay(200); + //Set RESET as High + PORTH |= (1 << 0); + delay(200); + +} + +void set_address_PCE(uint32_t address) +{ + //Set address + PORTF = address & 0xFF; + PORTK = (address >> 8) & 0xFF; + PORTL = (PORTL & 0xF0) | ((address >> 16) & 0x0F); +} + +uint8_t read_byte_PCE(uint32_t address) +{ + uint8_t ret; + uint8_t address_byte; + + set_address_PCE(address); + + // 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"); + + // Set CS(PL4) and RD(PH3) as LOW + PORTL &= ~(1 << 4); + PORTH &= ~(1 << 3); + + // 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 + ret = PINC; + + //Swap bit order for PC Engine HuCARD + if(pce_internal_mode == HUCARD) + { + ret = ((ret & 0x01) << 7) | ((ret & 0x02) << 5) | ((ret & 0x04) << 3) | ((ret & 0x08) << 1) | ((ret & 0x10) >> 1) | ((ret & 0x20) >> 3) | ((ret & 0x40) >> 5) | ((ret & 0x80) >> 7); + } + + // Set CS(PL4) and RD(PH3) as HIGH + PORTL |= (1 << 4); + PORTH |= (1 << 3); + + //return read data + return ret; + +} + +uint8_t write_byte_PCE(uint32_t address, uint8_t data) +{ + uint8_t ret; + uint8_t address_byte; + + set_address_PCE(address); + + // 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"); + + //Swap bit order for PC Engine HuCARD + if(pce_internal_mode == HUCARD) + { + data = ((data & 0x01) << 7) | ((data & 0x02) << 5) | ((data & 0x04) << 3) | ((data & 0x08) << 1) | ((data & 0x10) >> 1) | ((data & 0x20) >> 3) | ((data & 0x40) >> 5) | ((data & 0x80) >> 7); + } + + //write byte + PORTC = data; + + // Set Data Pins (D0-D7) to Output + DDRC = 0xFF; + + // Set CS(PL4) and WR(PH5) as LOW + PORTL &= ~(1 << 4); + PORTH &= ~(1 << 5); + + // 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"); + + // Set CS(PL4) and WR(PH5) as HIGH + PORTL |= (1 << 4); + PORTH |= (1 << 5); + + // Set Data Pins (D0-D7) to Input + DDRC = 0x00; + + // Enable Internal Pullups + PORTC = 0xFF; + + //return read data + return ret; + +} + +//Confirm the size of ROM - 128Kb, 256Kb, 384Kb, 512Kb, 768Kb or 1024Kb +uint32_t detect_rom_size_PCE(void) +{ + uint32_t rom_size; + uint8_t read_byte; + uint8_t current_byte; + uint8_t detect_128, detect_256, detect_512, detect_768; + + //Initialize variables + detect_128 = 0; + detect_256 = 0; + detect_512 = 0; + detect_768 = 0; + + //Set pins to read PC Engine cart + pin_read_write_PCE(); + + //Confirm where mirror address start from(128KB, 256KB, 512KB, 768, or 1024KB) + for (current_byte = 0; current_byte < DETECTION_SIZE; current_byte++) { + if((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 128KB, 256KB, 512KB detection + read_byte = read_byte_PCE(current_byte); + + //128KB detection + if(current_byte == detect_128) + { + if(read_byte_PCE(current_byte + 128UL * 1024UL) == read_byte) + { + detect_128++; + } + } + + //256KB detection + if(current_byte == detect_256) + { + if(read_byte_PCE(current_byte + 256UL * 1024UL) == read_byte) + { + detect_256++; + } + } + + //512KB detection + if(current_byte == detect_512) + { + if(read_byte_PCE(current_byte + 512UL * 1024UL) == read_byte) + { + detect_512++; + } + } + + //768KB detection + read_byte = read_byte_PCE(current_byte + 512UL * 1024UL); + if(current_byte == detect_768) + { + if(read_byte_PCE(current_byte + 768UL * 1024UL) == read_byte) + { + detect_768++; + } + } + } + + //debug + //sprintf(fileName, "%d %d %d %d", 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_128 == DETECTION_SIZE) + { + rom_size = 128; + } + else if(detect_256 == DETECTION_SIZE) + { + if(detect_512 == DETECTION_SIZE) + { + rom_size = 256; + } + else + { + //Another confirmation for 384KB because 384KB hucard has data in 0x0--0x40000 and 0x80000--0xA0000(0x40000 is mirror of 0x00000) + rom_size = 384; + } + } + else if(detect_512 == DETECTION_SIZE) + { + rom_size = 512; + } + else if(detect_768 == DETECTION_SIZE) + { + rom_size = 768; + } + else + { + rom_size = 1024; + } + + //If rom size is more than or equal to 512KB, detect Street fighter II' + if(rom_size >= 512) + { + //Look for "NEC HE " + if(read_byte_PCE(0x7FFF9) == 'N' && read_byte_PCE(0x7FFFA) == 'E' && read_byte_PCE(0x7FFFB) == 'C' + && read_byte_PCE(0x7FFFC) == ' ' && read_byte_PCE(0x7FFFD) == 'H' && read_byte_PCE(0x7FFFE) == 'E') + { + rom_size = 2560; + } + } + + return rom_size; +} + +/* Must be address_start and address_end should be 512 byte aligned */ +void read_bank_PCE(uint32_t address_start, uint32_t address_end, uint32_t *processed_size, uint32_t total_size) +{ + uint32_t currByte; + uint16_t c; + + for (currByte = address_start; currByte < address_end; currByte += 512) { + for (c = 0; c < 512; c++) { + sdBuffer[c] = read_byte_PCE(currByte + c); + } + myFile.write(sdBuffer, 512); + *processed_size += 512; + draw_progressbar(*processed_size, total_size); + } +} + +//Get line from file and convert upper case to lower case +void skip_line(SdFile* readfile) +{ + int i = 0; + char str_buf; + + while (readfile->available()) + { + //Read 1 byte from file + str_buf = readfile->read(); + + //if end of file or newline found, execute command + if (str_buf == '\r') + { + readfile->read(); //dispose \n because \r\n + break; + } + i++; + }//End while +} + +//Get line from file and convert upper case to lower case +void get_line(char* str_buf, SdFile* readfile, uint8_t maxi) +{ + int i = 0; + + while (readfile->available()) + { + //If line size is more than maximum array, limit it. + if(i >= maxi) + { + i = maxi - 1; + } + + //Read 1 byte from file + str_buf[i] = readfile->read(); + + //if end of file or newline found, execute command + if (str_buf[i] == '\r') + { + str_buf[i] = '\0'; + readfile->read(); //dispose \n because \r\n + break; + } + i++; + }//End while +} + +uint32_t calculate_crc32(int n, unsigned char c[], uint32_t r) +{ + int i, j; + + for (i = 0; i < n; i++) { + r ^= c[i]; + for (j = 0; j < 8; j++) + if (r & 1) r = (r >> 1) ^ 0xEDB88320UL; + else r >>= 1; + } + return r; +} + +void crc_search(char *file_p, char *folder_p, uint32_t rom_size) +{ + SdFile rom, script; + uint32_t r, crc, processedsize; + char gamename[100]; + char crc_file[9], crc_search[9]; + uint8_t flag; + flag = CHKSUM_SKIP; + + //Open list file. If no list file found, just skip + sd.chdir("/"); //Set read directry to root + if (script.open("PCE_CRC_LIST.txt", O_READ)) + { + //Calculate CRC of ROM file + sd.chdir(folder_p); + if (rom.open(file_p, O_READ)) + { + //Initialize flag as error + flag = CHKSUM_ERROR; + crc = 0xFFFFFFFFUL; //Initialize CRC + display_Clear(); + println_Msg("Calculating chksum..."); + processedsize = 0; + draw_progressbar(0, rom_size * 1024UL); //Initialize progress bar + + while (rom.available()) + { + r = rom.read(sdBuffer, 512); + crc = calculate_crc32(r, sdBuffer, crc); + processedsize += r; + draw_progressbar(processedsize, rom_size * 1024UL); + } + + crc = crc ^ 0xFFFFFFFFUL; //Finish CRC calculation and progress bar + draw_progressbar(rom_size * 1024UL, rom_size * 1024UL); + + //Display calculated CRC + sprintf(crc_file, "%08lX", crc); + + //Search for same CRC in list + while (script.available()) { + //Read 2 lines (game name and CRC) + get_line(gamename, &script, 96); + get_line(crc_search, &script, 9); + skip_line(&script); //Skip every 3rd line + + //if checksum search successful, rename the file and end search + if(strcmp(crc_search, crc_file) == 0) + { + print_Msg("Chksum OK "); + println_Msg(crc_file); + print_Msg(F("Saved to ")); + print_Msg(folder_p); + print_Msg(F("/")); + print_Msg(gamename); + print_Msg(F(".pce")); + flag = CHKSUM_OK; + strcat(gamename, ".pce"); + rom.rename(sd.vwd(), gamename); + break; + } + } + rom.close(); + } + } + + + if(flag == CHKSUM_SKIP) + { + print_Msg(F("Saved to ")); + print_Msg(folder_p); + print_Msg(F("/")); + print_Msg(file_p); + } + else if(flag == CHKSUM_ERROR) + { + print_Msg("Chksum Error "); + println_Msg(crc_file); + print_Msg(F("Saved to ")); + print_Msg(folder_p); + print_Msg(F("/")); + print_Msg(file_p); + } + + script.close(); + +} + + +void read_rom_PCE(void) +{ + uint32_t rom_size; + uint32_t processed_size = 0; + + //clear the screen + display_Clear(); + rom_size = detect_rom_size_PCE(); + sprintf(fileName, "Detected size: %dKB", rom_size); //using filename global variable as string. Initialzed in below anyways. + println_Msg(fileName); + + //debug + //return; + + // 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(10, foldern); + sprintf(folder, "PCE/ROM/%s/%d", romName, foldern); + sd.mkdir(folder, true); + sd.chdir(folder); + + println_Msg(F("Saving ROM...")); + display_Update(); + + // write new folder number back to eeprom + foldern = foldern + 1; + EEPROM_writeAnything(10, foldern); + + //open file on sd card + if (!myFile.open(fileName, O_RDWR | O_CREAT)) { + print_Error(F("Can't create file on SD"), true); + } + + pin_read_write_PCE(); + + //Initialize progress bar by setting processed size as 0 + draw_progressbar(0, rom_size * 1024UL); + + if(rom_size == 384) + { + //Read two sections. 0x000000--0x040000 and 0x080000--0x0A0000 for 384KB + read_bank_PCE(0, 0x40000, &processed_size, rom_size * 1024UL); + read_bank_PCE(0x80000, 0xA0000, &processed_size, rom_size * 1024UL); + } + else if(rom_size == 2560) + { + //Dump Street fighter II' Champion Edition + read_bank_PCE(0, 0x80000, &processed_size, rom_size * 1024UL); //Read first bank + write_byte_PCE(0x1FF0, 0xFF); //Display second bank + read_bank_PCE(0x80000, 0x100000, &processed_size, rom_size * 1024UL); //Read second bank + write_byte_PCE(0x1FF1, 0xFF); //Display third bank + read_bank_PCE(0x80000, 0x100000, &processed_size, rom_size * 1024UL); //Read third bank + write_byte_PCE(0x1FF2, 0xFF); //Display forth bank + read_bank_PCE(0x80000, 0x100000, &processed_size, rom_size * 1024UL); //Read forth bank + write_byte_PCE(0x1FF3, 0xFF); //Display fifth bank + read_bank_PCE(0x80000, 0x100000, &processed_size, rom_size * 1024UL); //Read fifth bank + } + else + { + //Read start form 0x000000 and keep reading until end of ROM + read_bank_PCE(0, rom_size * 1024UL, &processed_size, rom_size * 1024UL); + } + + pin_init_PCE(); + + //Close the file: + myFile.close(); + + //CRC search and rename ROM + crc_search(fileName, folder, rom_size); + +} + + + + +// SNES Menu +void pceMenu() { + // create menu with title and 7 options to choose from + unsigned char mainMenu; + // Copy menuOptions out of progmem + convertPgm(menuOptionspceCart, 2); + + if(pce_internal_mode == HUCARD) + { + mainMenu = question_box("PCE HuCARD menu", menuOptions, 2, 0); + } + else + { + mainMenu = question_box("TG TurboChip menu", menuOptions, 2, 0); + } + + // wait for user choice to come back from the question box menu + switch (mainMenu) + { + case 0: + display_Clear(); + // Change working dir to root + sd.chdir("/"); + read_rom_PCE(); + break; + + case 1: + asm volatile (" jmp 0"); + break; + } + println_Msg(F("")); + println_Msg(F("Press Button...")); + display_Update(); + wait(); +} + + +//****************************************** +// End of File +//****************************************** + diff --git a/pinout.xls b/pinout.xls index 08e9b8b..bea9f95 100644 Binary files a/pinout.xls and b/pinout.xls differ diff --git a/sd/PCE_CRC_LIST.txt b/sd/PCE_CRC_LIST.txt new file mode 100644 index 0000000..8cf7291 --- /dev/null +++ b/sd/PCE_CRC_LIST.txt @@ -0,0 +1,1277 @@ +Counter Attack (Super Grafx) +D206E241 + +Counter Attack (Super Grafx) +8C4588E2 + +1943 Kai +FDE08D6D + +21 Emon - Mezase Hotel Ou!! +73614660 + +Adventure Island +8E71D4F3 + +Aero Blasters +25BE2B81 + +Aero Blasters +B03E0B32 + +After Burner II +CA72A828 + +Air Zonk +933D5BCC + +Aldynes (Super Grafx) +4C2126B0 + +Alien Crush +60EDF4E1 + +Alien Crush +EA488494 + +Ankoku Densetsu +CACC06FB + +Aoi Blink +08A09B9A + +Appare Gateball +2B54CBA2 + +Armed Formation F +20EF87FD + +Artist Tool +5E4FA713 + +Atomic Robo-Kid Special +DD175EFD + +AV Poker +B866D282 + +Ballistix +8ACFC8AA + +Ballistix +420FA189 + +Bari Bari Densetsu +C267E25D + +Barunba +4A3DF3CA + +Batman +106BB7B2 + +Battle Ace (Super Grafx) +3B13AF61 + +Battle Lode Runner +59E44F45 + +Battle Royale +E70B01AF + +Be Ball +E439F299 + +Benkei Gaiden +C9626A43 + +Benkei Gaiden +E1A73797 + +Bikkuriman World +34893891 + +Bikkuriman World +2841FD1E + +Blazing Lazers +B4A1B0F6 + +Blodia +958BCD09 + +Bloody Wolf +37BAF6BC + +Body Conquest II +FFD92458 + +Bomberman '93 +B300C5D0 + +Bomberman '93 (Special Version) +02309AA0 + +Bomberman '93 +56171C1C + +Bomberman '94 +05362516 + +Bomberman +9ABB4D1F + +Bomberman +5F6F3C2A + +Bomberman - Users Battle +1489FA51 + +Bonk III - Bonk's Big Adventure +5A3F76D8 + +Bonk's Adventure +599EAD9B + +Bonk's Revenge +14250F9A + +Bouken Danshaku Don - The Lost Sunheart +8F4D9F94 + +Boxyboy +605BE213 + +Bravoman +CCA08B02 + +Break In +C9D7426A + +Bubblegum Crash! - Knight Sabers 2034 +0D766139 + +Bull Fight - Ring no Haja +5C4D1991 + +Burning Angels +D233C05A + +Busou Keiji - Cyber Cross +D0C250CA + +Cadash +8DC0D85F + +Cadash +BB0B3AEF + +Champion Wrestler +9EDC0AEA + +Champions Forever Boxing +15EE889A + +Chew Man Fu +8CD13E9A + +Chibi Maruko Chan - Quiz de Piihyara +951ED380 + +Chikudenya Toubei - Kubikiri Yakata Yori +84098884 + +Chikudenya Toubei - Kubikiri Yakata Yori +CAB21B2E + +China Warrior +A2EE361D + +Chouzetsu Rinjin - Bravoman +0DF57C90 + +Circus Lido +C3212C24 + +City Hunter +F91B055F + +Columns +99F7A572 + +Coryoon - Child of Dragon +D5389889 + +Coryoon - Child of Dragon +B4D29E3B + +Cratermaze +9033E83A + +Cross Wiber - Cyber Combat Police +2DF97BD0 + +Cyber Core +A98D276A + +Cyber Core +4CFB6E3E + +Cyber Dodge +B5326B16 + +Cyber Knight +A594FAC0 + +Dai Makaimura (Super Grafx) +B486A8ED + +Dai Senpu +9107BCC8 + +Daichi Kun Crisis - Do Natural +61A2935F + +Darius Alpha +B0BA689F + +Darius Plus (Super Grafx-compatible) +BEBFE042 + +Darkwing Duck +4AC97606 + +Davis Cup Tennis +9EDAB596 + +Dead Moon +56739BC7 + +Dead Moon +F5D98B0B + +Deep Blue +16B40B44 + +Deep Blue - Kaitei Shinwa +053A0F83 + +Detana!! TwinBee +5CF59D80 + +Devil Crash - Naxat Pinball +4EC81A80 + +Devil's Crush - Naxat Pinball +157B4492 + +Die Hard +1B5B1CB1 + +Digital Champ +17BA3032 + +Don Doko Don! +F42AA73E + +Doraemon - Meikyuu Dai Sakusen +DC760A07 + +Doraemon - Nobita no Dorabian Night +013A747F + +Double Dungeons - W +86087B39 + +Double Dungeons - W +4A1A8C60 + +Download +4E0DE488 + +Download +85101C20 + +Dragon Egg! +442405D5 + +Dragon Saber - After Story of Dragon Spirit +C89CE75A + +Dragon Saber - After Story of Dragon Spirit +3219849C + +Dragon Spirit +01A76935 + +Dragon Spirit +086F148C + +Dragon's Curse +7D2C4B09 + +Drop Rock Hora Hora +8E81FCAC + +Drop Rock Hora Hora +67EC5EC4 + +Drop.Off +FEA27B32 + +Dungeon Explorer +1B1A80A2 + +Dungeon Explorer +4FF01515 + +Energy +CA68FF21 + +F-1 Dream +D50FF730 + +F-1 Pilot - You're King of Kings +09048174 + +F1 Circus '91 - World Championship +D7CFD70F + +F1 Circus '92 - The Speed of Sound +B268F2A2 + +F1 Circus +79705779 + +F1 Circus +E14DEE08 + +F1 Triple Battle +13BF0409 + +Falcon +0BC0A12B + +Fantasy Zone +72CB0F9D + +Fantasy Zone +E8C3573D + +Fighting Run +1828D2E5 + +Final Blaster +C90971BA + +Final Lap Twin +C8C084E3 + +Final Lap Twin +26408EA3 + +Final Match Tennis +560D2305 + +Final Soldier +AF2DD2AF + +Final Soldier (Special Version) +02A578C5 + +Fire Pro Wrestling - Combination Tag +90ED6575 + +Fire Pro Wrestling 2 - 2nd Bout +E88987BB + +Fire Pro Wrestling 3 - Legend Bout +534E8808 + +Formation Soccer - Human Cup '90 +85A1E7B6 + +Formation Soccer - On J. League +7146027C + +Fushigi no Yume no Alice +12C4E6FD + +Gai Flame +95F90DEC + +Gaia no Monshou +6FD6827C + +Galaga '88 +1A8393C6 + +Galaga '90 +2909DEC6 + +Ganbare! Golf Boys +27A4D11A + +Gekisha Boy +E8702D51 + +Genji Tsuushin Agedama +AD450DFC + +Genpei Toumaden +B926C682 + +Genpei Toumaden Ni no Maki +8793758C + +Ghost Manor +2DB4C1FD + +Gokuraku! Chuuka Taisen +E749A22C + +Gomola Speed +9A353AFD + +Gradius +0517DA65 + +Gunboat +F370B58E + +Gunhed +A17D4D7E + +Gunhed - Hudson Gunhed Taikai +57F183AE + +Hana Taaka Daka! +BA4D0DD4 + +Hanii in the Sky +BF3E2CC7 + +Hanii on the Road +9897FA86 + +Hatris +44E7DF53 + +Heavy Unit +EB923DE5 + +Hisou Kihei - Xserd +1CAB1EE6 + +Hit the Ice - VHL the Official Video Hockey League +7ACB60C8 + +Hit the Ice - VHL the Official Video Hockey League +8B29C3AA + +Honoo no Toukyuuji Dodge Danpei +B01EE703 + +Idol Hanafuda Fan Club +9EC6FC6C + +Image Fight +A80C565F + +Impossamole +E2470F5F + +J. League Greatest Eleven +0AD97B04 + +J.J. & Jeff +E01C5127 + +Jack Nicklaus' Greatest 18 Holes of Major Championship Golf +EA751E82 + +Jack Nicklaus' Turbo Golf +83384572 + +Jackie Chan +C6FA6373 + +Jackie Chan's Action Kung Fu +9D2F6193 + +Jigoku Meguri +CC7D3EEB + +Jinmu Denshou +84240EF9 + +Jinmu Denshou +C150637A + +Juuouki +6A628982 + +Juuouki +C8C7D63E + +Kaizou Choujin Shubibinman +A9084D6E + +Kaizou Choujin Shubibinman 2 - Aratanaru Teki +109BA474 + +Kato Chan & Ken Chan +6069C5E7 + +Kattobi! Takuhai Kun +4F2844B0 + +Keith Courage in Alpha Zones +474D7A72 + +KickBall +7E3C367B + +Kiki Kaikai +C0CB5ADD + +King of Casino +BF52788E + +King of Casino +2F2E2240 + +Klax +C74FFBC9 + +Klax +0F1B59B4 + +Knight Rider Special +C614116C + +Kore ga Pro Yakyuu '89 +44F60137 + +Kore ga Pro Yakyuu '90 +1772B229 + +Kung Fu, The +B552C906 + +Kyuukyoku Mahjong - Idol Graphics +02DDE03E + +Kyuukyoku Mahjong II +E5B6B3E5 + +Kyuukyoku Tiger +09509315 + +Lady Sword +EB833D15 + +Lady Sword +C6F764EC + +Legend of Hero Tonma +C28B0D8A + +Legend of Hero Tonma +3C131486 + +Legendary Axe II, The +220EBF91 + +Legendary Axe, The +2D211007 + +Lode Runner - Lost Labyrinth +E6EE1468 + +Madou Ou - Granzooto (Super Grafx) +1F041166 + +Maerchen Maze +A15A1F37 + +Magical Chase +DD0EBF8C + +Magical Chase +95CD2979 + +Mahjong Gakuen - Touma Soushirou Toujou +F5B90D55 + +Mahjong Gakuen Mild - Touma Soushirou Toujou +3E4D432A + +Mahjong Gakuen Mild - Touma Soushirou Toujou +F4148600 + +Mahjong Gokuu Special +F8861456 + +Mahjong Haou Den - Kaiser's Quest +DF10C895 + +Mahjong Shikyaku Retsuden - Mahjong Wars +6C34AAEA + +Maison Ikkoku +5C78FEE1 + +Majin Eiyuu Den Wataru +2F8935AA + +Makai Hakken Den Shada +BE62EEF5 + +Makai Prince Dorabocchan +B101B333 + +Makyou Densetsu +D4C5AF46 + +Maniac Puroresu - Asu heno Tatakai +99F2865C + +Mesopotamia +E87190F1 + +Metal Stoker +25A02BEE + +Military Madness +93F316F7 + +Mizubaku Dai Bouken +B2EF558D + +Momotarou Densetsu Gaiden Dai 1 Shuu +F860455C + +Momotarou Densetsu II +D9E1549A + +Momotarou Densetsu Turbo +625221A6 + +Momotarou Katsugeki +345F43E9 + +Monster Puroresu +F2E46D25 + +Morita Shougi PC +2546EFE0 + +Moto Roader +428F36CD + +Moto Roader +E2B0D544 + +Moto Roader II +4BA525BA + +Moto Roader II +0B7F6E5F + +Mr. Heli no Daibouken +AC0CD796 + +Mr. Heli no Daibouken +2CB92290 + +Narazumono Sentai Butai - Bloody Wolf +B01F70C2 + +Naxat Open +60ECAE22 + +Naxat Stadium +20A7D128 + +Nazo no Mascarade +0441D85A + +Necromancer +53109AE6 + +Necros no Yousai +FB0FDCFE + +Nectaris +0243453B + +Nekketsu Koukou Dodgeball Bu - PC Bangai Hen +65FDB863 + +Nekketsu Koukou Dodgeball Bu - Soccer PC Hen +F2285C6D + +Neutopia +9C49EF11 + +Neutopia +A9A94E1B + +Neutopia II +2B94AEDC + +Neutopia II +C4ED4307 + +New Adventure Island +756A1802 + +New Zealand Story, The +8E4D75A8 + +NHK Taiga Drama - Taiheiki +A32430D5 + +Night Creatures +C159761B + +Niko Niko Pun +82DEF9EE + +Ninja Ryuuken Den +67573BAC + +Ninja Spirit +DE8AF1C1 + +Ninja Warriors, The +96E0CD9D + +Obocchama Kun +4D3B0BC9 + +Operation Wolf +FF898F87 + +Order of the Griffon +FAE0FC60 + +Ordyne +8C565CB6 + +Ordyne +E7BF2A74 + +Out Live +5CDB3F5B + +Out Run +E203F223 + +Override +B74EC562 + +P-47 - The Freedom Fighter +7632DB90 + +Pac-Land +14FAD3BA + +Pac-Land +D6E30CCD + +Pachio Kun - Juuban Shoubu +4148FD7C + +Panza Kick Boxing +A980E0E9 + +Paranoia +9893E0E6 + +Parasol Stars - The Story of Bubble Bobble III +51E86451 + +Parasol Stars - The Story of Bubble Bobble III +E6458212 + +Parodius da! - Shinwa Kara Owarai he +647718F9 + +PC Denjin - Punkic Cyborgs +8FB4F228 + +PC Denjin - Punkic Cyborgs +740491C2 + +PC Genjin - Pithecanthropus Computerurus +67B35E6E + +PC Genjin - Pithecanthropus Computerurus +2CB5CD55 + +PC Genjin 2 - Pithecanthropus Computerurus +3028F7CA + +PC Genjin 3 - Pithecanthropus Computerurus +A170B60E + +PC Genjin 3 - Pithecanthropus Computerurus (Taikenban) +6F6ED301 + +PC Pachi-Slot +0AA88F33 + +Populous +0A9ADE99 + +Populous +083C956A + +Power Drift +99E6D988 + +Power Drift +25E0F6E9 + +Power Eleven +3E647D8B + +Power Gate +BE8B6E3B + +Power Golf +EA324F07 + +Power Golf +ED1D3843 + +Power League '93 +7D3E6F33 + +Power League (All Star Version) +04A85769 + +Power League +69180984 + +Power League II +C5FDFA89 + +Power League III +8AA4B220 + +Power League IV +30CC3563 + +Power League V +8B61E029 + +Power Sports +29EEC024 + +Power Tennis +8DEF5AA1 + +Pro Tennis World Court +11A36745 + +Pro Yakyuu World Stadium '91 +66B167A9 + +Pro Yakyuu World Stadium +34E089A9 + +Psycho Chaser +03883EE8 + +Psychosis +6CC10824 + +Puzzle Boy +FAA6E187 + +Puzznic +965C95B3 + +Quiz Toukou Shashin +F2E6856D + +R-Type +91CE5156 + +R-Type Part-1 +CEC3D28A + +R-Type Part-2 +F207ECAE + +Rabio Lepus Special +D8373DE6 + +Racing Damashii +3E79734C + +Raiden +850829F2 + +Raiden +BC59C31E + +Rastan Saga II +00C38E69 + +Rock-On +2FD65312 + +Ryukyu +91E6896F + +Sadakichi 7 Series - Hideyoshi no Ougon +F999356F + +Saigo no Nindou - Ninja Spirit +0590A156 + +Salamander +FAECCE20 + +Samurai-Ghost +77A924B7 + +Sekigahara +2E955051 + +Sengoku Mahjong +90E6BF49 + +Shanghai +6923D736 + +Shinobi +BC655CF3 + +Shiryou Sensen +469A0FDF + +Shockman +2774462C + +Shougi Shodan Icchokusen +23EC8970 + +Shougi Shoshinsha Muyou +457F2BC4 + +SideArms - Hyper Dyne +E5E7B8B7 + +SideArms - Hyper Dyne +D1993C9F + +Silent Debuggers +616EA179 + +Silent Debuggers +FA7E5D66 + +Sindibad Chitei no Dai Makyuu +B5C4EEBD + +Sinistron +4F6E2DBD + +Skweek +4D539C9F + +Soldier Blade +8420B12B + +Soldier Blade +4BB68B13 + +Soldier Blade Special - Caravan Stage +F39F38ED + +Somer Assault +8FCAF2E9 + +Son Son II +D7921DF2 + +Sonic Spike - World Championship Beach Volleyball +F74E5EB3 + +Soukoban World +FB37DDC4 + +Space Harrier +64580427 + +Space Harrier +43B05EB8 + +Space Invaders - Fukkatsu no Hi +99496DB3 + +Special Criminal Investigation +09A0BFCC + +Spin Pair +1C6FF459 + +Spiral Wave +A5290DD0 + +Splatterhouse +6B319457 + +Splatterhouse +D00CA74F + +Stratego +727F4656 + +Street Fighter II' - Champion Edition +D15CB6BB + +Strip Fighter II +D6FC51CE + +Super Metal Crusher +56488B36 + +Super Momotarou Dentetsu +3EB5304A + +Super Momotarou Dentetsu (Alternate) +69D52E7A + +Super Momotarou Dentetsu II +2BC023FC + +Super Star Soldier +5D0E3105 + +Super Star Soldier +DB29486F + +Super Volleyball +CE2E4F9F + +Super Volleyball +245040B3 + +Susanoo Densetsu +CF73D8FC + +Taito Chase H.Q. +6F4FD790 + +Taito Chase H.Q. +9298254C + +Takahashi Meijin no Shin Boukenjima +E415EA19 + +Takeda Shingen +DF7AF71C + +Takeda Shingen +F022BE13 + +Takin' It to the Hoop +E9D51797 + +TaleSpin +BAE9CECC + +Tatsujin +C1B26659 + +Tatsujin +A6088275 + +Tatsunoko Fighter +EEB6DD43 + +Tennokoe Bank +3B3808BD + +Tenseiryuu - Saint Dragon +2E278CCB + +Terra Cresta II - Mandoraa no Gyakushuu +1B2D0077 + +Thunder Blade +DDC3E809 + +Tiger Road +985D492D + +Time Cruise +02C39660 + +Time Cruise II +CFEC1D6A + +Timeball +5D395019 + +Titan +D20F382F + +Toilet Kids +53B7784B + +Tora heno Michi +82AE3B16 + +Toshi Tensou Keikaku - Eternal City +B18D102D + +Tower of Druaga, The +72E00BC4 + +Toy Shop Boys +97C5EE9A + +Tricky +3AEA2F8F + +Tricky Kick +48E6FD34 + +Tsuppari Oozumou - Heisei Ban +61A6E210 + +Tsuru Teruhito no Jissen Kabushiki Bai Bai Game +F70112E5 + +Turrican +EB045EDF + +TV Sports Basketball +10B60601 + +TV Sports Basketball +EA54D653 + +TV Sports Football +968D908A + +TV Sports Football +5E25B557 + +TV Sports Hockey +E7529890 + +TV Sports Hockey +97FE5BCF + +USA Pro Basketball +1CAD4B7F + +Veigues - Tactical Gladiator +04188C5C + +Veigues - Tactical Gladiator +99D14FB7 + +Victory Run +03E28CFF + +Victory Run +85CBD045 + +Vigilante +E4124FE0 + +Vigilante +79D49A0D + +Violent Soldier +1BC36B36 + +Volfied +AD226F30 + +W-Ring - The Double Rings +BE990010 + +Wai Wai Mahjong - Yukaina Janyuu Tachi +A2A0776E + +Walkuere no Densetsu +A3303978 + +Wallaby!! - Usagi no Kuni no Kangaroo Race +0112D0C7 + +Winning Shot +9B5EBC58 + +Wonder Momo +59D07314 + +World Beach Volley +BE850530 + +World Circuit +B3EEEA2E + +World Class Baseball +4186D0C0 + +World Court Tennis +A4457DF0 + +World Jockey +A9AB2954 + +World Sports Competition +4B93F0AC + +Xevious - Fardraut Densetsu +F8F85EEC + +Yo, Bro +3CA7DB48 + +Youkai Douchuuki +F131B706 + +Yuu Yuu Jinsei - Victory Life +C0905CA9 + +Zero 4 Champ +B77F2E2F + +Zero 4 Champ +EE156721 + +Zipang +67AAB7A1 + +[CD] CD-ROM System +3F9F95A4 + +[CD] CD-ROM System +52520BC6 + +[CD] CD-ROM System +283B74E0 + +[CD] Games Express CD Card +51A12D90 + +[CD] Super CD-ROM System +6D9A73EF + +[CD] TurboGrafx CD Super System Card +2B5B75FE + +[CD] TurboGrafx CD System Card +FF2A5EC3