FlashGBX 4.4__tar.gz → 4.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/DataTransfer.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/FlashGBX.py +3 -2
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/FlashGBX_CLI.py +12 -3
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/FlashGBX_GUI.py +24 -20
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/Flashcart.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/GBMemory.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/LK_Device.py +30 -21
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/Mapper.py +2 -23
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/PocketCamera.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/PocketCameraWindow.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/RomFileAGB.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/RomFileDMG.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/UserInputDialog.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/Util.py +5 -5
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/__main__.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/fw_GBFlash.py +20 -3
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/fw_GBxCartRW_v1_3.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/fw_GBxCartRW_v1_4.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/fw_JoeyJr.py +2 -2
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/hw_GBFlash.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/hw_GBxCartRW.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/hw_JoeyJr.py +1 -1
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/pyside.py +1 -1
- flashgbx-4.6/FlashGBX/res/config.zip +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/fw_GBFlash.zip +0 -0
- flashgbx-4.6/FlashGBX/res/fw_GBxCart_RW_v1_4.zip +0 -0
- flashgbx-4.6/FlashGBX/res/fw_GBxCart_RW_v1_4a.zip +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/fw_JoeyJr.zip +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX.egg-info/PKG-INFO +21 -14
- {flashgbx-4.4 → flashgbx-4.6}/PKG-INFO +21 -14
- {flashgbx-4.4 → flashgbx-4.6}/README.md +15 -9
- {flashgbx-4.4 → flashgbx-4.6}/setup.py +5 -5
- flashgbx-4.4/FlashGBX/res/config.zip +0 -0
- flashgbx-4.4/FlashGBX/res/fw_GBxCart_RW_v1_4.zip +0 -0
- flashgbx-4.4/FlashGBX/res/fw_GBxCart_RW_v1_4a.zip +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/__init__.py +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/Third Party Notices.md +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/fw_GBxCart_RW_Mini_v1_0.zip +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/fw_GBxCart_RW_XMAS_v1_0.zip +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/fw_GBxCart_RW_v1_1_v1_2.zip +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/fw_GBxCart_RW_v1_3.zip +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/icon.ico +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/icon.png +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX/res/pc_frame.png +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX.egg-info/SOURCES.txt +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX.egg-info/dependency_links.txt +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX.egg-info/entry_points.txt +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX.egg-info/requires.txt +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/FlashGBX.egg-info/top_level.txt +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/LICENSE +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/MANIFEST.in +0 -0
- {flashgbx-4.4 → flashgbx-4.6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# FlashGBX
|
|
3
|
-
# Author: Lesserkuma (github.com/
|
|
3
|
+
# Author: Lesserkuma (github.com/Lesserkuma)
|
|
4
4
|
|
|
5
5
|
import sys, os, glob, re, json, zlib, argparse, zipfile, traceback, platform, datetime, copy
|
|
6
6
|
from . import Util
|
|
@@ -88,7 +88,7 @@ def main(portableMode=False):
|
|
|
88
88
|
os.environ['QT_MAC_WANTS_LAYER'] = '1'
|
|
89
89
|
|
|
90
90
|
print("{:s} {:s} by Lesserkuma".format(Util.APPNAME, Util.VERSION))
|
|
91
|
-
print("https://github.com/
|
|
91
|
+
print("https://github.com/Lesserkuma/FlashGBX")
|
|
92
92
|
|
|
93
93
|
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
|
|
94
94
|
app_path = os.path.dirname(sys.executable)
|
|
@@ -139,6 +139,7 @@ def main(portableMode=False):
|
|
|
139
139
|
ap_cli2.add_argument("--agb-romsize", choices=["auto", "32kb", "64kb", "128kb", "256kb", "512kb", "1mb", "2mb", "4mb", "8mb", "16mb", "32mb", "64mb", "128mb", "256mb", "512mb"], type=str.lower, default="auto", help="set size of Game Boy Advance cartridge ROM data")
|
|
140
140
|
ap_cli2.add_argument("--agb-savetype", choices=["auto", "eeprom4k", "eeprom64k", "sram256k", "flash512k", "flash1m", "dacs8m", "sram512k", "sram1m"], type=str.lower, default="auto", help="set type of Game Boy Advance cartridge save data")
|
|
141
141
|
ap_cli2.add_argument("--store-rtc", action="store_true", default=False, help="store RTC register values if supported")
|
|
142
|
+
ap_cli2.add_argument("--keep-calibration", action="store_true", default=True, help="keep existing calibration data of the e-Reader when writing save data")
|
|
142
143
|
ap_cli2.add_argument("--ignore-bad-header", action="store_true", help="don’t stop if invalid data found in cartridge header data")
|
|
143
144
|
ap_cli2.add_argument("--flashcart-type", type=str, default="autodetect", help="name of flash cart; see txt files in config directory")
|
|
144
145
|
ap_cli2.add_argument("--prefer-chip-erase", action="store_true", help="prefer full chip erase over sector erase when both available")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# FlashGBX
|
|
3
|
-
# Author: Lesserkuma (github.com/
|
|
3
|
+
# Author: Lesserkuma (github.com/Lesserkuma)
|
|
4
4
|
|
|
5
5
|
import datetime, shutil, platform, os, math, traceback, re, time, serial, zipfile
|
|
6
6
|
try:
|
|
@@ -485,6 +485,9 @@ class FlashGBX_CLI():
|
|
|
485
485
|
bad_read = False
|
|
486
486
|
s = ""
|
|
487
487
|
if self.CONN.GetMode() == "DMG":
|
|
488
|
+
if data["db"]:
|
|
489
|
+
s += "Game Name: {:s}\n".format(os.path.splitext(Util.GenerateFileName(mode=self.CONN.GetMode(), header=self.CONN.INFO, settings=None))[0])
|
|
490
|
+
|
|
488
491
|
s += "Game Title: {:s}\n".format(data["game_title"])
|
|
489
492
|
if len(data['game_code']) > 0:
|
|
490
493
|
s += "Game Code: {:s}\n".format(data['game_code'])
|
|
@@ -554,6 +557,9 @@ class FlashGBX_CLI():
|
|
|
554
557
|
self.ARGS["argparsed"].flashcart_type = cart_types[0][i]
|
|
555
558
|
|
|
556
559
|
elif self.CONN.GetMode() == "AGB":
|
|
560
|
+
if data["db"]:
|
|
561
|
+
s += "Game Name: {:s}\n".format(os.path.splitext(Util.GenerateFileName(mode=self.CONN.GetMode(), header=self.CONN.INFO, settings=None))[0])
|
|
562
|
+
|
|
557
563
|
s += "Game Title: {:s}\n".format(data["game_title"])
|
|
558
564
|
s += "Game Code: {:s}\n".format(data["game_code"])
|
|
559
565
|
s += "Revision: {:d}\n".format(data["version"])
|
|
@@ -670,7 +676,10 @@ class FlashGBX_CLI():
|
|
|
670
676
|
elif self.CONN.GetMode() == "AGB":
|
|
671
677
|
temp = "{:s}".format(Util.AGB_Header_Save_Types[save_type])
|
|
672
678
|
if save_type == 0:
|
|
673
|
-
|
|
679
|
+
if "Unknown" in save_chip:
|
|
680
|
+
msg_save_type_s = "Save Type: {:s}\n".format(save_chip)
|
|
681
|
+
else:
|
|
682
|
+
msg_save_type_s = "Save Type: None or unknown (no save data detected)\n"
|
|
674
683
|
else:
|
|
675
684
|
if sram_unstable and "SRAM" in temp:
|
|
676
685
|
msg_save_type_s = "Save Type: {:s} {:s}(not battery-backed){:s}\n".format(temp, ANSI.RED, ANSI.RESET)
|
|
@@ -1160,7 +1169,7 @@ class FlashGBX_CLI():
|
|
|
1160
1169
|
if "ereader_calibration" in self.CONN.INFO:
|
|
1161
1170
|
with open(path, "rb") as f: buffer = bytearray(f.read())
|
|
1162
1171
|
if buffer[0xD000:0xF000] != self.CONN.INFO["ereader_calibration"]:
|
|
1163
|
-
if
|
|
1172
|
+
if args.keep_calibration:
|
|
1164
1173
|
if args.action == "erase-save": args.action = "restore-save"
|
|
1165
1174
|
print("Note: Keeping existing e-Reader calibration data.")
|
|
1166
1175
|
buffer[0xD000:0xF000] = self.CONN.INFO["ereader_calibration"]
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# FlashGBX
|
|
3
|
-
# Author: Lesserkuma (github.com/
|
|
3
|
+
# Author: Lesserkuma (github.com/Lesserkuma)
|
|
4
4
|
|
|
5
|
-
import sys, os, time, datetime, json, platform, subprocess, requests, webbrowser,
|
|
5
|
+
import sys, os, time, datetime, json, platform, subprocess, requests, webbrowser, threading, calendar, queue
|
|
6
6
|
from .pyside import QtCore, QtWidgets, QtGui, QApplication
|
|
7
7
|
from PIL.ImageQt import ImageQt
|
|
8
8
|
from PIL import Image
|
|
9
9
|
from serial import SerialException
|
|
10
|
+
from packaging import version
|
|
10
11
|
from .RomFileDMG import RomFileDMG
|
|
11
12
|
from .RomFileAGB import RomFileAGB
|
|
12
13
|
from .PocketCameraWindow import PocketCameraWindow
|
|
@@ -204,7 +205,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
204
205
|
self.mnuConfig.addAction("Use &No-Intro file names", lambda: self.SETTINGS.setValue("UseNoIntroFilenames", str(self.mnuConfig.actions()[7].isChecked()).lower().replace("true", "enabled").replace("false", "disabled")))
|
|
205
206
|
self.mnuConfig.addAction("Automatic cartridge &power off", lambda: [ self.SETTINGS.setValue("AutoPowerOff", str(self.mnuConfig.actions()[8].isChecked()).lower().replace("true", "350").replace("false", "0")), self.SetAutoPowerOff() ])
|
|
206
207
|
self.mnuConfig.addAction("Skip writing matching ROM chunk&s", lambda: self.SETTINGS.setValue("CompareSectors", str(self.mnuConfig.actions()[9].isChecked()).lower().replace("true", "enabled").replace("false", "disabled")))
|
|
207
|
-
self.mnuConfig.addAction("
|
|
208
|
+
self.mnuConfig.addAction("Alternate address set mode (can fix or cause write errors)", lambda: self.SETTINGS.setValue("ForceWrPullup", str(self.mnuConfig.actions()[10].isChecked()).lower().replace("true", "enabled").replace("false", "disabled")))
|
|
208
209
|
self.mnuConfig.addSeparator()
|
|
209
210
|
self.mnuConfigReadModeAGB = QtWidgets.QMenu("&Read Method (Game Boy Advance)")
|
|
210
211
|
self.mnuConfigReadModeAGB.addAction("S&tream", lambda: [ self.SETTINGS.setValue("AGBReadMethod", str(self.mnuConfigReadModeAGB.actions()[1].isChecked()).lower().replace("true", "2")), self.SetAGBReadMethod() ])
|
|
@@ -629,8 +630,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
629
630
|
self.SETTINGS.setValue("UpdateCheck", "disabled")
|
|
630
631
|
if update_check and update_check.lower() == "enabled":
|
|
631
632
|
print("")
|
|
632
|
-
url = "https://api.github.com/repos/
|
|
633
|
-
site = "https://github.com/
|
|
633
|
+
url = "https://api.github.com/repos/Lesserkuma/FlashGBX/releases/latest"
|
|
634
|
+
site = "https://github.com/Lesserkuma/FlashGBX/releases/latest"
|
|
634
635
|
try:
|
|
635
636
|
ret = requests.get(url, allow_redirects=True, timeout=1.5)
|
|
636
637
|
except requests.exceptions.ConnectTimeout as e:
|
|
@@ -648,9 +649,9 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
648
649
|
ret = json.loads(ret)
|
|
649
650
|
if 'tag_name' in ret:
|
|
650
651
|
latest_version = str(ret['tag_name'])
|
|
651
|
-
if
|
|
652
|
+
if version.parse(latest_version) == version.parse(VERSION_PEP440):
|
|
652
653
|
print("You are using the latest version of {:s}.".format(APPNAME))
|
|
653
|
-
elif
|
|
654
|
+
elif version.parse(latest_version) > version.parse(VERSION_PEP440):
|
|
654
655
|
msg_text = "A new version of {:s} has been released!\nVersion {:s} is now available.".format(APPNAME, latest_version)
|
|
655
656
|
print(msg_text)
|
|
656
657
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle="{:s} Update Check".format(APPNAME), text=msg_text)
|
|
@@ -725,14 +726,14 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
725
726
|
def AboutFlashGBX(self):
|
|
726
727
|
msg = "This software is being developed by Lesserkuma as a hobby project. There is no affiliation with Nintendo or any other company. This software is provided as-is and the developer is not responsible for any damage that is caused by the use of it. Use at your own risk!<br><br>"
|
|
727
728
|
msg += f"© 2020–{datetime.datetime.now().year} Lesserkuma<br>"
|
|
728
|
-
msg += "• Website: <a href=\"https://github.com/
|
|
729
|
-
msg += "Acknowledgments and Contributors:<br>2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, delibird_deals, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, Gahr, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, infinest, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, luxkiller65, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, Mufsta, olDirdey, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr"
|
|
729
|
+
msg += "• Website: <a href=\"https://github.com/Lesserkuma/FlashGBX\">https://github.com/Lesserkuma/FlashGBX</a><br><br>"
|
|
730
|
+
msg += "Acknowledgments and Contributors:<br>2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, delibird_deals, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, Gahr, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, infinest, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, luxkiller65, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, Mufsta, olDirdey, orangeglo, paarongiroux, Paradoxical, Pese, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr"
|
|
730
731
|
QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), msg, QtWidgets.QMessageBox.Ok)
|
|
731
732
|
|
|
732
733
|
def AboutGameDB(self):
|
|
733
734
|
msg = f"{APPNAME} uses a game database that is based on the ongoing efforts of the No-Intro project. Visit <a href=\"https://no-intro.org/\">https://no-intro.org/</a> for more information.<br><br>"
|
|
734
735
|
msg += f"No-Intro databases referenced for this version of {APPNAME}:<br>"
|
|
735
|
-
msg += "• Nintendo - Game Boy (
|
|
736
|
+
msg += "• Nintendo - Game Boy (20260113-102506)<br>• Nintendo - Game Boy Advance (20260124-113814)<br>• Nintendo - Game Boy Advance (Video) (20251114-101831)<br>• Nintendo - Game Boy Color (20260110-131928)" # No-Intro DBs
|
|
736
737
|
QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), msg, QtWidgets.QMessageBox.Ok)
|
|
737
738
|
|
|
738
739
|
def OpenPath(self, path=None):
|
|
@@ -887,7 +888,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
887
888
|
text = "A firmware update for your {:s} device is required to use this software. Do you want to update now?".format(dev.GetFullName())
|
|
888
889
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text=text, standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, defaultButton=QtWidgets.QMessageBox.Yes)
|
|
889
890
|
elif dev.FW_UPDATE_REQ == 2:
|
|
890
|
-
text = "Your {:s} device is no longer supported in this version of FlashGBX due to technical limitations. The last supported version is <a href=\"https://github.com/
|
|
891
|
+
text = "Your {:s} device is no longer supported in this version of FlashGBX due to technical limitations. The last supported version is <a href=\"https://github.com/Lesserkuma/FlashGBX/releases/tag/3.37\">FlashGBX v3.37</a>.\n\nYou can still use the Firmware Updater, however any other functions are no longer available.\n\nDo you want to run the Firmware Updater now?".format(dev.GetFullName()).replace("\n", "<br>")
|
|
891
892
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text=text, standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, defaultButton=QtWidgets.QMessageBox.Yes)
|
|
892
893
|
else:
|
|
893
894
|
text = "A firmware update for your {:s} device is available. Do you want to update now?".format(dev.GetFullName())
|
|
@@ -988,7 +989,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
988
989
|
"- Check if the operating system detects the device (if not, reboot your machine)\n" \
|
|
989
990
|
"- Update the firmware through Options → Tools → Firmware Updater"
|
|
990
991
|
if platform.system() == "Darwin":
|
|
991
|
-
msg += "\n - <b>For Joey Jr on macOS:</b> Use the dedicated <a href=\"https://github.com/
|
|
992
|
+
msg += "\n - <b>For Joey Jr on macOS:</b> Use the dedicated <a href=\"https://github.com/Lesserkuma/JoeyJr_FWUpdater\">Firmware Updater for Joey Jr</a>"
|
|
992
993
|
elif platform.system() == "Linux":
|
|
993
994
|
msg += "\n- <b>For Linux users:</b> Ensure your user account has permissions to use the device (try adding yourself to user groups “dialout” or “uucp”)"
|
|
994
995
|
|
|
@@ -2273,11 +2274,11 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2273
2274
|
detected = False
|
|
2274
2275
|
if detected is False:
|
|
2275
2276
|
intro_msg = "In order to access Batteryless SRAM save data, its ROM location and size must be specified.\n\n"
|
|
2276
|
-
if mode == "AGB":
|
|
2277
|
-
|
|
2278
|
-
elif mode == "DMG":
|
|
2279
|
-
|
|
2280
|
-
intro_msg2 = "⚠️ The required parameters could not be auto-detected. Please enter the ROM location and size manually below. Note that wrong values can corrupt your game upon writing, so having a full
|
|
2277
|
+
# if mode == "AGB":
|
|
2278
|
+
# max_size = self.cmbAGBHeaderROMSizeResult.currentText().replace(" ", " ")
|
|
2279
|
+
# elif mode == "DMG":
|
|
2280
|
+
# max_size = self.cmbDMGHeaderROMSizeResult.currentText().replace(" ", " ")
|
|
2281
|
+
intro_msg2 = "⚠️ The required parameters could not be auto-detected. Please enter the ROM location and size manually below. Note that wrong values can corrupt your game upon writing, so having a full ROM backup is recommended."
|
|
2281
2282
|
|
|
2282
2283
|
if mode == "DMG":
|
|
2283
2284
|
# Load database of observed configurations from various bootlegs
|
|
@@ -2600,7 +2601,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2600
2601
|
self.CONN.SetMode("DMG")
|
|
2601
2602
|
elif self.optAGB.isChecked() and (mode == "DMG" or mode == None):
|
|
2602
2603
|
self.CONN.SetMode("AGB")
|
|
2603
|
-
except BrokenPipeError:
|
|
2604
|
+
except (BrokenPipeError, SerialException):
|
|
2604
2605
|
msg = "Failed to turn on the cartridge power.\n\nThe “Automatic cartridge power off” setting has therefore been disabled. Please re-connect the device and try again."
|
|
2605
2606
|
self.mnuConfig.actions()[5].setChecked(False)
|
|
2606
2607
|
self.SETTINGS.setValue("AutoPowerOff", "0")
|
|
@@ -2635,7 +2636,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
2635
2636
|
|
|
2636
2637
|
try:
|
|
2637
2638
|
data = self.CONN.ReadInfo(setPinsAsInputs=True)
|
|
2638
|
-
except SerialException:
|
|
2639
|
+
except (BrokenPipeError, SerialException):
|
|
2639
2640
|
self.LimitBaudRateGBxCartRW()
|
|
2640
2641
|
self.DisconnectDevice()
|
|
2641
2642
|
QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "The connection to the device was lost while trying to read the ROM header. This may happen if the inserted cartridge issues a short circuit or its peak power draw is too high.\n\nAs a potential workaround for the latter, you can try hotswapping the cartridge:\n1. Remove the cartridge from the device.\n2. Reconnect the device and select mode.\n3. Then insert the cartridge and click “{:s}”.".format(self.btnHeaderRefresh.text().replace("&", "")), QtWidgets.QMessageBox.Ok)
|
|
@@ -3047,7 +3048,10 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
3047
3048
|
pass
|
|
3048
3049
|
|
|
3049
3050
|
if save_type == 0:
|
|
3050
|
-
|
|
3051
|
+
if "Unknown" in save_chip:
|
|
3052
|
+
msg_save_type_s = "<b>Save Type:</b> {:s}<br>".format(save_chip)
|
|
3053
|
+
else:
|
|
3054
|
+
msg_save_type_s = "<b>Save Type:</b> None or unknown (no save data detected)<br>"
|
|
3051
3055
|
else:
|
|
3052
3056
|
if sram_unstable and "SRAM" in temp:
|
|
3053
3057
|
msg_save_type_s = "<b>Save Type:</b> {:s} <span style=\"color: red;\">(not stable or not battery-backed)</span><br>".format(temp)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# FlashGBX
|
|
3
|
-
# Author: Lesserkuma (github.com/
|
|
3
|
+
# Author: Lesserkuma (github.com/Lesserkuma)
|
|
4
4
|
|
|
5
5
|
import time, math, struct, traceback, zlib, copy, hashlib, os, datetime, platform, json, base64
|
|
6
6
|
import serial, serial.tools.list_ports
|
|
@@ -147,6 +147,7 @@ class LK_Device(ABC):
|
|
|
147
147
|
AGB_READ_METHODS = ["Single", "MemCpy", "Stream"]
|
|
148
148
|
LAST_CHECK_ACTIVE = 0
|
|
149
149
|
USER_ANSWER = None
|
|
150
|
+
SKIP_POWERCYCLE = False
|
|
150
151
|
|
|
151
152
|
def __init__(self):
|
|
152
153
|
pass
|
|
@@ -721,7 +722,7 @@ class LK_Device(ABC):
|
|
|
721
722
|
continue
|
|
722
723
|
|
|
723
724
|
def CartPowerCycle(self, delay=0.1):
|
|
724
|
-
if self.CanPowerCycleCart():
|
|
725
|
+
if self.CanPowerCycleCart() and not self.SKIP_POWERCYCLE:
|
|
725
726
|
dprint("Power cycling cartridge with a delay of {:.1f} seconds".format(delay))
|
|
726
727
|
self.CartPowerOff(delay=delay)
|
|
727
728
|
self.CartPowerOn(delay=delay)
|
|
@@ -868,6 +869,7 @@ class LK_Device(ABC):
|
|
|
868
869
|
dprint(f"Setting automatic power off time value to {value}")
|
|
869
870
|
self._set_fw_variable("AUTO_POWEROFF_TIME", value)
|
|
870
871
|
self._set_fw_variable("AUTO_POWEROFF_ENABLED", 1 if value != 0 else 0)
|
|
872
|
+
self.SKIP_POWERCYCLE = False if value != 0 else True
|
|
871
873
|
|
|
872
874
|
def GetSupportedCartridgesDMG(self):
|
|
873
875
|
return (list(self.SUPPORTED_CARTS['DMG'].keys()), list(self.SUPPORTED_CARTS['DMG'].values()))
|
|
@@ -1104,7 +1106,7 @@ class LK_Device(ABC):
|
|
|
1104
1106
|
if self.MODE == "DMG": #and setPinsAsInputs:
|
|
1105
1107
|
self._write(self.DEVICE_CMD["SET_ADDR_AS_INPUTS"], wait=self.FW["fw_ver"] >= 12)
|
|
1106
1108
|
|
|
1107
|
-
self.Debug()
|
|
1109
|
+
#self.Debug()
|
|
1108
1110
|
return data
|
|
1109
1111
|
|
|
1110
1112
|
def _DetectCartridge(self, args): # Wrapper for thread call
|
|
@@ -1140,7 +1142,7 @@ class LK_Device(ABC):
|
|
|
1140
1142
|
|
|
1141
1143
|
# Disable Auto Power Off
|
|
1142
1144
|
_apoe = False
|
|
1143
|
-
if self.FW["fw_ver"] >= 12:
|
|
1145
|
+
if self.FW["fw_ver"] >= 12 and self.SKIP_POWERCYCLE is False:
|
|
1144
1146
|
if self.CanPowerCycleCart():
|
|
1145
1147
|
self.CartPowerCycle()
|
|
1146
1148
|
_apoe = self._get_fw_variable("AUTO_POWEROFF_ENABLED") == 1
|
|
@@ -1262,21 +1264,25 @@ class LK_Device(ABC):
|
|
|
1262
1264
|
if ret is not False:
|
|
1263
1265
|
(flash_save_id, _) = ret
|
|
1264
1266
|
try:
|
|
1265
|
-
if flash_save_id != 0
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1267
|
+
if flash_save_id != 0:
|
|
1268
|
+
if flash_save_id in Util.AGB_Flash_Save_Chips:
|
|
1269
|
+
save_size = Util.AGB_Flash_Save_Chips_Sizes[list(Util.AGB_Flash_Save_Chips).index(flash_save_id)]
|
|
1270
|
+
save_chip = Util.AGB_Flash_Save_Chips[flash_save_id]
|
|
1271
|
+
if flash_save_id in (0xBF4B, 0xBF5B, 0xFFFF, 0xBF6D): # Bootlegs
|
|
1272
|
+
if self.INFO["data"][0:0x20000] == bytearray([0xFF] * 0x20000):
|
|
1273
|
+
save_type = 5
|
|
1274
|
+
elif self.INFO["data"][0:0x10000] == self.INFO["data"][0x10000:0x20000]:
|
|
1275
|
+
save_type = 4
|
|
1276
|
+
else:
|
|
1277
|
+
save_type = 5
|
|
1278
|
+
elif save_size == 131072:
|
|
1271
1279
|
save_type = 5
|
|
1272
|
-
elif
|
|
1280
|
+
elif save_size == 65536:
|
|
1273
1281
|
save_type = 4
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
elif save_size == 65536:
|
|
1279
|
-
save_type = 4
|
|
1282
|
+
else: # Other bootleg chips
|
|
1283
|
+
save_type = 0
|
|
1284
|
+
save_size = 0
|
|
1285
|
+
save_chip = f"Unknown FLASH save chip (0x{flash_save_id:04X})"
|
|
1280
1286
|
except:
|
|
1281
1287
|
pass
|
|
1282
1288
|
|
|
@@ -1332,7 +1338,7 @@ class LK_Device(ABC):
|
|
|
1332
1338
|
self.INFO["last_action"] = 0
|
|
1333
1339
|
self.INFO["action"] = None
|
|
1334
1340
|
|
|
1335
|
-
if self.CanPowerCycleCart() and _apoe is True:
|
|
1341
|
+
if self.CanPowerCycleCart() and _apoe is True and self.SKIP_POWERCYCLE is False:
|
|
1336
1342
|
self._set_fw_variable("AUTO_POWEROFF_TIME", _apot)
|
|
1337
1343
|
|
|
1338
1344
|
return (info, save_size, save_type, save_chip, sram_unstable, cart_types, cart_type_id, cfi_s, cfi, flash_id, detected_size)
|
|
@@ -2882,6 +2888,7 @@ class LK_Device(ABC):
|
|
|
2882
2888
|
|
|
2883
2889
|
# Calculate Global Checksum
|
|
2884
2890
|
if self.MODE == "DMG":
|
|
2891
|
+
self.INFO["dump_info"]["header"].update(RomFileDMG(buffer[:0x180]).GetHeader(unchanged=True))
|
|
2885
2892
|
if _mbc.GetName() == "MMM01":
|
|
2886
2893
|
self.INFO["dump_info"]["header"].update(RomFileDMG(buffer[-0x8000:-0x8000+0x180]).GetHeader(unchanged=True))
|
|
2887
2894
|
elif _mbc.GetName() == "Sachen":
|
|
@@ -3118,8 +3125,10 @@ class LK_Device(ABC):
|
|
|
3118
3125
|
return False
|
|
3119
3126
|
buffer_len = 0x1000
|
|
3120
3127
|
(agb_flash_chip, _) = ret
|
|
3121
|
-
if agb_flash_chip in (0xBF5B, 0xFFFF): # Bootlegs
|
|
3128
|
+
if agb_flash_chip in (0xBF4B, 0xBF5B, 0xFFFF): # Bootlegs
|
|
3122
3129
|
buffer_len = 0x800
|
|
3130
|
+
elif agb_flash_chip == 0xBF6D:
|
|
3131
|
+
buffer_len = 0x8000
|
|
3123
3132
|
elif args["save_type"] == 6: # DACS
|
|
3124
3133
|
# self._write(self.DEVICE_CMD["AGB_BOOTUP_SEQUENCE"], wait=self.FW["fw_ver"] >= 12)
|
|
3125
3134
|
empty_data_byte = 0xFF
|
|
@@ -3255,7 +3264,7 @@ class LK_Device(ABC):
|
|
|
3255
3264
|
end_address = min(save_size, bank_size)
|
|
3256
3265
|
|
|
3257
3266
|
if save_size > bank_size:
|
|
3258
|
-
if args["save_type"] == 8 or agb_flash_chip in (0xBF5B, 0xFFFF): # Bootleg 1M
|
|
3267
|
+
if args["save_type"] == 8 or agb_flash_chip in (0xBF4B, 0xBF5B, 0xFFFF, 0xBF6D): # Bootleg 1M
|
|
3259
3268
|
dprint("Switching to bootleg save bank {:d}".format(bank))
|
|
3260
3269
|
self._cart_write(0x1000000, bank)
|
|
3261
3270
|
elif args["save_type"] == 5: # FLASH 1M
|
|
@@ -3563,7 +3572,7 @@ class LK_Device(ABC):
|
|
|
3563
3572
|
buffer[0xFF80:0x10000] = self.INFO["data"][0xFF80:0x10000]
|
|
3564
3573
|
buffer[0x1FF80:0x20000] = self.INFO["data"][0xFF80:0x10000]
|
|
3565
3574
|
|
|
3566
|
-
|
|
3575
|
+
if (self.INFO["data"][:end_address] != buffer[:end_address]):
|
|
3567
3576
|
msg = ""
|
|
3568
3577
|
count = 0
|
|
3569
3578
|
time_start = time.time()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# FlashGBX
|
|
3
|
-
# Author: Lesserkuma (github.com/
|
|
3
|
+
# Author: Lesserkuma (github.com/Lesserkuma)
|
|
4
4
|
|
|
5
5
|
import time, datetime, struct, math, hashlib
|
|
6
6
|
from dateutil.relativedelta import relativedelta
|
|
@@ -260,13 +260,6 @@ class DMG_MBC3(DMG_MBC):
|
|
|
260
260
|
def GetName(self):
|
|
261
261
|
return "MBC3"
|
|
262
262
|
|
|
263
|
-
def EnableRAM(self, enable=True):
|
|
264
|
-
dprint(self.GetName(), "|", enable)
|
|
265
|
-
commands = [
|
|
266
|
-
[ 0x0000, 0x0A if enable else 0x00 ],
|
|
267
|
-
]
|
|
268
|
-
self.CartWrite(commands)
|
|
269
|
-
|
|
270
263
|
def HasRTC(self):
|
|
271
264
|
dprint("Checking for RTC")
|
|
272
265
|
if self.MBC_ID not in (0x0F, 0x10, 0x110, 0x206):
|
|
@@ -472,20 +465,6 @@ class DMG_MBC5(DMG_MBC):
|
|
|
472
465
|
def GetName(self):
|
|
473
466
|
return "MBC5"
|
|
474
467
|
|
|
475
|
-
def EnableRAM(self, enable=True):
|
|
476
|
-
dprint(self.GetName(), "|", enable)
|
|
477
|
-
if enable:
|
|
478
|
-
commands = [
|
|
479
|
-
[ 0x6000, 0x01 ],
|
|
480
|
-
[ 0x0000, 0x0A ],
|
|
481
|
-
]
|
|
482
|
-
else:
|
|
483
|
-
commands = [
|
|
484
|
-
[ 0x0000, 0x00 ],
|
|
485
|
-
[ 0x6000, 0x00 ],
|
|
486
|
-
]
|
|
487
|
-
self.CartWrite(commands)
|
|
488
|
-
|
|
489
468
|
def SelectBankROM(self, index):
|
|
490
469
|
dprint(self.GetName(), "|", index)
|
|
491
470
|
|
|
@@ -701,7 +680,7 @@ class DMG_MMM01(DMG_MBC):
|
|
|
701
680
|
class DMG_GBD(DMG_MBC5):
|
|
702
681
|
def GetName(self):
|
|
703
682
|
return "MAC-GBD"
|
|
704
|
-
|
|
683
|
+
|
|
705
684
|
def SelectBankROM(self, index):
|
|
706
685
|
dprint(self.GetName(), "|", index)
|
|
707
686
|
commands = [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# FlashGBX
|
|
3
|
-
# Author: Lesserkuma (github.com/
|
|
3
|
+
# Author: Lesserkuma (github.com/Lesserkuma)
|
|
4
4
|
|
|
5
5
|
import math, time, datetime, copy, configparser, threading, os, platform, traceback, io, struct, re, statistics, random, sys
|
|
6
6
|
from io import StringIO
|
|
@@ -8,9 +8,9 @@ from enum import Enum
|
|
|
8
8
|
|
|
9
9
|
# Common constants
|
|
10
10
|
APPNAME = "FlashGBX"
|
|
11
|
-
VERSION_PEP440 = "4.
|
|
11
|
+
VERSION_PEP440 = "4.6"
|
|
12
12
|
VERSION = "v{:s}".format(VERSION_PEP440)
|
|
13
|
-
VERSION_TIMESTAMP =
|
|
13
|
+
VERSION_TIMESTAMP = 1769513530
|
|
14
14
|
DEBUG = False
|
|
15
15
|
DEBUG_LOG = []
|
|
16
16
|
APP_PATH = ""
|
|
@@ -20,8 +20,8 @@ AGB_Header_ROM_Sizes = [ "32 KiB", "64 KiB", "128 KiB", "256 KiB", "512 KiB", "1
|
|
|
20
20
|
AGB_Header_ROM_Sizes_Map = [ 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000 ]
|
|
21
21
|
AGB_Header_Save_Types = [ "None", "4K EEPROM (512 Bytes)", "64K EEPROM (8 KiB)", "256K SRAM/FRAM (32 KiB)", "512K FLASH (64 KiB)", "1M FLASH (128 KiB)", "8M DACS (1 MiB)", "Unlicensed 512K SRAM (64 KiB)", "Unlicensed 1M SRAM (128 KiB)", "Unlicensed Batteryless SRAM" ]
|
|
22
22
|
AGB_Header_Save_Sizes = [ 0, 512, 8192, 32768, 65536, 131072, 1048576, 65536, 131072, 0 ]
|
|
23
|
-
AGB_Flash_Save_Chips = { 0xBFD4:"SST 39VF512", 0x1F3D:"Atmel AT29LV512", 0xC21C:"Macronix MX29L512", 0x321B:"Panasonic MN63F805MNP", 0xC209:"Macronix MX29L010", 0x6213:"SANYO LE26FV10N1TS", 0xBF5B:"Unlicensed SST49LF080A", 0xFFFF:"Unlicensed 0xFFFF" }
|
|
24
|
-
AGB_Flash_Save_Chips_Sizes = [ 0x10000, 0x10000, 0x10000, 0x10000, 0x20000, 0x20000, 0x20000, 0x20000 ]
|
|
23
|
+
AGB_Flash_Save_Chips = { 0xBFD4:"SST 39VF512", 0x1F3D:"Atmel AT29LV512", 0xC21C:"Macronix MX29L512", 0x321B:"Panasonic MN63F805MNP", 0xC209:"Macronix MX29L010", 0x6213:"SANYO LE26FV10N1TS", 0xBF4B:"Unlicensed SST25VF064C", 0xBF5B:"Unlicensed SST49LF080A", 0xBF6D:"Unlicensed SST39VF6401B", 0xFFFF:"Unlicensed 0xFFFF" }
|
|
24
|
+
AGB_Flash_Save_Chips_Sizes = [ 0x10000, 0x10000, 0x10000, 0x10000, 0x20000, 0x20000, 0x20000, 0x20000, 0x20000, 0x20000 ]
|
|
25
25
|
|
|
26
26
|
DMG_Header_Mapper = { 0x00:'None', 0x01:'MBC1', 0x02:'MBC1+SRAM', 0x03:'MBC1+SRAM+BATTERY', 0x06:'MBC2+SRAM+BATTERY', 0x0F:'MBC3+RTC+BATTERY', 0x10:'MBC3+RTC+SRAM+BATTERY', 0x110:'MBC30+RTC+SRAM+BATTERY', 0x12:'MBC3+SRAM', 0x13:'MBC3+SRAM+BATTERY', 0x19:'MBC5', 0x1A:'MBC5+SRAM', 0x1B:'MBC5+SRAM+BATTERY', 0x1C:'MBC5+RUMBLE', 0x1E:'MBC5+RUMBLE+SRAM+BATTERY', 0x20:'MBC6+SRAM+FLASH+BATTERY', 0x22:'MBC7+ACCELEROMETER+EEPROM', 0x101:'MBC1M', 0x103:'MBC1M+SRAM+BATTERY', 0x0B:'MMM01', 0x0D:'MMM01+SRAM+BATTERY', 0xFC:'MAC-GBD+SRAM+BATTERY', 0x105:'G-MMC1+SRAM+BATTERY', 0x104:'M161', 0xFF:'HuC-1+IR+SRAM+BATTERY', 0xFE:'HuC-3+RTC+SRAM+BATTERY', 0xFD:'TAMA5+RTC+EEPROM', 0x201:'Unlicensed 256M Mapper', 0x202:'Unlicensed Wisdom Tree Mapper', 0x203:'Unlicensed Xploder GB Mapper', 0x204:'Unlicensed Sachen Mapper', 0x205:'Unlicensed Datel Orbit V2 Mapper', 0x206:'Unlicensed MBCX Mapper' }
|
|
27
27
|
DMG_Mapper_Types = { "None":[ 0x00, 0x08, 0x09 ], "MBC1":[ 0x01, 0x02, 0x03 ], "MBC2":[ 0x05, 0x06 ], "MBC3":[ 0x0F, 0x10, 0x11, 0x12, 0x13 ], "MBC30":[ 0x110 ], "MBC5":[ 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E ], "MBC6":[ 0x20 ], "MBC7":[ 0x22 ], "MBC1M":[ 0x101, 0x103 ], "MMM01":[ 0x0B, 0x0D ], "MAC-GBD":[ 0xFC ], "G-MMC1":[ 0x105 ], "M161":[ 0x104 ], "HuC-1":[ 0xFF ], "HuC-3":[ 0xFE ], "TAMA5":[ 0xFD ], "Unlicensed 256M Multi Cart Mapper":[ 0x201 ], "Unlicensed Wisdom Tree Mapper":[ 0x202 ], "Unlicensed Xploder GB Mapper":[ 0x203 ], "Unlicensed Sachen Mapper":[ 0x204 ], "Unlicensed Datel Orbit V2 Mapper":[ 0x205 ], "Unlicensed MBCX Mapper":[ 0x206 ] }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# FlashGBX
|
|
3
|
-
# Author: Lesserkuma (github.com/
|
|
3
|
+
# Author: Lesserkuma (github.com/Lesserkuma)
|
|
4
4
|
|
|
5
5
|
import zipfile, serial, struct, time, datetime
|
|
6
6
|
try:
|
|
@@ -36,7 +36,11 @@ class FirmwareUpdater():
|
|
|
36
36
|
values = struct.unpack(">IBHHH", self.DEVICE.read(11))
|
|
37
37
|
data = dict(zip(keys, values))
|
|
38
38
|
data["payload"] = self.DEVICE.read(data["payload_len"])
|
|
39
|
-
|
|
39
|
+
try:
|
|
40
|
+
data["outro"] = self.DEVICE.read(4)
|
|
41
|
+
data["outro"] = struct.unpack(">I", data["outro"])[0]
|
|
42
|
+
except struct.error:
|
|
43
|
+
return {"clone":True, "error": "Erroneous outro response: " + ''.join(format(x, '02X') for x in data["outro"])}
|
|
40
44
|
return data
|
|
41
45
|
|
|
42
46
|
def CRC16(self, data):
|
|
@@ -87,6 +91,9 @@ class FirmwareUpdater():
|
|
|
87
91
|
if data is None:
|
|
88
92
|
self.DEVICE = None
|
|
89
93
|
return False
|
|
94
|
+
if "error" in data:
|
|
95
|
+
self.DEVICE = None
|
|
96
|
+
return data
|
|
90
97
|
if data["seq_no"] != seq_no:
|
|
91
98
|
self.DEVICE = None
|
|
92
99
|
return False
|
|
@@ -120,6 +127,9 @@ class FirmwareUpdater():
|
|
|
120
127
|
else:
|
|
121
128
|
data = self.TryConnect(self.PORT)
|
|
122
129
|
|
|
130
|
+
if "error" in data:
|
|
131
|
+
fncSetStatus(text=data["error"], cloneError="clone" in data and data["clone"] is True)
|
|
132
|
+
return 2
|
|
123
133
|
if self.DEVICE is None:
|
|
124
134
|
fncSetStatus("No device found.")
|
|
125
135
|
return 2
|
|
@@ -409,8 +419,15 @@ try:
|
|
|
409
419
|
answer = msgbox.exec()
|
|
410
420
|
return False
|
|
411
421
|
|
|
412
|
-
def SetStatus(self, text, enableUI=False, setProgress=None):
|
|
422
|
+
def SetStatus(self, text, enableUI=False, setProgress=None, cloneError=False):
|
|
413
423
|
self.lblStatus.setText("Status: {:s}".format(text))
|
|
424
|
+
|
|
425
|
+
if cloneError:
|
|
426
|
+
text = "Your GBFlash device reported a registration error, which means it may be an illegitimate clone. If the error persists, try to get a refund from the seller.\r\n\r\n" + text
|
|
427
|
+
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok)
|
|
428
|
+
answer = msgbox.exec()
|
|
429
|
+
return False
|
|
430
|
+
|
|
414
431
|
if setProgress is not None:
|
|
415
432
|
self.prgStatus.setValue(setProgress * 10)
|
|
416
433
|
if enableUI:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# FlashGBX
|
|
3
|
-
# Author: Lesserkuma (github.com/
|
|
3
|
+
# Author: Lesserkuma (github.com/Lesserkuma)
|
|
4
4
|
|
|
5
5
|
import zipfile, time, os, struct, serial, platform
|
|
6
6
|
from serial import SerialException
|
|
@@ -422,7 +422,7 @@ try:
|
|
|
422
422
|
verified = False
|
|
423
423
|
|
|
424
424
|
if verified is False:
|
|
425
|
-
text = "The firmware update file is corrupted."
|
|
425
|
+
text = "The firmware update file is corrupted or invalid."
|
|
426
426
|
self.btnUpdate.setEnabled(True)
|
|
427
427
|
self.btnClose.setEnabled(True)
|
|
428
428
|
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: FlashGBX
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.6
|
|
4
4
|
Summary: Reads and writes Game Boy and Game Boy Advance cartridge data
|
|
5
|
-
Home-page: https://github.com/
|
|
5
|
+
Home-page: https://github.com/Lesserkuma/FlashGBX
|
|
6
6
|
Author: Lesserkuma
|
|
7
|
-
Project-URL: Source, https://github.com/
|
|
8
|
-
Project-URL: Tracker, https://github.com/
|
|
7
|
+
Project-URL: Source, https://github.com/Lesserkuma/FlashGBX/
|
|
8
|
+
Project-URL: Tracker, https://github.com/Lesserkuma/FlashGBX/issues
|
|
9
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Environment :: X11 Applications :: Qt
|
|
11
11
|
Classifier: Topic :: Terminals :: Serial
|
|
@@ -31,6 +31,7 @@ Dynamic: classifier
|
|
|
31
31
|
Dynamic: description
|
|
32
32
|
Dynamic: description-content-type
|
|
33
33
|
Dynamic: home-page
|
|
34
|
+
Dynamic: license-file
|
|
34
35
|
Dynamic: project-url
|
|
35
36
|
Dynamic: provides-extra
|
|
36
37
|
Dynamic: requires-dist
|
|
@@ -39,9 +40,9 @@ Dynamic: summary
|
|
|
39
40
|
|
|
40
41
|
# FlashGBX (by Lesserkuma)
|
|
41
42
|
|
|
42
|
-
for Windows, Linux, macOS (→ [Download](https://github.com/
|
|
43
|
+
for Windows, Linux, macOS (→ [Download](https://github.com/Lesserkuma/FlashGBX/releases))
|
|
43
44
|
|
|
44
|
-
<img src="https://raw.githubusercontent.com/
|
|
45
|
+
<img src="https://raw.githubusercontent.com/Lesserkuma/FlashGBX/master/.github/01.png" alt="FlashGBX on Windows 11" width="500"><br><img src="https://raw.githubusercontent.com/Lesserkuma/FlashGBX/master/.github/02.png" alt="GB Camera Album Viewer" width="500">
|
|
45
46
|
|
|
46
47
|
## Introduction
|
|
47
48
|
|
|
@@ -126,6 +127,7 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
126
127
|
- Ferrante Crafts cart 64 KB
|
|
127
128
|
- Ferrante Crafts cart 512 KB
|
|
128
129
|
- FunnyPlaying MidnightTrace 4 MiB Flash Cart
|
|
130
|
+
- Gamebank-web DMG-29W-04 with M29W320DB
|
|
129
131
|
- Gamebank-web DMG-29W-04 with M29W320EB
|
|
130
132
|
- Gamebank-web DMG-29W-04 with M29W320ET
|
|
131
133
|
- GameShark Pro
|
|
@@ -147,6 +149,7 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
147
149
|
- insideGadgets 4 MiB (2× 2 MiB), 32 KiB FRAM, MBC5
|
|
148
150
|
- insideGadgets MegaDuck 32K
|
|
149
151
|
- ModRetro Chromatic Cartridge with 39VF1681
|
|
152
|
+
- ModRetro Chromatic Cartridge with IS29GL032
|
|
150
153
|
- Mr Flash 64M
|
|
151
154
|
- Sillyhatday MBC5-DUAL-FLASH-4/8MB
|
|
152
155
|
- Squareboi 4 MiB (2× 2 MiB)
|
|
@@ -224,6 +227,7 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
224
227
|
- SD007_BV5_V3 with AM29LV160MB
|
|
225
228
|
- SD007_K8D3216_32M with MX29LV160CT
|
|
226
229
|
- SD007_T40_48BALL_71_TV_TS28 with M29W640
|
|
230
|
+
- SD007_T40_6401B\*CD_71_TS28 with 39VF6401B
|
|
227
231
|
- SD007_T40_64BALL_S71_TV_TS28 with TC58FVB016FT-85
|
|
228
232
|
- SD007_T40_64BALL_SOJ28 with 29LV016T
|
|
229
233
|
- SD007_T40_64BALL_TSOP28 with 29LV016T
|
|
@@ -315,6 +319,8 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
315
319
|
- M6MGJ927 (no PCB text)
|
|
316
320
|
- MSP54LV512 (no PCB text)
|
|
317
321
|
- MX29GL128EHT2I and ALTERA CPLD
|
|
322
|
+
- MXP54_16D_046 with MSP54LV256
|
|
323
|
+
- MXP54_16D_ERATH with MSP54LV256
|
|
318
324
|
- SUN100S_MSP54XXX with MSP54LV100
|
|
319
325
|
- Unknown 29LV320 variant (no PCB text)
|
|
320
326
|
|
|
@@ -326,19 +332,20 @@ Many different reproduction cartridges share their flash chip command set, so ev
|
|
|
326
332
|
|
|
327
333
|
### Pre-compiled binaries and packages
|
|
328
334
|
|
|
329
|
-
Available in the GitHub [Releases](https://github.com/
|
|
335
|
+
Available in the GitHub [Releases](https://github.com/Lesserkuma/FlashGBX/releases) section are pre-compiled downloads available for:
|
|
330
336
|
|
|
331
337
|
* **Windows (64-bit)** *(Windows 8 or newer)*
|
|
332
338
|
* Setup: An installer that will add the application to the start menu and optionally create a desktop icon
|
|
333
339
|
* Portable: Have everything in one place including the config files
|
|
334
340
|
|
|
335
341
|
* **Linux**
|
|
336
|
-
*
|
|
342
|
+
* Ubuntu (.deb file): Install using `dpkg -i /path/to/FlashGBX_x.x_Ubuntu-all.deb`.
|
|
343
|
+
* Other distributions: Pre-made Linux packages are available at [JJ-Fox’s repository](https://github.com/JJ-Fox/FlashGBX-Linux-builds/releases/latest).
|
|
337
344
|
|
|
338
|
-
* **macOS** *(
|
|
339
|
-
* x86-64/arm64 (.dmg file): Install by opening the .dmg file and copying over the “FlashGBX” application to the desktop.<br>If it doesn’t run, it probably got quarantined
|
|
345
|
+
* **macOS** *(Sequoia 15 or newer)*
|
|
346
|
+
* x86-64/arm64 (.dmg file): Install by opening the .dmg file and copying over the “FlashGBX” application to the desktop.<br>If it doesn’t run, it probably got quarantined due to the lack of a Apple Developer Program certificate. Right-click the extracted FlashGBX icon, choose “Open Terminal at Folder” and enter this command to unquarantine it: `xattr -d com.apple.quarantine ../FlashGBX.app`.
|
|
340
347
|
|
|
341
|
-
*(If you have a Joey Jr and use macOS, please run the [Joey Jr Firmware Updater](https://github.com/
|
|
348
|
+
*(If you have a Joey Jr and use macOS, please run the [Joey Jr Firmware Updater](https://github.com/Lesserkuma/JoeyJr_FWUpdater) before using FlashGBX.)*
|
|
342
349
|
|
|
343
350
|
### Run via Python
|
|
344
351
|
|
|
@@ -418,13 +425,13 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
|
|
418
425
|
|
|
419
426
|
The author would like to thank the following very kind people for their help, contributions or documentation (in alphabetical order):
|
|
420
427
|
|
|
421
|
-
2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, delibird_deals, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, Gahr, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, infinest, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, luxkiller65, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, Mufsta, olDirdey, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr
|
|
428
|
+
2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, delibird_deals, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, Gahr, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, infinest, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, luxkiller65, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, Mufsta, olDirdey, orangeglo, paarongiroux, Paradoxical, Pese, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr
|
|
422
429
|
|
|
423
430
|
Thanks to the No-Intro project for their game databases which FlashGBX’s databases are partly based on.
|
|
424
431
|
|
|
425
432
|
## Third Party Notices and Licenses
|
|
426
433
|
|
|
427
|
-
Please view the <a href="https://github.com/
|
|
434
|
+
Please view the <a href="https://github.com/Lesserkuma/FlashGBX/blob/master/Third%20Party%20Notices.md">Third Party Notices</a>.
|
|
428
435
|
|
|
429
436
|
## DISCLAIMER
|
|
430
437
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: FlashGBX
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.6
|
|
4
4
|
Summary: Reads and writes Game Boy and Game Boy Advance cartridge data
|
|
5
|
-
Home-page: https://github.com/
|
|
5
|
+
Home-page: https://github.com/Lesserkuma/FlashGBX
|
|
6
6
|
Author: Lesserkuma
|
|
7
|
-
Project-URL: Source, https://github.com/
|
|
8
|
-
Project-URL: Tracker, https://github.com/
|
|
7
|
+
Project-URL: Source, https://github.com/Lesserkuma/FlashGBX/
|
|
8
|
+
Project-URL: Tracker, https://github.com/Lesserkuma/FlashGBX/issues
|
|
9
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Environment :: X11 Applications :: Qt
|
|
11
11
|
Classifier: Topic :: Terminals :: Serial
|
|
@@ -31,6 +31,7 @@ Dynamic: classifier
|
|
|
31
31
|
Dynamic: description
|
|
32
32
|
Dynamic: description-content-type
|
|
33
33
|
Dynamic: home-page
|
|
34
|
+
Dynamic: license-file
|
|
34
35
|
Dynamic: project-url
|
|
35
36
|
Dynamic: provides-extra
|
|
36
37
|
Dynamic: requires-dist
|
|
@@ -39,9 +40,9 @@ Dynamic: summary
|
|
|
39
40
|
|
|
40
41
|
# FlashGBX (by Lesserkuma)
|
|
41
42
|
|
|
42
|
-
for Windows, Linux, macOS (→ [Download](https://github.com/
|
|
43
|
+
for Windows, Linux, macOS (→ [Download](https://github.com/Lesserkuma/FlashGBX/releases))
|
|
43
44
|
|
|
44
|
-
<img src="https://raw.githubusercontent.com/
|
|
45
|
+
<img src="https://raw.githubusercontent.com/Lesserkuma/FlashGBX/master/.github/01.png" alt="FlashGBX on Windows 11" width="500"><br><img src="https://raw.githubusercontent.com/Lesserkuma/FlashGBX/master/.github/02.png" alt="GB Camera Album Viewer" width="500">
|
|
45
46
|
|
|
46
47
|
## Introduction
|
|
47
48
|
|
|
@@ -126,6 +127,7 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
126
127
|
- Ferrante Crafts cart 64 KB
|
|
127
128
|
- Ferrante Crafts cart 512 KB
|
|
128
129
|
- FunnyPlaying MidnightTrace 4 MiB Flash Cart
|
|
130
|
+
- Gamebank-web DMG-29W-04 with M29W320DB
|
|
129
131
|
- Gamebank-web DMG-29W-04 with M29W320EB
|
|
130
132
|
- Gamebank-web DMG-29W-04 with M29W320ET
|
|
131
133
|
- GameShark Pro
|
|
@@ -147,6 +149,7 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
147
149
|
- insideGadgets 4 MiB (2× 2 MiB), 32 KiB FRAM, MBC5
|
|
148
150
|
- insideGadgets MegaDuck 32K
|
|
149
151
|
- ModRetro Chromatic Cartridge with 39VF1681
|
|
152
|
+
- ModRetro Chromatic Cartridge with IS29GL032
|
|
150
153
|
- Mr Flash 64M
|
|
151
154
|
- Sillyhatday MBC5-DUAL-FLASH-4/8MB
|
|
152
155
|
- Squareboi 4 MiB (2× 2 MiB)
|
|
@@ -224,6 +227,7 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
224
227
|
- SD007_BV5_V3 with AM29LV160MB
|
|
225
228
|
- SD007_K8D3216_32M with MX29LV160CT
|
|
226
229
|
- SD007_T40_48BALL_71_TV_TS28 with M29W640
|
|
230
|
+
- SD007_T40_6401B\*CD_71_TS28 with 39VF6401B
|
|
227
231
|
- SD007_T40_64BALL_S71_TV_TS28 with TC58FVB016FT-85
|
|
228
232
|
- SD007_T40_64BALL_SOJ28 with 29LV016T
|
|
229
233
|
- SD007_T40_64BALL_TSOP28 with 29LV016T
|
|
@@ -315,6 +319,8 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
315
319
|
- M6MGJ927 (no PCB text)
|
|
316
320
|
- MSP54LV512 (no PCB text)
|
|
317
321
|
- MX29GL128EHT2I and ALTERA CPLD
|
|
322
|
+
- MXP54_16D_046 with MSP54LV256
|
|
323
|
+
- MXP54_16D_ERATH with MSP54LV256
|
|
318
324
|
- SUN100S_MSP54XXX with MSP54LV100
|
|
319
325
|
- Unknown 29LV320 variant (no PCB text)
|
|
320
326
|
|
|
@@ -326,19 +332,20 @@ Many different reproduction cartridges share their flash chip command set, so ev
|
|
|
326
332
|
|
|
327
333
|
### Pre-compiled binaries and packages
|
|
328
334
|
|
|
329
|
-
Available in the GitHub [Releases](https://github.com/
|
|
335
|
+
Available in the GitHub [Releases](https://github.com/Lesserkuma/FlashGBX/releases) section are pre-compiled downloads available for:
|
|
330
336
|
|
|
331
337
|
* **Windows (64-bit)** *(Windows 8 or newer)*
|
|
332
338
|
* Setup: An installer that will add the application to the start menu and optionally create a desktop icon
|
|
333
339
|
* Portable: Have everything in one place including the config files
|
|
334
340
|
|
|
335
341
|
* **Linux**
|
|
336
|
-
*
|
|
342
|
+
* Ubuntu (.deb file): Install using `dpkg -i /path/to/FlashGBX_x.x_Ubuntu-all.deb`.
|
|
343
|
+
* Other distributions: Pre-made Linux packages are available at [JJ-Fox’s repository](https://github.com/JJ-Fox/FlashGBX-Linux-builds/releases/latest).
|
|
337
344
|
|
|
338
|
-
* **macOS** *(
|
|
339
|
-
* x86-64/arm64 (.dmg file): Install by opening the .dmg file and copying over the “FlashGBX” application to the desktop.<br>If it doesn’t run, it probably got quarantined
|
|
345
|
+
* **macOS** *(Sequoia 15 or newer)*
|
|
346
|
+
* x86-64/arm64 (.dmg file): Install by opening the .dmg file and copying over the “FlashGBX” application to the desktop.<br>If it doesn’t run, it probably got quarantined due to the lack of a Apple Developer Program certificate. Right-click the extracted FlashGBX icon, choose “Open Terminal at Folder” and enter this command to unquarantine it: `xattr -d com.apple.quarantine ../FlashGBX.app`.
|
|
340
347
|
|
|
341
|
-
*(If you have a Joey Jr and use macOS, please run the [Joey Jr Firmware Updater](https://github.com/
|
|
348
|
+
*(If you have a Joey Jr and use macOS, please run the [Joey Jr Firmware Updater](https://github.com/Lesserkuma/JoeyJr_FWUpdater) before using FlashGBX.)*
|
|
342
349
|
|
|
343
350
|
### Run via Python
|
|
344
351
|
|
|
@@ -418,13 +425,13 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
|
|
418
425
|
|
|
419
426
|
The author would like to thank the following very kind people for their help, contributions or documentation (in alphabetical order):
|
|
420
427
|
|
|
421
|
-
2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, delibird_deals, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, Gahr, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, infinest, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, luxkiller65, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, Mufsta, olDirdey, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr
|
|
428
|
+
2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, delibird_deals, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, Gahr, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, infinest, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, luxkiller65, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, Mufsta, olDirdey, orangeglo, paarongiroux, Paradoxical, Pese, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr
|
|
422
429
|
|
|
423
430
|
Thanks to the No-Intro project for their game databases which FlashGBX’s databases are partly based on.
|
|
424
431
|
|
|
425
432
|
## Third Party Notices and Licenses
|
|
426
433
|
|
|
427
|
-
Please view the <a href="https://github.com/
|
|
434
|
+
Please view the <a href="https://github.com/Lesserkuma/FlashGBX/blob/master/Third%20Party%20Notices.md">Third Party Notices</a>.
|
|
428
435
|
|
|
429
436
|
## DISCLAIMER
|
|
430
437
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# FlashGBX (by Lesserkuma)
|
|
2
2
|
|
|
3
|
-
for Windows, Linux, macOS (→ [Download](https://github.com/
|
|
3
|
+
for Windows, Linux, macOS (→ [Download](https://github.com/Lesserkuma/FlashGBX/releases))
|
|
4
4
|
|
|
5
|
-
<img src="https://raw.githubusercontent.com/
|
|
5
|
+
<img src="https://raw.githubusercontent.com/Lesserkuma/FlashGBX/master/.github/01.png" alt="FlashGBX on Windows 11" width="500"><br><img src="https://raw.githubusercontent.com/Lesserkuma/FlashGBX/master/.github/02.png" alt="GB Camera Album Viewer" width="500">
|
|
6
6
|
|
|
7
7
|
## Introduction
|
|
8
8
|
|
|
@@ -87,6 +87,7 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
87
87
|
- Ferrante Crafts cart 64 KB
|
|
88
88
|
- Ferrante Crafts cart 512 KB
|
|
89
89
|
- FunnyPlaying MidnightTrace 4 MiB Flash Cart
|
|
90
|
+
- Gamebank-web DMG-29W-04 with M29W320DB
|
|
90
91
|
- Gamebank-web DMG-29W-04 with M29W320EB
|
|
91
92
|
- Gamebank-web DMG-29W-04 with M29W320ET
|
|
92
93
|
- GameShark Pro
|
|
@@ -108,6 +109,7 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
108
109
|
- insideGadgets 4 MiB (2× 2 MiB), 32 KiB FRAM, MBC5
|
|
109
110
|
- insideGadgets MegaDuck 32K
|
|
110
111
|
- ModRetro Chromatic Cartridge with 39VF1681
|
|
112
|
+
- ModRetro Chromatic Cartridge with IS29GL032
|
|
111
113
|
- Mr Flash 64M
|
|
112
114
|
- Sillyhatday MBC5-DUAL-FLASH-4/8MB
|
|
113
115
|
- Squareboi 4 MiB (2× 2 MiB)
|
|
@@ -185,6 +187,7 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
185
187
|
- SD007_BV5_V3 with AM29LV160MB
|
|
186
188
|
- SD007_K8D3216_32M with MX29LV160CT
|
|
187
189
|
- SD007_T40_48BALL_71_TV_TS28 with M29W640
|
|
190
|
+
- SD007_T40_6401B\*CD_71_TS28 with 39VF6401B
|
|
188
191
|
- SD007_T40_64BALL_S71_TV_TS28 with TC58FVB016FT-85
|
|
189
192
|
- SD007_T40_64BALL_SOJ28 with 29LV016T
|
|
190
193
|
- SD007_T40_64BALL_TSOP28 with 29LV016T
|
|
@@ -276,6 +279,8 @@ for Windows, Linux, macOS (→ [Download](https://github.com/lesserkuma/FlashGBX
|
|
|
276
279
|
- M6MGJ927 (no PCB text)
|
|
277
280
|
- MSP54LV512 (no PCB text)
|
|
278
281
|
- MX29GL128EHT2I and ALTERA CPLD
|
|
282
|
+
- MXP54_16D_046 with MSP54LV256
|
|
283
|
+
- MXP54_16D_ERATH with MSP54LV256
|
|
279
284
|
- SUN100S_MSP54XXX with MSP54LV100
|
|
280
285
|
- Unknown 29LV320 variant (no PCB text)
|
|
281
286
|
|
|
@@ -287,19 +292,20 @@ Many different reproduction cartridges share their flash chip command set, so ev
|
|
|
287
292
|
|
|
288
293
|
### Pre-compiled binaries and packages
|
|
289
294
|
|
|
290
|
-
Available in the GitHub [Releases](https://github.com/
|
|
295
|
+
Available in the GitHub [Releases](https://github.com/Lesserkuma/FlashGBX/releases) section are pre-compiled downloads available for:
|
|
291
296
|
|
|
292
297
|
* **Windows (64-bit)** *(Windows 8 or newer)*
|
|
293
298
|
* Setup: An installer that will add the application to the start menu and optionally create a desktop icon
|
|
294
299
|
* Portable: Have everything in one place including the config files
|
|
295
300
|
|
|
296
301
|
* **Linux**
|
|
297
|
-
*
|
|
302
|
+
* Ubuntu (.deb file): Install using `dpkg -i /path/to/FlashGBX_x.x_Ubuntu-all.deb`.
|
|
303
|
+
* Other distributions: Pre-made Linux packages are available at [JJ-Fox’s repository](https://github.com/JJ-Fox/FlashGBX-Linux-builds/releases/latest).
|
|
298
304
|
|
|
299
|
-
* **macOS** *(
|
|
300
|
-
* x86-64/arm64 (.dmg file): Install by opening the .dmg file and copying over the “FlashGBX” application to the desktop.<br>If it doesn’t run, it probably got quarantined
|
|
305
|
+
* **macOS** *(Sequoia 15 or newer)*
|
|
306
|
+
* x86-64/arm64 (.dmg file): Install by opening the .dmg file and copying over the “FlashGBX” application to the desktop.<br>If it doesn’t run, it probably got quarantined due to the lack of a Apple Developer Program certificate. Right-click the extracted FlashGBX icon, choose “Open Terminal at Folder” and enter this command to unquarantine it: `xattr -d com.apple.quarantine ../FlashGBX.app`.
|
|
301
307
|
|
|
302
|
-
*(If you have a Joey Jr and use macOS, please run the [Joey Jr Firmware Updater](https://github.com/
|
|
308
|
+
*(If you have a Joey Jr and use macOS, please run the [Joey Jr Firmware Updater](https://github.com/Lesserkuma/JoeyJr_FWUpdater) before using FlashGBX.)*
|
|
303
309
|
|
|
304
310
|
### Run via Python
|
|
305
311
|
|
|
@@ -379,13 +385,13 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
|
|
379
385
|
|
|
380
386
|
The author would like to thank the following very kind people for their help, contributions or documentation (in alphabetical order):
|
|
381
387
|
|
|
382
|
-
2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, delibird_deals, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, Gahr, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, infinest, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, luxkiller65, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, Mufsta, olDirdey, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr
|
|
388
|
+
2358, 90sFlav, AcoVanConis, AdmirtheSableye, AlexiG, ALXCO-Hardware, AndehX, antPL, aronson, Ausar, bbsan, BennVenn, ccs21, chobby, ClassicOldSong, Cliffback, CodyWick13, Corborg, Cristóbal, crizzlycruz, Crystal, Därk, Davidish, delibird_deals, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, Gahr, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, infinest, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, luxkiller65, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, Mufsta, olDirdey, orangeglo, paarongiroux, Paradoxical, Pese, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, Sonikks, Squiddy, Stitch, Super Maker, t5b6_de, Tauwasser, TheNFCookie, Timville, twitnic, velipso, Veund, voltagex, Voultar, Warez Waldo, wickawack, Winter1760, Wkr, x7l7j8cc, xactoes, xukkorz, yosoo, Zeii, Zelante, zipplet, Zoo, zvxr
|
|
383
389
|
|
|
384
390
|
Thanks to the No-Intro project for their game databases which FlashGBX’s databases are partly based on.
|
|
385
391
|
|
|
386
392
|
## Third Party Notices and Licenses
|
|
387
393
|
|
|
388
|
-
Please view the <a href="https://github.com/
|
|
394
|
+
Please view the <a href="https://github.com/Lesserkuma/FlashGBX/blob/master/Third%20Party%20Notices.md">Third Party Notices</a>.
|
|
389
395
|
|
|
390
396
|
## DISCLAIMER
|
|
391
397
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# FlashGBX
|
|
3
|
-
# Author: Lesserkuma (github.com/
|
|
3
|
+
# Author: Lesserkuma (github.com/Lesserkuma)
|
|
4
4
|
|
|
5
5
|
import setuptools
|
|
6
6
|
|
|
@@ -8,10 +8,10 @@ with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read(
|
|
|
8
8
|
|
|
9
9
|
setuptools.setup(
|
|
10
10
|
name="FlashGBX",
|
|
11
|
-
version="4.
|
|
11
|
+
version="4.6",
|
|
12
12
|
author="Lesserkuma",
|
|
13
13
|
description="Reads and writes Game Boy and Game Boy Advance cartridge data",
|
|
14
|
-
url="https://github.com/
|
|
14
|
+
url="https://github.com/Lesserkuma/FlashGBX",
|
|
15
15
|
packages=setuptools.find_packages(),
|
|
16
16
|
install_requires=['pyserial>=3.5', 'Pillow', 'setuptools', 'requests', 'python-dateutil'],
|
|
17
17
|
extras_require={
|
|
@@ -30,8 +30,8 @@ setuptools.setup(
|
|
|
30
30
|
'Intended Audience :: Developers',
|
|
31
31
|
],
|
|
32
32
|
project_urls={
|
|
33
|
-
'Source': 'https://github.com/
|
|
34
|
-
'Tracker': 'https://github.com/
|
|
33
|
+
'Source': 'https://github.com/Lesserkuma/FlashGBX/',
|
|
34
|
+
'Tracker': 'https://github.com/Lesserkuma/FlashGBX/issues',
|
|
35
35
|
},
|
|
36
36
|
entry_points={
|
|
37
37
|
'console_scripts': (
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|