This commit is contained in:
Lesserkuma
2023-04-26 11:53:23 +02:00
parent fff59a36fa
commit 2cf0e1fb09
15 changed files with 130 additions and 27 deletions

View File

@@ -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)*

View File

@@ -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 its 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"]})

View File

@@ -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 = ""

View File

@@ -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,

View 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 ]
]
}
}

View File

@@ -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,

View File

@@ -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

View File

@@ -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()

View File

@@ -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, "Couldnt 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.

View File

@@ -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

View File

@@ -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",