diff --git a/CHANGES.md b/CHANGES.md
index fd80833..8e96838 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,4 +1,9 @@
# Release notes
+### v3.9 (released 2022-04-29)
+- Added support for Ferrante Crafts cart 64 KB *(thanks FerrantePescara)*
+- Added support for Ferrante Crafts cart 512 KB *(thanks FerrantePescara)*
+- Fixed a bug with querying MBC3/MBC30 Real Time Clock values *(thanks HDR and AdmirtheSableye)*
+
### v3.8 (released 2022-04-21)
- Added support for AGB-E05-01 with MSP55LV100G *(thanks EmperorOfTigers)*
- Added support for DV15 with MSP55LV100G *(thanks zvxr)*
diff --git a/FlashGBX/FlashGBX.py b/FlashGBX/FlashGBX.py
index c4f6512..3ea433b 100644
--- a/FlashGBX/FlashGBX.py
+++ b/FlashGBX/FlashGBX.py
@@ -33,7 +33,7 @@ def LoadConfig(args):
(config_version, fc_files) = ReadConfigFiles(args=args)
if config_version != Util.VERSION:
# Rename old files that have since been replaced/renamed/merged
- deprecated_files = [ "fc_AGB_TEST.txt", "fc_DMG_TEST.txt", "fc_AGB_Nintendo_E201850.txt", "fc_AGB_Nintendo_E201868.txt", "config.ini", "fc_DMG_MX29LV320ABTC.txt", "fc_DMG_iG_4MB_MBC3_RTC.txt", "fc_AGB_Flash2Advance.txt", "fc_AGB_MX29LV640_AUDIO.txt", "fc_AGB_M36L0R7050T.txt", "fc_AGB_M36L0R8060B.txt", "fc_AGB_M36L0R8060T.txt", "fc_AGB_iG_32MB_S29GL512N.txt" ]
+ deprecated_files = [ "fc_AGB_TEST.txt", "fc_DMG_TEST.txt", "fc_AGB_Nintendo_E201850.txt", "fc_AGB_Nintendo_E201868.txt", "config.ini", "fc_DMG_MX29LV320ABTC.txt", "fc_DMG_iG_4MB_MBC3_RTC.txt", "fc_AGB_Flash2Advance.txt", "fc_AGB_MX29LV640_AUDIO.txt", "fc_AGB_M36L0R7050T.txt", "fc_AGB_M36L0R8060B.txt", "fc_AGB_M36L0R8060T.txt", "fc_AGB_iG_32MB_S29GL512N.txt", "fc_DMG_SST39SF010_AUDIO.txt" ]
for file in deprecated_files:
if os.path.exists(config_path + "/" + file):
os.rename(config_path + "/" + file, config_path + "/" + file + "_" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + ".bak")
@@ -59,17 +59,18 @@ def LoadConfig(args):
# Read flash cart types
for file in fc_files:
- with open(file, encoding='utf-8') as f:
- data = f.read()
- specs_int = re.sub("(0x[0-9A-F]+)", lambda m: str(int(m.group(1), 16)), data) # hex numbers to int numbers, otherwise not valid json
- try:
- specs = json.loads(specs_int)
- except:
- ret.append([2, "The flashchip type file “{:s}” could not be parsed and needs to be fixed before it can be used.".format(os.path.basename(file))])
- continue
- for name in specs["names"]:
- if not specs["type"] in flashcarts: continue # only DMG and AGB are supported right now
- flashcarts[specs["type"]][name] = specs
+ if os.path.exists(file):
+ with open(file, encoding='utf-8') as f:
+ data = f.read()
+ specs_int = re.sub("(0x[0-9A-F]+)", lambda m: str(int(m.group(1), 16)), data) # hex numbers to int numbers, otherwise not valid json
+ try:
+ specs = json.loads(specs_int)
+ except:
+ ret.append([2, "The flashchip type file “{:s}” could not be parsed and needs to be fixed before it can be used.".format(os.path.basename(file))])
+ continue
+ for name in specs["names"]:
+ if not specs["type"] in flashcarts: continue # only DMG and AGB are supported right now
+ flashcarts[specs["type"]][name] = specs
return { "flashcarts":flashcarts, "config_ret":ret }
diff --git a/FlashGBX/Util.py b/FlashGBX/Util.py
index 684a452..265394c 100644
--- a/FlashGBX/Util.py
+++ b/FlashGBX/Util.py
@@ -7,7 +7,7 @@ from enum import Enum
# Common constants
APPNAME = "FlashGBX"
-VERSION_PEP440 = "3.8"
+VERSION_PEP440 = "3.9"
VERSION = "v{:s}".format(VERSION_PEP440)
DEBUG = False
diff --git a/FlashGBX/config/fc_DMG_AT49F040_WR.txt b/FlashGBX/config/fc_DMG_AT49F040_WR.txt
index 1d900db..98863c4 100644
--- a/FlashGBX/config/fc_DMG_AT49F040_WR.txt
+++ b/FlashGBX/config/fc_DMG_AT49F040_WR.txt
@@ -24,9 +24,6 @@
[ 0x2AAA, 0x55 ],
[ 0x5555, 0x90 ]
],
- "read_cfi":[
- [ 0x5555, 0x98 ]
- ],
"chip_erase":[
[ 0x5555, 0xAA ],
[ 0x2AAA, 0x55 ],
diff --git a/FlashGBX/config/fc_DMG_FerranteCrafts_32KB.txt b/FlashGBX/config/fc_DMG_FerranteCrafts_32KB.txt
new file mode 100644
index 0000000..43ea70d
--- /dev/null
+++ b/FlashGBX/config/fc_DMG_FerranteCrafts_32KB.txt
@@ -0,0 +1,54 @@
+{
+ "type":"DMG",
+ "names":[
+ "Ferrante Crafts cart 32 KB"
+ ],
+ "flash_ids":[
+ [ 0xBF, 0xB5, 0x01, 0xFF ]
+ ],
+ "voltage":5,
+ "flash_size":0x8000,
+ "start_addr":0,
+ "first_bank":1,
+ "write_pin":"AUDIO",
+ "chip_erase_timeout":20,
+ "command_set":"AMD",
+ "commands":{
+ "reset":[
+ [ 0, 0xF0 ]
+ ],
+ "read_identifier":[
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 0x90 ]
+ ],
+ "chip_erase":[
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 0x80 ],
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 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":[
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 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_FerranteCrafts_64KB.txt b/FlashGBX/config/fc_DMG_FerranteCrafts_64KB.txt
new file mode 100644
index 0000000..bf2a1db
--- /dev/null
+++ b/FlashGBX/config/fc_DMG_FerranteCrafts_64KB.txt
@@ -0,0 +1,55 @@
+{
+ "type":"DMG",
+ "names":[
+ "Ferrante Crafts cart 64 KB"
+ ],
+ "flash_ids":[
+ [ 0xBF, 0xB5, 0x01, 0xFF ]
+ ],
+ "voltage":5,
+ "flash_size":0x10000,
+ "start_addr":0,
+ "first_bank":1,
+ "flash_commands_on_bank_1":true,
+ "write_pin":"AUDIO",
+ "chip_erase_timeout":20,
+ "command_set":"AMD",
+ "commands":{
+ "reset":[
+ [ 0, 0xF0 ]
+ ],
+ "read_identifier":[
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 0x90 ]
+ ],
+ "chip_erase":[
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 0x80 ],
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 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":[
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 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_MX29GL256EL.txt b/FlashGBX/config/fc_DMG_MX29GL256EL.txt
index 9fd9265..003a418 100644
--- a/FlashGBX/config/fc_DMG_MX29GL256EL.txt
+++ b/FlashGBX/config/fc_DMG_MX29GL256EL.txt
@@ -1,8 +1,7 @@
{
"type":"DMG",
"names":[
- "SD008-6810-V4 with MX29GL256EL",
- "SD008-6810-V4 with unlabeled flash chip"
+ "SD008-6810-V4 with MX29GL256EL"
],
"flash_ids":[
[ 0xF3, 0xC3, 0x00, 0x01 ],
diff --git a/FlashGBX/config/fc_DMG_SST39SF010_AUDIO.txt b/FlashGBX/config/fc_DMG_SST39SF020_MBC1_AUDIO.txt
similarity index 84%
rename from FlashGBX/config/fc_DMG_SST39SF010_AUDIO.txt
rename to FlashGBX/config/fc_DMG_SST39SF020_MBC1_AUDIO.txt
index 7b57b33..82b58c0 100644
--- a/FlashGBX/config/fc_DMG_SST39SF010_AUDIO.txt
+++ b/FlashGBX/config/fc_DMG_SST39SF020_MBC1_AUDIO.txt
@@ -1,19 +1,19 @@
{
"type":"DMG",
"names":[
- "Ferrante Crafts cart with SST39SF010A",
"GB-CART32K-A with SST39SF020A"
],
"flash_ids":[
- [ 0xBF, 0xB5, 0x01, 0xFF ],
[ 0xBF, 0xB6, 0x01, 0xFF ]
],
"voltage":5,
- "flash_size":0x8000,
+ "flash_size":0x10000,
"start_addr":0,
"first_bank":1,
+ "mbc":0x03,
+ "flash_commands_on_bank_1":true,
"write_pin":"AUDIO",
- "chip_erase_timeout":60,
+ "chip_erase_timeout":20,
"command_set":"AMD",
"commands":{
"reset":[
@@ -24,9 +24,6 @@
[ 0x2AAA, 0x55 ],
[ 0x5555, 0x90 ]
],
- "read_cfi":[
- [ 0x5555, 0x98 ]
- ],
"chip_erase":[
[ 0x5555, 0xAA ],
[ 0x2AAA, 0x55 ],
diff --git a/FlashGBX/config/fc_DMG_SST39SF040_MBC1_AUDIO.txt b/FlashGBX/config/fc_DMG_SST39SF040_MBC1_AUDIO.txt
index 3858d6b..dc8eae1 100644
--- a/FlashGBX/config/fc_DMG_SST39SF040_MBC1_AUDIO.txt
+++ b/FlashGBX/config/fc_DMG_SST39SF040_MBC1_AUDIO.txt
@@ -10,6 +10,7 @@
"flash_size":0x80000,
"start_addr":0,
"first_bank":1,
+ "mbc":0x03,
"flash_commands_on_bank_1":true,
"write_pin":"AUDIO",
"chip_erase_timeout":30,
diff --git a/FlashGBX/config/fc_DMG_SST39SF040_MBC5_AUDIO.txt b/FlashGBX/config/fc_DMG_SST39SF040_MBC5_AUDIO.txt
new file mode 100644
index 0000000..010be6c
--- /dev/null
+++ b/FlashGBX/config/fc_DMG_SST39SF040_MBC5_AUDIO.txt
@@ -0,0 +1,56 @@
+{
+ "type":"DMG",
+ "names":[
+ "Ferrante Crafts cart 512 KB"
+ ],
+ "flash_ids":[
+ [ 0xBF, 0xB7, 0x01, 0xFF ]
+ ],
+ "voltage":5,
+ "flash_size":0x80000,
+ "start_addr":0,
+ "first_bank":1,
+ "mbc":0x19,
+ "flash_commands_on_bank_1":true,
+ "write_pin":"AUDIO",
+ "chip_erase_timeout":30,
+ "command_set":"AMD",
+ "commands":{
+ "reset":[
+ [ 0, 0xF0 ]
+ ],
+ "read_identifier":[
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 0x90 ]
+ ],
+ "chip_erase":[
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 0x80 ],
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 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":[
+ [ 0x5555, 0xAA ],
+ [ 0x2AAA, 0x55 ],
+ [ 0x5555, 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_TC58FVB016FT.txt b/FlashGBX/config/fc_DMG_TC58FVB016FT.txt
index b74e547..42327f0 100644
--- a/FlashGBX/config/fc_DMG_TC58FVB016FT.txt
+++ b/FlashGBX/config/fc_DMG_TC58FVB016FT.txt
@@ -3,7 +3,10 @@
"names":[
"SD007_T40_64BALL_TSOP28 with TC58FVB016FT-85"
],
- "voltage":3.3,
+ "flash_ids":[
+ [ 0x98, 0x45, 0x00, 0x2A ]
+ ],
+ "voltage":5,
"flash_size":0x200000,
"start_addr":0,
"first_bank":1,
diff --git a/FlashGBX/config/fc_DMG_iG_512KB.txt b/FlashGBX/config/fc_DMG_iG_512KB.txt
index ec8ab7f..0122fc0 100644
--- a/FlashGBX/config/fc_DMG_iG_512KB.txt
+++ b/FlashGBX/config/fc_DMG_iG_512KB.txt
@@ -10,7 +10,6 @@
],
"voltage":5,
"power_cycle":true,
- "flash_size":0x80000,
"start_addr":0,
"first_bank":1,
"flash_commands_on_bank_1":true,
diff --git a/FlashGBX/fw_GBxCartRW_v1_3.py b/FlashGBX/fw_GBxCartRW_v1_3.py
index 3cbc200..2f71627 100644
--- a/FlashGBX/fw_GBxCartRW_v1_3.py
+++ b/FlashGBX/fw_GBxCartRW_v1_3.py
@@ -193,10 +193,10 @@ class FirmwareUpdaterWindow(QtWidgets.QDialog):
fw = ""
path = ""
if self.optCFW.isChecked():
- fw = "Version {:s}".format(self.CFW_VER)
+ fw = self.CFW_VER
fn = "cfw.hex"
elif self.optOFW.isChecked():
- fw = "Version {:s}".format(self.OFW_VER)
+ fw = self.OFW_VER
fn = "ofw.hex"
else:
path = self.APP.SETTINGS.value("LastDirFirmwareUpdate")
@@ -298,7 +298,7 @@ class FirmwareUpdaterWindow(QtWidgets.QDialog):
if self.ResetAVR(delay) is False:
fncSetStatus(text="Status: Bootloader error.", enableUI=True)
self.prgStatus.setValue(0)
- msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="FlashGBX", text="The firmware update was not successful as the GBxCart RW bootloader is not responding. If it doesn’t work even after multiple retries, please use the official firmware updater instead.", standardButtons=QtWidgets.QMessageBox.Ok)
+ msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="FlashGBX", text="The firmware update failed as the device is not responding correctly. Please ensure you use a genuine GBxCart RW, re-connect using a different USB cable and try again.\n\n⚠️ For safety reasons and to avoid potential fire hazards, do not use unauthorized clone hardware that have no electrical fuses, such as the “FLASH BOY” series.".replace("\n", "
"), standardButtons=QtWidgets.QMessageBox.Ok)
answer = msgbox.exec()
return 2
diff --git a/FlashGBX/fw_GBxCartRW_v1_4.py b/FlashGBX/fw_GBxCartRW_v1_4.py
index abcc3cc..3c1a05b 100644
--- a/FlashGBX/fw_GBxCartRW_v1_4.py
+++ b/FlashGBX/fw_GBxCartRW_v1_4.py
@@ -109,7 +109,7 @@ class FirmwareUpdaterWindow(QtWidgets.QDialog):
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\nGBxCart RW v1.3 can be updated only after connecting to it first. If you want to update another GBxCart RW hardware revision, please use the official firmware updater by insideGadgets instead."
+ 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."
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()
diff --git a/FlashGBX/hw_GBxCartRW.py b/FlashGBX/hw_GBxCartRW.py
index b61d5e5..8f93d29 100644
--- a/FlashGBX/hw_GBxCartRW.py
+++ b/FlashGBX/hw_GBxCartRW.py
@@ -895,7 +895,7 @@ class GbxDevice:
return buffer
- def ReadROM_3DMemory(self, address, length, max_length=512):
+ def ReadROM_3DMemory(self, address, length, max_length=64):
buffer_size = 0x1000
num = math.ceil(length / max_length)
dprint("Reading 0x{:X} bytes from cartridge ROM in {:d} iteration(s)".format(length, num))
@@ -920,7 +920,7 @@ class GbxDevice:
return buffer
- def ReadRAM(self, address, length, command=None, max_length=512):
+ def ReadRAM(self, address, length, command=None, max_length=64):
num = math.ceil(length / max_length)
dprint("Reading 0x{:X} bytes from cartridge RAM in {:d} iteration(s)".format(length, num))
if length > max_length: length = max_length
@@ -1414,6 +1414,8 @@ class GbxDevice:
flashcart.Reset(full_reset=False)
dprint("Found the correct cartridge type!")
+ if self.CanPowerCycleCart(): self.CartPowerCycle()
+
# Check flash size
flash_type_id = 0
cfi_s = ""
@@ -1426,19 +1428,20 @@ class GbxDevice:
supp_flash_types = self.GetSupportedCartridgesAGB()
(flash_id, cfi_s, cfi) = self.CheckFlashChip(limitVoltage=limitVoltage, cart_type=supp_flash_types[1][flash_type_id])
- 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 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"]:
- flash_type_id = flash_types[i]
- size_undetected = False
- break
+ if "flash_size" in supp_flash_types[1][flash_types[0]]:
+ 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 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"]:
+ flash_type_id = flash_types[i]
+ size_undetected = False
+ break
else:
(flash_id, cfi_s, cfi) = self.CheckFlashChip(limitVoltage=limitVoltage)
diff --git a/FlashGBX/hw_GBxCartRW_ofw.py b/FlashGBX/hw_GBxCartRW_ofw.py
index cda2270..3fbd4d5 100644
--- a/FlashGBX/hw_GBxCartRW_ofw.py
+++ b/FlashGBX/hw_GBxCartRW_ofw.py
@@ -903,19 +903,20 @@ class GbxDevice:
supp_flash_types = self.GetSupportedCartridgesAGB()
(flash_id, cfi_s, cfi) = self.CheckFlashChip(limitVoltage=limitVoltage, cart_type=supp_flash_types[1][flash_type_id])
- 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 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"]:
- flash_type_id = flash_types[i]
- size_undetected = False
- break
+ if "flash_size" in supp_flash_types[1][flash_types[0]]:
+ 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 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"]:
+ flash_type_id = flash_types[i]
+ size_undetected = False
+ break
else:
(flash_id, cfi_s, cfi) = self.CheckFlashChip(limitVoltage=limitVoltage)
diff --git a/FlashGBX/res/config.zip b/FlashGBX/res/config.zip
index 53c0b14..1bfab2e 100644
Binary files a/FlashGBX/res/config.zip and b/FlashGBX/res/config.zip differ
diff --git a/FlashGBX/res/fw_GBxCart_RW_v1_3.zip b/FlashGBX/res/fw_GBxCart_RW_v1_3.zip
index 53f0126..69e9e83 100644
Binary files a/FlashGBX/res/fw_GBxCart_RW_v1_3.zip and b/FlashGBX/res/fw_GBxCart_RW_v1_3.zip differ
diff --git a/README.md b/README.md
index 7873578..b33aaef 100644
--- a/README.md
+++ b/README.md
@@ -98,7 +98,9 @@ Use this command in a Terminal or Command Prompt window to launch the installed
- DIY cart with MX29LV640
- DIY cart with SST39SF040
- DMG-MBC5-32M-FLASH Development Cartridge, E201264
- - Ferrante Crafts cart with SST39SF010A
+ - Ferrante Crafts cart 32 KB
+ - Ferrante Crafts cart 64 KB
+ - Ferrante Crafts cart 512 KB
- GB-CART32K-A with SST39SF020A
- GB Smart 32M
- HDR Game Boy Camera Flashcart
@@ -237,7 +239,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
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.
-*¹ = Cannot be auto-detected, select cartridge type manually*
+*¹ = Cannot always be auto-detected, select cartridge type manually*
### Troubleshooting
@@ -269,6 +271,7 @@ The author would like to thank the following very kind people for their help and
- 90sFlav (flash chip info)
- AcoVanConis (bug reports, flash chip info)
+- AdmirtheSableye (bug reports)
- AlexiG (GBxCart RW hardware, bug reports, flash chip info)
- AndehX (app icon, flash chip info)
- antPL (flash chip info)
@@ -285,9 +288,11 @@ The author would like to thank the following very kind people for their help and
- EmperorOfTigers (bug reports, flash chip info)
- endrift (research, mGBA emulator)
- eveningmoose (flash chip info)
+- FerrantePescara (flash chip info)
- frarees (bug reports)
- Frost Clock (flash chip info)
- Grender (testing)
+- HDR (testing)
- Herax (flash chip info)
- hiks (flash chip info)
- howie0210 (flash chip info, bug reports)
diff --git a/setup.py b/setup.py
index 201df18..9a2c065 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.8",
+ version="3.9",
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",