mirror of
https://github.com/lesserkuma/FlashGBX.git
synced 2026-08-24 09:45:18 -05:00
3.27
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
# Release notes
|
||||
### v3.27 (released 2023-04-26)
|
||||
- Bundles GBxCart RW v1.4/v1.4a firmware version R42+L10 (improves flash cart compatibility) *(thanks wickawack)*
|
||||
- Added support for cartridges with MX29GL128EHT2I and ALTERA CPLD *(thanks Merkin)*
|
||||
- Improved writing speed for cartridges with MSP54LV512 (no PCB text) *(thanks SH for the contribution)*
|
||||
- Minor bug fixes and improvements *(thanks ide)*
|
||||
|
||||
### v3.26 (released 2023-04-18)
|
||||
- Fixed a bug that made exporting Game Boy Camera pictures with a frame not work *(thanks Ell)*
|
||||
- Fixed a bug with Game Boy ROM write verification on sectors smaller than 0x4000 bytes *(thanks KOOORAY)*
|
||||
|
||||
@@ -815,7 +815,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
||||
msg += message + "\n\n"
|
||||
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), msg[:-2], QtWidgets.QMessageBox.Ok)
|
||||
else:
|
||||
QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text="No compatible devices found. Please ensure the device is connected properly.\n\nTroubleshooting advice:\n- Reconnect the device and check if the operating system detects it\n- Try different USB ports and cables, avoid passive USB hubs\n- Use a USB data cable (battery charging cables may not work)\n- Ensure your user account has permissions to use the device\n- Refer to the device compatibility list on the <a href=\"https://github.com/lesserkuma/FlashGBX/#compatible-cartridge-readerwriter-hardware\">GitHub page</a>".replace("\n", "<br>"), standardButtons=QtWidgets.QMessageBox.Ok).exec()
|
||||
QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text="No compatible devices found. Please ensure the device is connected properly.\n\nTroubleshooting advice:\n- Reconnect the device, try different USB ports/cables, avoid passive USB hubs\n- Use a USB data cable (battery charging cables may not work)\n- Check if the operating system detects the device (if not, reboot your machine)\n- Ensure your user account has permissions to use the device\n- Refer to the device compatibility list on the <a href=\"https://github.com/lesserkuma/FlashGBX/#compatible-cartridge-readerwriter-hardware\">GitHub page</a>".replace("\n", "<br>"), standardButtons=QtWidgets.QMessageBox.Ok).exec()
|
||||
|
||||
self.lblDevice.setText("No devices found.")
|
||||
self.lblDevice.setStyleSheet("")
|
||||
@@ -1047,7 +1047,24 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
||||
if "broken_sectors" in self.CONN.INFO:
|
||||
s = ""
|
||||
for sector in self.CONN.INFO["broken_sectors"]: s += "0x{:X}~0x{:X}, ".format(sector[0], sector[0]+sector[1]-1)
|
||||
answer = QtWidgets.QMessageBox.warning(self, "{:s} {:s}".format(APPNAME, VERSION), "The ROM was written completely, but verification of written data failed in the following sector(s): {:s}.\n\nDo you want to try and write the sectors again that failed verification?".format(s[:-2]), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes)
|
||||
msg_v = "The ROM was written completely, but verification of written data failed in the following sector(s): {:s}.".format(s[:-2])
|
||||
if "verify_error_params" in self.CONN.INFO:
|
||||
if self.CONN.GetMode() == "DMG":
|
||||
cart_types = self.CONN.GetSupportedCartridgesDMG()[0]
|
||||
elif self.CONN.GetMode() == "AGB":
|
||||
cart_types = self.CONN.GetSupportedCartridgesAGB()[0]
|
||||
cart_type_str = " ({:s})".format(cart_types[self.CONN.INFO["dump_info"]["cart_type"]])
|
||||
msg_v += "\n\nTips:\n- Clean cartridge contacts\n- Check soldering if it’s a DIY cartridge\n- Avoid passive USB hubs and try different USB ports/cables\n- Check cartridge type selection{:s}\n- Check cartridge ROM storage size (at least {:s} is required)".format(cart_type_str, Util.formatFileSize(self.CONN.INFO["verify_error_params"]["rom_size"]))
|
||||
if "mapper_selection_type" in self.CONN.INFO["verify_error_params"]:
|
||||
if self.CONN.INFO["verify_error_params"]["mapper_selection_type"] == 1: # manual
|
||||
msg_v += "\n- Check mapper type used: {:s} (manual selection)".format(self.CONN.INFO["verify_error_params"]["mapper_name"])
|
||||
elif self.CONN.INFO["verify_error_params"]["mapper_selection_type"] == 2: # forced by cart type
|
||||
msg_v += "\n- Check mapper type used: {:s} (forced by selected cartridge type)".format(self.CONN.INFO["verify_error_params"]["mapper_name"])
|
||||
if self.CONN.INFO["verify_error_params"]["rom_size"] > self.CONN.INFO["verify_error_params"]["mapper_max_size"]:
|
||||
msg_v += "\n- Check mapper type ROM size limit: likely up to {:s}".format(Util.formatFileSize(self.CONN.INFO["verify_error_params"]["mapper_max_size"]))
|
||||
msg_v += "\n\nDo you want to try and write the sectors again that failed verification?"
|
||||
|
||||
answer = QtWidgets.QMessageBox.warning(self, "{:s} {:s}".format(APPNAME, VERSION), msg_v, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes)
|
||||
if answer == QtWidgets.QMessageBox.Yes:
|
||||
args = self.STATUS["args"]
|
||||
args.update({"flash_sectors":self.CONN.INFO["broken_sectors"]})
|
||||
|
||||
@@ -7,9 +7,9 @@ from enum import Enum
|
||||
|
||||
# Common constants
|
||||
APPNAME = "FlashGBX"
|
||||
VERSION_PEP440 = "3.26"
|
||||
VERSION_PEP440 = "3.27"
|
||||
VERSION = "v{:s}".format(VERSION_PEP440)
|
||||
VERSION_TIMESTAMP = 1681817120
|
||||
VERSION_TIMESTAMP = 1682502626
|
||||
DEBUG = False
|
||||
DEBUG_LOG = []
|
||||
APP_PATH = ""
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"type":"AGB",
|
||||
"names":[
|
||||
"AGB-E20-30 with M29W128GH"
|
||||
"AGB-E20-30 with M29W128GH",
|
||||
"MX29GL128EHT2I and ALTERA CPLD"
|
||||
],
|
||||
"flash_ids":[
|
||||
[ 0x20, 0x00, 0x7E, 0x22 ]
|
||||
[ 0x20, 0x00, 0x7E, 0x22 ],
|
||||
[ 0xC2, 0x00, 0x7E, 0x22 ]
|
||||
],
|
||||
"voltage":3.3,
|
||||
"flash_size":0x1000000,
|
||||
|
||||
73
FlashGBX/config/fc_DMG_MSP54LV512.txt
Normal file
73
FlashGBX/config/fc_DMG_MSP54LV512.txt
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"type":"DMG",
|
||||
"names":[
|
||||
"MSP54LV512 (no PCB text)"
|
||||
],
|
||||
"flash_ids":[
|
||||
[ 0x02, 0x7D, 0x00, 0x09 ]
|
||||
],
|
||||
"voltage":5,
|
||||
"flash_size":0x2000000,
|
||||
"start_addr":0,
|
||||
"first_bank":1,
|
||||
"buffer_size":32,
|
||||
"sector_size":0x10000,
|
||||
"reset_every":0x800000,
|
||||
"mbc":0x201,
|
||||
"write_pin":"WR",
|
||||
"command_set":"AMD",
|
||||
"commands":{
|
||||
"reset":[
|
||||
[ 0, 0xF0 ]
|
||||
],
|
||||
"read_identifier":[
|
||||
[ 0x555, 0xA9 ],
|
||||
[ 0x2AA, 0x56 ],
|
||||
[ 0x555, 0x90 ]
|
||||
],
|
||||
"sector_erase":[
|
||||
[ 0x555, 0xA9 ],
|
||||
[ 0x2AA, 0x56 ],
|
||||
[ 0x555, 0x80 ],
|
||||
[ 0x555, 0xA9 ],
|
||||
[ 0x2AA, 0x56 ],
|
||||
[ "SA", 0x30 ]
|
||||
],
|
||||
"sector_erase_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ "SA", 0xFF, 0xFF ]
|
||||
],
|
||||
"buffer_write":[
|
||||
[ 0x555, 0xA9 ],
|
||||
[ 0x2AA, 0x56 ],
|
||||
[ "SA", 0x26 ],
|
||||
[ "SA", "BS" ],
|
||||
[ "PA", "PD" ],
|
||||
[ "SA", 0x2A ]
|
||||
],
|
||||
"buffer_write_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ "SA", "PD", 0xFFFF ]
|
||||
],
|
||||
"single_write":[
|
||||
[ 0x555, 0xA9 ],
|
||||
[ 0x2AA, 0x56 ],
|
||||
[ 0x555, 0xA0 ],
|
||||
[ "PA", "PD" ]
|
||||
],
|
||||
"single_write_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ]
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
{
|
||||
"type":"DMG",
|
||||
"names":[
|
||||
"SD008-6810-512S with MSP55LV512",
|
||||
"MSP54LV512 (no PCB text)"
|
||||
"SD008-6810-512S with MSP55LV512"
|
||||
],
|
||||
"flash_ids":[
|
||||
[ 0x02, 0x7D, 0x00, 0x08 ],
|
||||
[ 0x02, 0x7D, 0x00, 0x09 ]
|
||||
[ 0x02, 0x7D, 0x00, 0x08 ]
|
||||
],
|
||||
"voltage":3.3,
|
||||
"voltage_variants":true,
|
||||
|
||||
@@ -307,7 +307,7 @@ class FirmwareUpdaterWindow(QtWidgets.QDialog):
|
||||
|
||||
while True:
|
||||
try:
|
||||
dev = serial.Serial(port=port, baudrate=9600, timeout=1)
|
||||
dev = serial.Serial(port=port, baudrate=9600*4, timeout=1)
|
||||
except:
|
||||
fncSetStatus(text="Status: Device access error.", enableUI=True)
|
||||
return 2
|
||||
|
||||
@@ -98,7 +98,7 @@ try:
|
||||
QtWidgets.QDialog.__init__(self)
|
||||
if icon is not None: self.setWindowIcon(QtGui.QIcon(icon))
|
||||
self.setStyleSheet("QMessageBox { messagebox-text-interaction-flags: 5; }")
|
||||
self.setWindowTitle("FlashGBX – Firmware Updater for GBxCart RW v1.4")
|
||||
self.setWindowTitle("FlashGBX – Firmware Updater for GBxCart RW")
|
||||
self.setWindowFlags((self.windowFlags() | QtCore.Qt.MSWindowsFixedSizeDialogHint) & ~QtCore.Qt.WindowContextHelpButtonHint)
|
||||
|
||||
self.APP = app
|
||||
@@ -110,7 +110,7 @@ try:
|
||||
self.DEVICE = device
|
||||
else:
|
||||
self.APP.QT_APP.processEvents()
|
||||
text = "This Firmware Updater is for insideGadgets GBxCart RW v1.4 devices only. Please only proceed if your device matches this hardware revision.\n\nOlder GBxCart RW revisions can be updated only after connecting to them first."
|
||||
text = "This Firmware Updater is for insideGadgets GBxCart RW v1.4/v1.4a devices only. Please only proceed if your device matches this hardware revision.\n\nOlder GBxCart RW revisions can be updated only after connecting to them first."
|
||||
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
|
||||
msgbox.setDefaultButton(QtWidgets.QMessageBox.Ok)
|
||||
answer = msgbox.exec()
|
||||
|
||||
@@ -16,8 +16,8 @@ from . import Util
|
||||
class GbxDevice:
|
||||
DEVICE_NAME = "GBxCart RW"
|
||||
DEVICE_MIN_FW = 1
|
||||
DEVICE_MAX_FW = 9
|
||||
DEVICE_LATEST_FW_TS = { 4:1681739002, 5:1681395695, 6:1681395696 }
|
||||
DEVICE_MAX_FW = 10
|
||||
DEVICE_LATEST_FW_TS = { 4:1682502626, 5:1681900614, 6:1681900614 }
|
||||
|
||||
DEVICE_CMD = {
|
||||
"NULL":0x30,
|
||||
@@ -165,15 +165,10 @@ class GbxDevice:
|
||||
if self.FW is not None:
|
||||
conn_msg.append([0, "Couldn’t communicate with the GBxCart RW device on port " + ports[i] + ". Please disconnect and reconnect the device, then try again."])
|
||||
continue
|
||||
elif self.FW is None or "cfw_id" not in self.FW or self.FW["cfw_id"] != 'L': # Not a CFW by Lesserkuma
|
||||
elif self.FW is None or "cfw_id" not in self.FW or self.FW["cfw_id"] != 'L' or self.FW["fw_ver"] < self.DEVICE_MIN_FW or (self.FW["pcb_ver"] < 5 and self.FW["fw_ver"] != 1): # Not a CFW by Lesserkuma
|
||||
dev.close()
|
||||
self.DEVICE = None
|
||||
continue
|
||||
elif self.FW["fw_ver"] < self.DEVICE_MIN_FW:
|
||||
dev.close()
|
||||
self.DEVICE = None
|
||||
conn_msg.append([3, "The GBxCart RW device on port " + ports[i] + " requires a firmware update to work with this software. Please try again after updating it to version L" + str(self.DEVICE_MIN_FW) + " or higher.<br><br>Firmware updates are available at <a href=\"https://www.gbxcart.com/\">https://www.gbxcart.com/</a>."])
|
||||
continue
|
||||
elif self.FW["fw_ts"] > self.DEVICE_LATEST_FW_TS[self.FW["pcb_ver"]]:
|
||||
conn_msg.append([0, "Note: The GBxCart RW device on port " + ports[i] + " is running a firmware version that is newer than what this version of FlashGBX was developed to work with, so errors may occur."])
|
||||
|
||||
@@ -375,8 +370,10 @@ class GbxDevice:
|
||||
|
||||
def FirmwareUpdateAvailable(self):
|
||||
if self.FW["pcb_ver"] not in (4, 5, 6): return False
|
||||
if (self.FW["pcb_ver"] in (4, 5, 6) and self.FW["fw_ts"] < self.DEVICE_LATEST_FW_TS[self.FW["pcb_ver"]]):
|
||||
if self.FW["pcb_ver"] == 4: self.FW_UPDATE_REQ = True
|
||||
if self.FW["pcb_ver"] in (5, 6) and self.FW["fw_ts"] < self.DEVICE_LATEST_FW_TS[self.FW["pcb_ver"]]:
|
||||
return True
|
||||
if self.FW["pcb_ver"] == 4 and self.FW["fw_ts"] != self.DEVICE_LATEST_FW_TS[self.FW["pcb_ver"]]:
|
||||
self.FW_UPDATE_REQ = True
|
||||
return True
|
||||
|
||||
def GetFirmwareUpdaterClass(self):
|
||||
@@ -2181,7 +2178,7 @@ class GbxDevice:
|
||||
if (self.MODE == "AGB" and "command_set" in cart_type and cart_type["command_set"] == "3DMEMORY"):
|
||||
temp = self.ReadROM_3DMemory(address=pos, length=buffer_len, max_length=max_length)
|
||||
else:
|
||||
if self.FW["fw_ver"] >= 9 and "verify_write" in args and (self.MODE != "AGB" or args["verify_base_pos"] > 0xC9):
|
||||
if self.FW["fw_ver"] >= 10 and "verify_write" in args and (self.MODE != "AGB" or args["verify_base_pos"] > 0xC9):
|
||||
# Verify mode (by CRC32)
|
||||
dprint("CRC32 verification (verify_base_pos=0x{:X}, pos=0x{:X}, pos_total=0x{:X}, buffer_len=0x{:X})".format(args["verify_base_pos"], pos, pos_total, buffer_len))
|
||||
if self.MODE == "DMG":
|
||||
@@ -2202,7 +2199,7 @@ class GbxDevice:
|
||||
continue
|
||||
else:
|
||||
dprint("Mismatch during CRC32 verification between 0x{:X} and 0x{:X}".format(pos_total, pos_total+buffer_len))
|
||||
return pos_total
|
||||
temp = self.ReadROM(address=pos, length=buffer_len, skip_init=skip_init, max_length=max_length)
|
||||
else:
|
||||
# Normal read
|
||||
temp = self.ReadROM(address=pos, length=buffer_len, skip_init=skip_init, max_length=max_length)
|
||||
@@ -3556,6 +3553,15 @@ class GbxDevice:
|
||||
|
||||
if len(broken_sectors) > 0:
|
||||
self.INFO["broken_sectors"] = broken_sectors
|
||||
self.INFO["verify_error_params"] = {}
|
||||
self.INFO["verify_error_params"]["rom_size"] = len(data_import)
|
||||
if self.MODE == "DMG":
|
||||
self.INFO["verify_error_params"]["mapper_name"] = _mbc.GetName()
|
||||
if flashcart.GetMBC() == "manual":
|
||||
self.INFO["verify_error_params"]["mapper_selection_type"] = 1 # manual
|
||||
else:
|
||||
self.INFO["verify_error_params"]["mapper_selection_type"] = 2 # forced by cart type
|
||||
self.INFO["verify_error_params"]["mapper_max_size"] = _mbc.GetMaxROMSize()
|
||||
verified = False
|
||||
# ↑↑↑ Flash verify
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -265,6 +265,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
||||
- M5M29G130AN (no PCB text)
|
||||
- M6MGJ927 (no PCB text)
|
||||
- MSP54LV512 (no PCB text)
|
||||
- MX29GL128EHT2I and ALTERA CPLD
|
||||
- SUN100S_MSP54XXX with MSP54LV100
|
||||
|
||||
Many different reproduction cartridges share their flash chip command set, so even if yours is not on this list, it may still work fine or even be auto-detected as another one. Support for more cartridges can also be added by creating external config files that include the necessary flash chip commands.
|
||||
@@ -301,7 +302,7 @@ Many different reproduction cartridges share their flash chip command set, so ev
|
||||
|
||||
The author would like to thank the following very kind people for their help, contributions or documentation (in alphabetical order):
|
||||
|
||||
2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, bbsan, BennVenn, ccs21, ClassicOldSong, CodyWick13, Corborg, crizzlycruz, Därk, Davidish, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, Jayro, Jenetrix, JFox, joyrider3774, JS7457, julgr, Kaede, KOOORAY, kscheel, kyokohunter, litlemoran, LovelyA72, Luca DS, LucentW, manuelcm1, marv17, metroid-maniac, Mr_V, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, s1cp, Satumox, Sgt.DoudouMiel, Shinichi999, sillyhatday, Sithdown, skite2001, Smelly-Ghost, Stitch, Super Maker, t5b6_de, Tauwasser, Timville, twitnic, velipso, Veund, voltagex, Voultar, Wkr, x7l7j8cc, xactoes, Zeii, Zelante, zvxr
|
||||
2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, bbsan, BennVenn, ccs21, ClassicOldSong, CodyWick13, Corborg, crizzlycruz, Därk, Davidish, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, Jayro, Jenetrix, JFox, joyrider3774, JS7457, julgr, Kaede, KOOORAY, kscheel, kyokohunter, litlemoran, LovelyA72, Luca DS, LucentW, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, sillyhatday, Sithdown, skite2001, Smelly-Ghost, Stitch, Super Maker, t5b6_de, Tauwasser, Timville, twitnic, velipso, Veund, voltagex, Voultar, wickawack, Wkr, x7l7j8cc, xactoes, Zeii, Zelante, zvxr
|
||||
|
||||
## DISCLAIMER
|
||||
|
||||
|
||||
2
setup.py
2
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.26",
|
||||
version="3.27",
|
||||
author="Lesserkuma",
|
||||
description="Reads and writes Game Boy and Game Boy Advance cartridge data using the GBxCart RW by insideGadgets",
|
||||
url="https://github.com/lesserkuma/FlashGBX",
|
||||
|
||||
Reference in New Issue
Block a user