diff --git a/CHANGES.md b/CHANGES.md index e296afc..09daf3f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,9 @@ # Release notes +### v3.15 (released 2022-07-05) +- Improved support for several flash cartridge types +- Confirmed support for the Catskull 32k Gameboy Flash Cart *(thanks CodyWick13)* +- Minor bug fixes and improvements + ### v3.14 (released 2022-06-11) - Fixed a bug with extracting the Game Boy Camera’s Game Face image *(thanks 2358)* - Improved the default file names, now includes the ROM revision information as well diff --git a/FlashGBX/FlashGBX_GUI.py b/FlashGBX/FlashGBX_GUI.py index eccbbe4..51f66d1 100644 --- a/FlashGBX/FlashGBX_GUI.py +++ b/FlashGBX/FlashGBX_GUI.py @@ -2,7 +2,7 @@ # FlashGBX # Author: Lesserkuma (github.com/lesserkuma) -import sys, os, time, datetime, re, json, platform, subprocess, requests, webbrowser, pkg_resources, struct, math +import sys, os, time, datetime, json, platform, subprocess, requests, webbrowser, pkg_resources, struct, math from .pyside import QtCore, QtWidgets, QtGui, QApplication from .RomFileDMG import RomFileDMG from .RomFileAGB import RomFileAGB @@ -2297,9 +2297,9 @@ class FlashGBX_GUI(QtWidgets.QWidget): except ImportError: pass - try: + if callable(getattr(qt_app, "exec", None)): qt_app.exec() # PySide6 - except AttributeError: + else: qt_app.exec_() # PySide2 qt_app = QApplication(sys.argv) diff --git a/FlashGBX/Flashcart.py b/FlashGBX/Flashcart.py index 47af10c..b5284cd 100644 --- a/FlashGBX/Flashcart.py +++ b/FlashGBX/Flashcart.py @@ -179,8 +179,8 @@ class Flashcart: time.sleep(0.001) def VerifyFlashID(self): - if "read_identifier" not in self.CONFIG["commands"]: return False - if len(self.CONFIG["flash_ids"]) == 0: return False + if "read_identifier" not in self.CONFIG["commands"]: return (False, []) + if len(self.CONFIG["flash_ids"]) == 0: return (False, []) if "power_cycle" in self.CONFIG and self.CONFIG["power_cycle"] is True: self.CART_POWERCYCLE_FNCPTR() self.Reset() diff --git a/FlashGBX/Util.py b/FlashGBX/Util.py index 890617e..e311a85 100644 --- a/FlashGBX/Util.py +++ b/FlashGBX/Util.py @@ -7,7 +7,7 @@ from enum import Enum # Common constants APPNAME = "FlashGBX" -VERSION_PEP440 = "3.14" +VERSION_PEP440 = "3.15" VERSION = "v{:s}".format(VERSION_PEP440) DEBUG = False diff --git a/FlashGBX/config/fc_AGB_GL256S.txt b/FlashGBX/config/fc_AGB_GL256S.txt index a67e25e..7bcbf7e 100644 --- a/FlashGBX/config/fc_AGB_GL256S.txt +++ b/FlashGBX/config/fc_AGB_GL256S.txt @@ -9,6 +9,7 @@ "voltage":3.3, "flash_size":0x2000000, "sector_size":0x20000, + "chip_erase_timeout":120, "command_set":"AMD", "commands":{ "reset":[ @@ -38,6 +39,22 @@ [ null, null, null ], [ "SA", 0xFFFF, 0xFFFF ] ], + "chip_erase":[ + [ 0xAAA, 0xA9 ], + [ 0x555, 0x56 ], + [ 0xAAA, 0x80 ], + [ 0xAAA, 0xA9 ], + [ 0x555, 0x56 ], + [ 0xAAA, 0x10 ] + ], + "chip_erase_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ 0, 0xFFFF, 0xFFFF ] + ], "buffer_write":[ [ 0xAAA, 0xA9 ], [ 0x555, 0x56 ], diff --git a/FlashGBX/config/fc_DMG_FerranteCrafts_32KB.txt b/FlashGBX/config/fc_DMG_FerranteCrafts_32KB.txt index 43ea70d..7e9aa8d 100644 --- a/FlashGBX/config/fc_DMG_FerranteCrafts_32KB.txt +++ b/FlashGBX/config/fc_DMG_FerranteCrafts_32KB.txt @@ -1,7 +1,8 @@ { "type":"DMG", "names":[ - "Ferrante Crafts cart 32 KB" + "Ferrante Crafts cart 32 KB", + "Catskull 32k Gameboy Flash Cart" ], "flash_ids":[ [ 0xBF, 0xB5, 0x01, 0xFF ] diff --git a/FlashGBX/config/fc_DMG_iG_1MB_2.txt b/FlashGBX/config/fc_DMG_iG_1MB_2.txt new file mode 100644 index 0000000..346d8dd --- /dev/null +++ b/FlashGBX/config/fc_DMG_iG_1MB_2.txt @@ -0,0 +1,52 @@ +{ + "type":"DMG", + "names":[ + "insideGadgets 1 MB, 32 KB FRAM v2.0" + ], + "flash_ids":[], + "voltage":5, + "flash_size":0x100000, + "start_addr":0, + "first_bank":1, + "write_pin":"WR", + "chip_erase_timeout":120, + "command_set":"AMD", + "commands":{ + "reset":[ + [ 0, 0xF0 ] + ], + "read_identifier":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x90 ] + ], + "chip_erase":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x80 ], + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x10 ] + ], + "chip_erase_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ 0, 0xFF, 0xFF ] + ], + "single_write":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0xA0 ], + [ "PA", "PD" ] + ], + "single_write_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ] + ] + } +} diff --git a/FlashGBX/config/fc_DMG_iG_2MB.txt b/FlashGBX/config/fc_DMG_iG_2MB.txt index 5bc4a6b..eca763e 100644 --- a/FlashGBX/config/fc_DMG_iG_2MB.txt +++ b/FlashGBX/config/fc_DMG_iG_2MB.txt @@ -1,17 +1,22 @@ { "type":"DMG", "names":[ - "insideGadgets 2 MB, 128 KB SRAM/32 KB FRAM" + "insideGadgets 2 MB, 128 KB SRAM/32 KB FRAM (T)" ], "flash_ids":[ - [ 0x01, 0x01, 0xD2, 0xD2 ], - [ 0x01, 0x01, 0xD8, 0xD8 ] + [ 0x01, 0x01, 0xD2, 0xD2 ] ], "voltage":5, "flash_size":0x200000, "start_addr":0, "first_bank":1, "write_pin":"WR", + "sector_size":[ + [0x10000, 31], + [0x8000, 1], + [0x2000, 2], + [0x4000, 1] + ], "chip_erase_timeout":120, "command_set":"AMD", "commands":{ @@ -39,6 +44,22 @@ [ null, null, null ], [ 0, 0xFF, 0xFF ] ], + "sector_erase":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x80 ], + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ "SA", 0x30 ] + ], + "sector_erase_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ "SA", 0xFF, 0xFF ] + ], "single_write":[ [ 0xAAA, 0xAA ], [ 0x555, 0x55 ], diff --git a/FlashGBX/config/fc_DMG_iG_2MB_2.txt b/FlashGBX/config/fc_DMG_iG_2MB_2.txt new file mode 100644 index 0000000..6b42de5 --- /dev/null +++ b/FlashGBX/config/fc_DMG_iG_2MB_2.txt @@ -0,0 +1,76 @@ +{ + "type":"DMG", + "names":[ + "insideGadgets 2 MB, 128 KB SRAM/32 KB FRAM (B)" + ], + "flash_ids":[ + [ 0x01, 0x01, 0xD8, 0xD8 ] + ], + "voltage":5, + "flash_size":0x200000, + "start_addr":0, + "first_bank":1, + "write_pin":"WR", + "sector_size":[ + [0x4000, 1], + [0x2000, 2], + [0x8000, 1], + [0x10000, 31] + ], + "chip_erase_timeout":120, + "command_set":"AMD", + "commands":{ + "reset":[ + [ 0, 0xF0 ] + ], + "read_identifier":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x90 ] + ], + "chip_erase":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x80 ], + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x10 ] + ], + "chip_erase_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ 0, 0xFF, 0xFF ] + ], + "sector_erase":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x80 ], + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ "SA", 0x30 ] + ], + "sector_erase_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ "SA", 0xFF, 0xFF ] + ], + "single_write":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0xA0 ], + [ "PA", "PD" ] + ], + "single_write_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ] + ] + } +} diff --git a/FlashGBX/config/fc_DMG_iG_4MB_2.txt b/FlashGBX/config/fc_DMG_iG_4MB_2.txt new file mode 100644 index 0000000..ce303e6 --- /dev/null +++ b/FlashGBX/config/fc_DMG_iG_4MB_2.txt @@ -0,0 +1,71 @@ +{ + "type":"DMG", + "names":[ + "insideGadgets 4 MB (S29JL032J)" + ], + "flash_ids":[ + [ 0x01, 0x01, 0x56, 0x56 ] + ], + "voltage":5, + "flash_size":0x400000, + "start_addr":0x4000, + "first_bank":0, + "write_pin":"WR", + "sector_size_from_cfi":true, + "chip_erase_timeout":60, + "command_set":"AMD", + "commands":{ + "reset":[ + [ 0, 0xF0 ] + ], + "read_identifier":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x90 ] + ], + "chip_erase":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x80 ], + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x10 ] + ], + "chip_erase_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ 0, 0xFF, 0xFF ] + ], + "sector_erase":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0x80 ], + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ "SA", 0x30 ] + ], + "sector_erase_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ "SA", 0xFF, 0xFF ] + ], + "single_write":[ + [ 0xAAA, 0xAA ], + [ 0x555, 0x55 ], + [ 0xAAA, 0xA0 ], + [ "PA", "PD" ] + ], + "single_write_wait_for":[ + [ null, null, null ], + [ null, null, null ], + [ null, null, null ], + [ null, null, null ] + ] + } +} diff --git a/FlashGBX/hw_GBxCartRW.py b/FlashGBX/hw_GBxCartRW.py index 4433c30..c5ace0d 100644 --- a/FlashGBX/hw_GBxCartRW.py +++ b/FlashGBX/hw_GBxCartRW.py @@ -1394,7 +1394,7 @@ class GbxDevice: self._write(self.DEVICE_CMD["SET_VOLTAGE_5V"]) time.sleep(0.1) self._write(self.DEVICE_CMD["SET_MODE_DMG"]) - elif self.MODE == "DMG": + elif self.MODE == "AGB": self._write(self.DEVICE_CMD["SET_MODE_AGB"]) for f in range(1, len(supported_carts)): @@ -1446,13 +1446,14 @@ class GbxDevice: size = supp_flash_types[1][flash_types[0]]["flash_size"] size_undetected = False for i in range(0, len(flash_types)): - if size != supp_flash_types[1][flash_types[i]]["flash_size"]: - size_undetected = True + if "flash_size" in supp_flash_types[1][flash_types[i]]: + if size != supp_flash_types[1][flash_types[i]]["flash_size"]: + size_undetected = True if size_undetected: if isinstance(cfi, dict) and "device_size" in cfi: for i in range(0, len(flash_types)): - if cfi['device_size'] == supp_flash_types[1][flash_types[i]]["flash_size"]: + if "flash_size" in supp_flash_types[1][flash_types[i]] and cfi['device_size'] == supp_flash_types[1][flash_types[i]]["flash_size"]: flash_type_id = flash_types[i] size_undetected = False break diff --git a/FlashGBX/hw_GBxCartRW_ofw.py b/FlashGBX/hw_GBxCartRW_ofw.py index 0d5cd2f..8459ead 100644 --- a/FlashGBX/hw_GBxCartRW_ofw.py +++ b/FlashGBX/hw_GBxCartRW_ofw.py @@ -5,7 +5,7 @@ # This code is used for official firmware of GBxCart v1.3 only and this code is pure chaos, sorry # Refer to hw_GBxCartRW.py for the much cleaner rewrite (used for GBxCart RW v1.4 and firmware L1 on v1.3) -import time, math, struct, traceback, zlib, copy, hashlib, os, platform, datetime +import time, math, struct, traceback, zlib, copy, hashlib, os, datetime import serial, serial.tools.list_ports from serial import SerialException from .RomFileDMG import RomFileDMG @@ -1146,7 +1146,7 @@ class GbxDevice: if header is False or len(header) != 0x180: raise Exception("Couldn’t read the cartridge information. Please try again.") if Util.DEBUG: with open("debug_header.bin", "wb") as f: f.write(header) - + # Check for DACS dacs_8m = False if header[0x04:0x04+0x9C] == bytearray([0x00] * 0x9C): @@ -1490,10 +1490,10 @@ class GbxDevice: break self.INFO["dump_info"]["agb_savelib"] = temp_ver self.INFO["dump_info"]["agb_save_flash_id"] = None - if "FLASH" in temp_ver: - agb_save_flash_id = self.ReadFlashSaveID() - if agb_save_flash_id is not False and len(agb_save_flash_id) == 3: - self.INFO["dump_info"]["agb_save_flash_id"] = agb_save_flash_id + #if "FLASH" in temp_ver: + # agb_save_flash_id = self.ReadFlashSaveID() + # if agb_save_flash_id is not False and len(agb_save_flash_id) == 3: + # self.INFO["dump_info"]["agb_save_flash_id"] = agb_save_flash_id self.INFO["rom_checksum_calc"] = chk diff --git a/FlashGBX/res/config.zip b/FlashGBX/res/config.zip index 42df668..8f42583 100644 Binary files a/FlashGBX/res/config.zip and b/FlashGBX/res/config.zip differ diff --git a/README.md b/README.md index 945f2ac..1b46583 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ Available in the GitHub [Releases](https://github.com/lesserkuma/FlashGBX/releas * Windows Setup: An installer that will add the application to the start menu and optionally create a desktop icon * Windows Portable: Have everything in one place including the config files +These work for installing fresh and upgrading from an older version. + ### Run using Python (Linux, macOS, Windows) #### Installing @@ -93,6 +95,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed - 29LV Series Flash BOY with 29LV160DB - BLAZE Xploder GB - BUNG Doctor GB Card 64M + - Catskull 32k Gameboy Flash Cart - DIY cart with AM29F010 - DIY cart with AM29F016 - DIY cart with AM29F032 diff --git a/setup.py b/setup.py index 3a566ce..afc0641 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read( setuptools.setup( name="FlashGBX", - version="3.14", + version="3.15", author="Lesserkuma", description="Reads and writes Game Boy and Game Boy Advance cartridge data. Supported hardware: GBxCart RW v1.3 and v1.4 by insideGadgets.", url="https://github.com/lesserkuma/FlashGBX",