FlashGBX 4.4__py3-none-any.whl → 4.6__py3-none-any.whl

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/DataTransfer.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  import traceback
6
6
  from serial import SerialException
FlashGBX/FlashGBX.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
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/lesserkuma/FlashGBX")
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")
FlashGBX/FlashGBX_CLI.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
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
- msg_save_type_s = "Save Type: None or unknown (no save data detected)\n"
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 not args.overwrite:
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"]
FlashGBX/FlashGBX_GUI.py CHANGED
@@ -1,12 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
- import sys, os, time, datetime, json, platform, subprocess, requests, webbrowser, pkg_resources, threading, calendar, queue
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("Alternative 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
+ 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/lesserkuma/FlashGBX/releases/latest"
633
- site = "https://github.com/lesserkuma/FlashGBX/releases/latest"
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 pkg_resources.parse_version(latest_version) == pkg_resources.parse_version(VERSION_PEP440):
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 pkg_resources.parse_version(latest_version) > pkg_resources.parse_version(VERSION_PEP440):
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/lesserkuma/FlashGBX\">https://github.com/lesserkuma/FlashGBX</a><br><br>"
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 (20250427-010043)<br>• Nintendo - Game Boy Advance (20250516-204815)<br>• Nintendo - Game Boy Advance (Video) (20241213-211743)<br>• Nintendo - Game Boy Color (20250516-032234)" # No-Intro DBs
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/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
+ 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/lesserkuma/JoeyJr_FWUpdater\">Firmware Updater for Joey Jr</a>"
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
- max_size = self.cmbAGBHeaderROMSizeResult.currentText().replace(" ", " ")
2278
- elif mode == "DMG":
2279
- max_size = self.cmbDMGHeaderROMSizeResult.currentText().replace(" ", " ")
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 " + max_size + " ROM backup is recommended."
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
- msg_save_type_s = "<b>Save Type:</b> None or unknown (no save data detected)<br>"
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)
FlashGBX/Flashcart.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  import time, copy, math, struct
6
6
  from .Util import dprint, bitswap
FlashGBX/GBMemory.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  import datetime, struct, copy, zlib, hashlib
6
6
  from . import Util
FlashGBX/LK_Device.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
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 and flash_save_id in Util.AGB_Flash_Save_Chips:
1266
- save_size = Util.AGB_Flash_Save_Chips_Sizes[list(Util.AGB_Flash_Save_Chips).index(flash_save_id)]
1267
- save_chip = Util.AGB_Flash_Save_Chips[flash_save_id]
1268
-
1269
- if flash_save_id in (0xBF5B, 0xFFFF): # Bootlegs
1270
- if self.INFO["data"][0:0x20000] == bytearray([0xFF] * 0x20000):
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 self.INFO["data"][0:0x10000] == self.INFO["data"][0x10000:0x20000]:
1280
+ elif save_size == 65536:
1273
1281
  save_type = 4
1274
- else:
1275
- save_type = 5
1276
- elif save_size == 131072:
1277
- save_type = 5
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
- elif (self.INFO["data"][:end_address] != buffer[:end_address]):
3575
+ if (self.INFO["data"][:end_address] != buffer[:end_address]):
3567
3576
  msg = ""
3568
3577
  count = 0
3569
3578
  time_start = time.time()
FlashGBX/Mapper.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
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 = [
FlashGBX/PocketCamera.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  from PIL import Image
6
6
  from PIL.PngImagePlugin import PngInfo
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  import functools, os, json, platform, shutil
6
6
  from PIL.ImageQt import ImageQt
FlashGBX/RomFileAGB.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  import hashlib, re, zlib, string, os, json, copy, struct
6
6
  from . import Util
FlashGBX/RomFileDMG.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  import hashlib, re, string, struct, os, json, copy
6
6
  from . import Util
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  from .pyside import QtCore, QtWidgets, QtGui
6
6
 
FlashGBX/Util.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
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.4"
11
+ VERSION_PEP440 = "4.6"
12
12
  VERSION = "v{:s}".format(VERSION_PEP440)
13
- VERSION_TIMESTAMP = 1748007939
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 ] }
FlashGBX/__main__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  from . import FlashGBX
6
6
  FlashGBX.main()
FlashGBX/fw_GBFlash.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
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
- data["outro"] = struct.unpack(">I", self.DEVICE.read(4))[0]
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/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  import zipfile, os, serial, struct, time, re, math
6
6
  from .pyside import QtCore, QtWidgets, QtGui, QDesktopWidget
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  import zipfile, serial, struct, time, random, hashlib, datetime
6
6
  try:
FlashGBX/fw_JoeyJr.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
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)
FlashGBX/hw_GBFlash.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  # pylint: disable=wildcard-import, unused-wildcard-import
6
6
  from .LK_Device import *
FlashGBX/hw_GBxCartRW.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  # pylint: disable=wildcard-import, unused-wildcard-import
6
6
  from .LK_Device import *
FlashGBX/hw_JoeyJr.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
 
5
5
  # pylint: disable=wildcard-import, unused-wildcard-import
6
6
  from .LK_Device import *
FlashGBX/pyside.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # FlashGBX
3
- # Author: Lesserkuma (github.com/lesserkuma)
3
+ # Author: Lesserkuma (github.com/Lesserkuma)
4
4
  #
5
5
  # PySide abstraction layer contributed by J-Fox
6
6
  #
FlashGBX/res/config.zip CHANGED
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,11 +1,11 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: FlashGBX
3
- Version: 4.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/lesserkuma/FlashGBX
5
+ Home-page: https://github.com/Lesserkuma/FlashGBX
6
6
  Author: Lesserkuma
7
- Project-URL: Source, https://github.com/lesserkuma/FlashGBX/
8
- Project-URL: Tracker, https://github.com/lesserkuma/FlashGBX/issues
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/lesserkuma/FlashGBX/releases))
43
+ for Windows, Linux, macOS (→ [Download](https://github.com/Lesserkuma/FlashGBX/releases))
43
44
 
44
- <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
+ <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/lesserkuma/FlashGBX/releases) section are pre-compiled downloads available for:
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
- * Pre-made packages are contributed by JJ-Fox [here](https://github.com/JJ-Fox/FlashGBX-Linux-builds/releases/latest).
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** *(Monterey 12 or newer)*
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 during download. Run the following command in a Terminal window to unquarantine it: `xattr -d com.apple.quarantine /path/to/FlashGBX.app`.<br>*(Based on a contribution by [Cliffback](https://github.com/Cliffback))*
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/lesserkuma/JoeyJr_FWUpdater) before using FlashGBX.)*
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/lesserkuma/FlashGBX/blob/master/Third%20Party%20Notices.md">Third Party Notices</a>.
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
 
@@ -0,0 +1,43 @@
1
+ FlashGBX/DataTransfer.py,sha256=Uosh2bDvplYHgw33YegSiBCoHmjzptnmm3Pq-bnTYQU,1750
2
+ FlashGBX/FlashGBX.py,sha256=15kX2qrZU95cpQ8wyTypO4z4F5EuT44nxzM-EvXiBBA,12942
3
+ FlashGBX/FlashGBX_CLI.py,sha256=wFQ5rwH_td4tWNG_7WAfoSpnqYi6eJaTAXx83CV9XWA,65462
4
+ FlashGBX/FlashGBX_GUI.py,sha256=HJP1jtOU8_TXG44gXWjxEb-vs0Q4x5iQPWVT3nIUegA,186768
5
+ FlashGBX/Flashcart.py,sha256=XYlGh3DEYxFgOOz9NHK_dsJK9jfAEdkVQLD0zknkIMU,36465
6
+ FlashGBX/GBMemory.py,sha256=NvOkdoha8j8JVOo804KwQTLyVYthWTDQWezYNsXi98E,13463
7
+ FlashGBX/LK_Device.py,sha256=5pQ1_-RPFcy1BWXoSWXLz2Ck40yZHNb6CwH0TytmpMg,196525
8
+ FlashGBX/Mapper.py,sha256=LRSN4rzwUbbvKEBYf6eyxb3tZQD8MhDoJNq-2oWxKPw,57421
9
+ FlashGBX/PocketCamera.py,sha256=WVdtqCkTfqYj2Olsk9X3Cc0V08tD4SquIBV4AwYeOk4,4898
10
+ FlashGBX/PocketCameraWindow.py,sha256=T9t7HTRGPX-Xtual4Be9dKPLT6x7TwPcFNeenO4JP-E,17262
11
+ FlashGBX/RomFileAGB.py,sha256=8MMcp2d9-Ijt2mocnDIydl0g7P1PrniUz-lMBL0dmLk,8967
12
+ FlashGBX/RomFileDMG.py,sha256=iSk0lRdFoOBZ8asmLR-oN-LKfOfS7s25YnE7NNQ9rpU,21720
13
+ FlashGBX/UserInputDialog.py,sha256=IsBR8GedVG1olY5-shOAR7ffg_6l5KmmvjWOQIMm9mc,2911
14
+ FlashGBX/Util.py,sha256=7002iH1hQdi-nGTk4VMs1t_hBIkOFLWnORN5GdeiN5c,42701
15
+ FlashGBX/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ FlashGBX/__main__.py,sha256=WQKOVwzAO6yzwr_4ZpMNijilVmn3VqmQV5OxW5ue6DY,120
17
+ FlashGBX/fw_GBFlash.py,sha256=oVZC_lHpn24DE5zOLB9yMlkZ24Vzx68ZEc3v6dBgRwg,15991
18
+ FlashGBX/fw_GBxCartRW_v1_3.py,sha256=7jzLdMeIygWEtRhtDmN4fBZMa-CEGJQMjHueIEOt-Rc,21498
19
+ FlashGBX/fw_GBxCartRW_v1_4.py,sha256=OjKZqzymHuev7eTAcRRRynSBCeKZgzL9m9gzE5S5aHo,14259
20
+ FlashGBX/fw_JoeyJr.py,sha256=odlcPeakJUqZcouym7LbumBqmKWh3O104rylGT2BJsE,21339
21
+ FlashGBX/hw_GBFlash.py,sha256=t31odPPIwATDGkJvz0Go8C9by1Fi8AgdUhgG7S3TR-o,8336
22
+ FlashGBX/hw_GBxCartRW.py,sha256=3KPA2DB69nqobSs5cPCk3dxPInP9m2yMoG1npS_vi1I,11243
23
+ FlashGBX/hw_JoeyJr.py,sha256=MEan6p7NrJhmJGIl5EVtyA2W0QuPg1rs8gryqI-SIjE,9335
24
+ FlashGBX/pyside.py,sha256=hn_-2gNp-oshoYnIUVbLPYpniUFkWjXWPf3sHVY6jBo,1662
25
+ FlashGBX/res/Third Party Notices.md,sha256=hTl66zRJfRgj20L6d4HxiFrBUXS0osI1cQIalJ1F_KY,21380
26
+ FlashGBX/res/config.zip,sha256=VQj53WVTuj4ruR41YrZbHeY2KmRUY-fdB9B18FaXCv8,385030
27
+ FlashGBX/res/fw_GBFlash.zip,sha256=YGikqgp-QixVoRry6CNnADHNdpbO7u6U9RooAIof7CY,18467
28
+ FlashGBX/res/fw_GBxCart_RW_Mini_v1_0.zip,sha256=-QpHSw2JsjPG2WQ7E6mRqre4D3VThau2U7bFZYPY6r0,4774
29
+ FlashGBX/res/fw_GBxCart_RW_XMAS_v1_0.zip,sha256=ai6ithbSsEst22lCcDyJhr8KIlixqhg3HF4XV16Fdto,8093
30
+ FlashGBX/res/fw_GBxCart_RW_v1_1_v1_2.zip,sha256=H9tTjRMovpRkR89tUCsMMpwPslCoRml_cEWu8oYfMLs,8137
31
+ FlashGBX/res/fw_GBxCart_RW_v1_3.zip,sha256=zi2f7fdulQcSATuiIFMaCrpz3mCF5RGftVpbZNVedq0,15681
32
+ FlashGBX/res/fw_GBxCart_RW_v1_4.zip,sha256=GC1ulEKRZMbXd8FqfXtmSZ5JMaYBWctr5mCENBte6AQ,37284
33
+ FlashGBX/res/fw_GBxCart_RW_v1_4a.zip,sha256=9H4_v5KuImvjxKQEurn2_IHLCOr58us_jmQvuIbM2l4,36772
34
+ FlashGBX/res/fw_JoeyJr.zip,sha256=u_wR_oBHRss0229Zk3tpyyM9zTSsgILFxx98sDg_uiE,72013
35
+ FlashGBX/res/icon.ico,sha256=2FNNCkh2W0IFQNYNdy8cmodh69NC0gYfpw81GZtr9rU,129959
36
+ FlashGBX/res/icon.png,sha256=WtE7XqPKr2538lw4gVbm6slWvMLJpwYjre8_z1q70GY,19286
37
+ FlashGBX/res/pc_frame.png,sha256=Hp8cUT_e7kc3-nrTD9ekB8gNVgKNEZRr75ggNDihJOg,653
38
+ flashgbx-4.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
39
+ flashgbx-4.6.dist-info/METADATA,sha256=a_2DshfPm209YXNrj42QnFYTdE9d-3zzV-GMZUlotsk,21936
40
+ flashgbx-4.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
41
+ flashgbx-4.6.dist-info/entry_points.txt,sha256=lsg7RmPUIvEI_Q8bA3jIRh8MLF1qIBzUX_yEjD4lJ-g,52
42
+ flashgbx-4.6.dist-info/top_level.txt,sha256=y6Ssb3YnEYYHNJIPsG_b5ifITM1STAyQXMpjtNOtyzA,9
43
+ flashgbx-4.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,43 +0,0 @@
1
- FlashGBX/DataTransfer.py,sha256=bE4ZW3iQNceGMgS_SyDQKrXTZcdQxeRSni8GkxBtXIY,1750
2
- FlashGBX/FlashGBX.py,sha256=bCxU0sTeQrxOMtTBzVQhD-_YBF8AlXuFJtep15YakFc,12784
3
- FlashGBX/FlashGBX_CLI.py,sha256=xWhAH4jjMlao3VKF3A1l3v3OYKSUWeUfRApR5xQyUs4,65007
4
- FlashGBX/FlashGBX_GUI.py,sha256=PfPu6jf_OxasoMFdo3jK850Dk4vDV631AcbE9dCdfeU,186657
5
- FlashGBX/Flashcart.py,sha256=ZbwgPo9__IiYbc2ZndoDChn6_nq25bUwJs2nYppZhwM,36465
6
- FlashGBX/GBMemory.py,sha256=BoM8_3rgIVQoxYin20t_-_pLHHPdNnuGXoPl2hRYGOY,13463
7
- FlashGBX/LK_Device.py,sha256=GfS1XIqHGM9hfr7qbsIO5fABisiiQibCvou9v5vuCKE,195976
8
- FlashGBX/Mapper.py,sha256=ALNZTki3Q9WOp5UPvYntrRnnKlQOMNuTJrfBMq5ITUw,57855
9
- FlashGBX/PocketCamera.py,sha256=zLspGfQcX_fjplI54VPJXWk9dHP_3Ix99a4tqFU3Vf4,4898
10
- FlashGBX/PocketCameraWindow.py,sha256=CErgsMf-z7RklC84XKTkghpF1G0I4p_bbX77Gg8HY0E,17262
11
- FlashGBX/RomFileAGB.py,sha256=S5iMw-KLOhWvKoNjflbCRoUM-zrOofPcpYmLLsF8WRw,8967
12
- FlashGBX/RomFileDMG.py,sha256=QarLMwTYoPPpKA4Txv3KtCFcNiVg5bDslvfrqoN6J8k,21720
13
- FlashGBX/UserInputDialog.py,sha256=aYe3CeYlzQoCLI4DQulL5K9euB0HcMpcKZCFZfIJzqE,2911
14
- FlashGBX/Util.py,sha256=w2c3AY_ujhbJK-Hg_E1tYxami8luXRKkl8obKqjN8FA,42616
15
- FlashGBX/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- FlashGBX/__main__.py,sha256=L3ibKoTXOlTCepGzrgcktk_Jwp25xBCmGpNQO7W8Bbc,120
17
- FlashGBX/fw_GBFlash.py,sha256=aNn8_jjGGWeDaRCSnXPbQ-e_JN98cn9-22Nv_waY3wA,15184
18
- FlashGBX/fw_GBxCartRW_v1_3.py,sha256=qiYReJi1C-UDTjJVY0VujIsM5wPolnUrl_3TQYV-Drw,21498
19
- FlashGBX/fw_GBxCartRW_v1_4.py,sha256=wVjjjdxY0ugg6B9e4QA_ErySdZCYHL3ljoQzWnheL6A,14259
20
- FlashGBX/fw_JoeyJr.py,sha256=_ru3hcBQDJeTXk3yd0wHSlWDOXem0MaBiEy8nngFzSI,21328
21
- FlashGBX/hw_GBFlash.py,sha256=hZ1Cga07AmpqtmiZsG2RSibIP69DSrfBR7iy6hZutvc,8336
22
- FlashGBX/hw_GBxCartRW.py,sha256=meXKAGfS6v3e51VmVXBBHdPA99u13unwgwZFq59D_ZU,11243
23
- FlashGBX/hw_JoeyJr.py,sha256=F9uqoRw3hR-p21POgNY-dUU7wAhegOD-rp1Vz7odBYg,9335
24
- FlashGBX/pyside.py,sha256=hlvYbV29AFJ1Epv0R41Sz-wuo4I9-gH8hgS8sfwJyCk,1662
25
- FlashGBX/res/Third Party Notices.md,sha256=hTl66zRJfRgj20L6d4HxiFrBUXS0osI1cQIalJ1F_KY,21380
26
- FlashGBX/res/config.zip,sha256=weBRVFqS8-AFIveXwmitBBoEsGT9YO2iUAq7W4T3L10,383438
27
- FlashGBX/res/fw_GBFlash.zip,sha256=rTLStKSMcl160UO16djRxpaVCTmwE-CbGsGXKnp7ZDU,18467
28
- FlashGBX/res/fw_GBxCart_RW_Mini_v1_0.zip,sha256=-QpHSw2JsjPG2WQ7E6mRqre4D3VThau2U7bFZYPY6r0,4774
29
- FlashGBX/res/fw_GBxCart_RW_XMAS_v1_0.zip,sha256=ai6ithbSsEst22lCcDyJhr8KIlixqhg3HF4XV16Fdto,8093
30
- FlashGBX/res/fw_GBxCart_RW_v1_1_v1_2.zip,sha256=H9tTjRMovpRkR89tUCsMMpwPslCoRml_cEWu8oYfMLs,8137
31
- FlashGBX/res/fw_GBxCart_RW_v1_3.zip,sha256=zi2f7fdulQcSATuiIFMaCrpz3mCF5RGftVpbZNVedq0,15681
32
- FlashGBX/res/fw_GBxCart_RW_v1_4.zip,sha256=KYEsS8k5mUAAia5QqfoGBzSJBjOaumXxtkR-J820dvw,37284
33
- FlashGBX/res/fw_GBxCart_RW_v1_4a.zip,sha256=IrZ0uI1v_mErR5Mi2ETgwmojee5GYS_Fqlia48ODT88,36772
34
- FlashGBX/res/fw_JoeyJr.zip,sha256=vJBBplHFiLdjkx3w-wjyD-sLKhAmf8ZSLZlYo_E0ohc,72013
35
- FlashGBX/res/icon.ico,sha256=2FNNCkh2W0IFQNYNdy8cmodh69NC0gYfpw81GZtr9rU,129959
36
- FlashGBX/res/icon.png,sha256=WtE7XqPKr2538lw4gVbm6slWvMLJpwYjre8_z1q70GY,19286
37
- FlashGBX/res/pc_frame.png,sha256=Hp8cUT_e7kc3-nrTD9ekB8gNVgKNEZRr75ggNDihJOg,653
38
- FlashGBX-4.4.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
39
- FlashGBX-4.4.dist-info/METADATA,sha256=0dkjr10xlg8h8bvVWWWVERuv6ncWrQsbM1SzeNBaK24,21560
40
- FlashGBX-4.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
41
- FlashGBX-4.4.dist-info/entry_points.txt,sha256=lsg7RmPUIvEI_Q8bA3jIRh8MLF1qIBzUX_yEjD4lJ-g,52
42
- FlashGBX-4.4.dist-info/top_level.txt,sha256=y6Ssb3YnEYYHNJIPsG_b5ifITM1STAyQXMpjtNOtyzA,9
43
- FlashGBX-4.4.dist-info/RECORD,,