FlashGBX 4.2__tar.gz → 4.4__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.
Files changed (54) hide show
  1. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/DataTransfer.py +1 -2
  2. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/FlashGBX.py +2 -2
  3. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/FlashGBX_CLI.py +40 -29
  4. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/FlashGBX_GUI.py +484 -191
  5. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/Flashcart.py +3 -1
  6. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/GBMemory.py +3 -1
  7. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/LK_Device.py +408 -199
  8. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/Mapper.py +46 -7
  9. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/PocketCamera.py +2 -2
  10. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/PocketCameraWindow.py +35 -5
  11. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/RomFileAGB.py +4 -1
  12. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/RomFileDMG.py +13 -2
  13. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/Util.py +86 -16
  14. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/fw_GBFlash.py +0 -5
  15. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/fw_GBxCartRW_v1_4.py +2 -5
  16. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/fw_JoeyJr.py +23 -8
  17. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/hw_GBFlash.py +16 -7
  18. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/hw_GBxCartRW.py +18 -16
  19. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/hw_JoeyJr.py +2 -2
  20. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/res/Third Party Notices.md +21 -1
  21. flashgbx-4.4/FlashGBX/res/config.zip +0 -0
  22. flashgbx-4.4/FlashGBX/res/fw_GBFlash.zip +0 -0
  23. flashgbx-4.4/FlashGBX/res/fw_GBxCart_RW_v1_4.zip +0 -0
  24. flashgbx-4.4/FlashGBX/res/fw_GBxCart_RW_v1_4a.zip +0 -0
  25. flashgbx-4.4/FlashGBX/res/fw_JoeyJr.zip +0 -0
  26. {FlashGBX-4.2 → flashgbx-4.4/FlashGBX.egg-info}/PKG-INFO +98 -49
  27. FlashGBX-4.2/README.md → flashgbx-4.4/PKG-INFO +431 -353
  28. FlashGBX-4.2/FlashGBX.egg-info/PKG-INFO → flashgbx-4.4/README.md +392 -382
  29. {FlashGBX-4.2 → flashgbx-4.4}/setup.py +1 -1
  30. FlashGBX-4.2/FlashGBX/res/config.zip +0 -0
  31. FlashGBX-4.2/FlashGBX/res/fw_GBFlash.zip +0 -0
  32. FlashGBX-4.2/FlashGBX/res/fw_GBxCart_RW_v1_4.zip +0 -0
  33. FlashGBX-4.2/FlashGBX/res/fw_GBxCart_RW_v1_4a.zip +0 -0
  34. FlashGBX-4.2/FlashGBX/res/fw_JoeyJr.zip +0 -0
  35. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/UserInputDialog.py +0 -0
  36. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/__init__.py +0 -0
  37. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/__main__.py +0 -0
  38. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/fw_GBxCartRW_v1_3.py +0 -0
  39. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/pyside.py +0 -0
  40. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/res/fw_GBxCart_RW_Mini_v1_0.zip +0 -0
  41. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/res/fw_GBxCart_RW_XMAS_v1_0.zip +0 -0
  42. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/res/fw_GBxCart_RW_v1_1_v1_2.zip +0 -0
  43. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/res/fw_GBxCart_RW_v1_3.zip +0 -0
  44. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/res/icon.ico +0 -0
  45. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/res/icon.png +0 -0
  46. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX/res/pc_frame.png +0 -0
  47. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX.egg-info/SOURCES.txt +0 -0
  48. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX.egg-info/dependency_links.txt +0 -0
  49. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX.egg-info/entry_points.txt +0 -0
  50. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX.egg-info/requires.txt +0 -0
  51. {FlashGBX-4.2 → flashgbx-4.4}/FlashGBX.egg-info/top_level.txt +0 -0
  52. {FlashGBX-4.2 → flashgbx-4.4}/LICENSE +0 -0
  53. {FlashGBX-4.2 → flashgbx-4.4}/MANIFEST.in +0 -0
  54. {FlashGBX-4.2 → flashgbx-4.4}/setup.cfg +0 -0
@@ -5,7 +5,6 @@
5
5
  import traceback
6
6
  from serial import SerialException
7
7
  from . import pyside as PySide2
8
- from . import Util
9
8
  from .Util import dprint
10
9
 
11
10
  class DataTransfer(PySide2.QtCore.QThread):
@@ -54,5 +53,5 @@ class DataTransfer(PySide2.QtCore.QThread):
54
53
  if error is not None:
55
54
  print(tb)
56
55
  dprint(tb)
57
- self.updateProgress.emit({"action":"ABORT", "info_type":"msgbox_critical", "fatal":True, "info_msg":"An unresolvable error has occured. See console output for more information. Reconnect the device, restart the software and try again.\n\n{:s}: {:s}".format(type(error).__name__, str(error)), "abortable":False})
56
+ self.updateProgress.emit({"action":"ABORT", "info_type":"msgbox_critical", "fatal":True, "info_msg":"An unresolvable error has occured. See the debug log file for more information. Reconnect the device, restart the software and try again.\n\n{:s}: {:s}".format(type(error).__name__, str(error)), "abortable":False})
58
57
  self.FINISHED = True
@@ -133,9 +133,9 @@ def main(portableMode=False):
133
133
  ap_cli1.add_argument("path", nargs="?", default="auto", help="target or source file path (optional when reading, required when writing)")
134
134
 
135
135
  ap_cli2 = parser.add_argument_group('optional command line interface arguments')
136
- ap_cli2.add_argument("--dmg-romsize", choices=["auto", "32kb", "64kb", "128kb", "256kb", "512kb", "1mb", "2mb", "4mb", "8mb", "16mb", "32mb"], type=str.lower, default="auto", help="set size of Game Boy cartridge ROM data")
136
+ ap_cli2.add_argument("--dmg-romsize", choices=["auto", "32kb", "64kb", "128kb", "256kb", "512kb", "1mb", "2mb", "4mb", "8mb", "16mb", "32mb", "64mb", "128mb"], type=str.lower, default="auto", help="set size of Game Boy cartridge ROM data")
137
137
  ap_cli2.add_argument("--dmg-mbc", type=str.lower, default="auto", help="set memory bank controller type of Game Boy cartridge")
138
- ap_cli2.add_argument("--dmg-savesize", choices=["auto", "4k", "16k", "64k", "256k", "512k", "1m", "eeprom2k", "eeprom4k", "tama5", "4m"], type=str.lower, default="auto", help="set size of Game Boy cartridge save data")
138
+ ap_cli2.add_argument("--dmg-savetype", choices=["auto", "4k", "16k", "64k", "256k", "512k", "1m", "mbc6", "mbc7_2k", "mbc7_4k", "tama5", "sram4m", "eeprom1m", "photo"], type=str.lower, default="auto", help="set type of Game Boy cartridge save data")
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")
@@ -371,11 +371,21 @@ class FlashGBX_CLI():
371
371
 
372
372
  elif self.CONN.INFO["last_action"] == 2: # Backup RAM
373
373
  self.CONN.INFO["last_action"] = 0
374
- if not "debug" in self.ARGS and self.CONN.GetMode() == "DMG" and self.CONN.INFO["mapper_raw"] == 252 and self.CONN.INFO["transferred"] == 131072: # Pocket Camera / 128 KiB: # 128 KiB
374
+ if not "debug" in self.ARGS and self.CONN.GetMode() == "DMG" and self.CONN.INFO["mapper_raw"] == 252 and self.CONN.INFO["transferred"] == 0x20000 or (self.CONN.INFO["transferred"] == 0x100000 and self.CONN.INFO["dump_info"]["header"]["ram_size_raw"] == 0x204):
375
375
  answer = input("Would you like to extract Game Boy Camera pictures to “{:s}” now? [Y/n]: ".format(Util.formatPathOS(os.path.abspath(os.path.splitext(self.CONN.INFO["last_path"])[0]), end_sep=True) + "IMG_PC**.{:s}".format(self.ARGS["argparsed"].gbcamera_outfile_format))).strip().lower()
376
376
  if answer != "n":
377
+ if self.CONN.INFO["transferred"] == 0x100000:
378
+ answer = int(input("A Photo! save file was detected. Please select the roll of pictures that you would like to load.\n- 1: Current Save Data\n- 2-8: Flash Directory Slots\nLoad Roll [1-8]: "))
379
+ if answer == 0:
380
+ return
381
+ with open(self.CONN.INFO["last_path"], "rb") as f:
382
+ f.seek(0x20000 * (answer - 1))
383
+ file = bytearray(f.read(0x20000))
384
+ else:
385
+ file = self.CONN.INFO["last_path"]
386
+
377
387
  pc = PocketCamera()
378
- if pc.LoadFile(self.CONN.INFO["last_path"]) != False:
388
+ if pc.LoadFile(file) != False:
379
389
  palettes = [ "grayscale", "dmg", "sgb", "cgb1", "cgb2", "cgb3" ]
380
390
  pc.SetPalette(palettes.index(self.ARGS["argparsed"].gbcamera_palette))
381
391
  file = os.path.splitext(self.CONN.INFO["last_path"])[0] + "/IMG_PC00.png"
@@ -571,12 +581,10 @@ class FlashGBX_CLI():
571
581
  bad_read = True
572
582
 
573
583
  s += "ROM Checksum: "
574
- #Util.AGB_Global_CRC32 = 0
575
584
  db_agb_entry = data["db"]
576
585
  if db_agb_entry != None:
577
586
  if data["rom_size_calc"] < 0x400000:
578
587
  s += "In database (0x{:06X})\n".format(db_agb_entry['rc'])
579
- #Util.AGB_Global_CRC32 = db_agb_entry['rc']
580
588
  s += "ROM Size: {:d} MiB\n".format(int(db_agb_entry['rs']/1024/1024))
581
589
  data['rom_size'] = db_agb_entry['rs']
582
590
  elif data["rom_size"] != 0:
@@ -606,10 +614,6 @@ class FlashGBX_CLI():
606
614
 
607
615
  if data['logo_correct'] and isinstance(db_agb_entry, dict) and "rs" in db_agb_entry and db_agb_entry['rs'] == 0x4000000 and not self.CONN.IsSupported3dMemory():
608
616
  print("{:s}\nWARNING: This cartridge uses a Memory Bank Controller that may not be completely supported yet. A future version of the {:s} device firmware may add support for it.{:s}".format(ANSI.YELLOW, self.CONN.GetFullName(), ANSI.RESET))
609
-
610
- # if "has_rtc" in data and data["has_rtc"] is not True and "no_rtc_reason" in data:
611
- # if data["no_rtc_reason"] == 1:
612
- # print("{:s}NOTE: It seems that this cartridge’s Real Time Clock battery may no longer be functional and needs to be replaced.{:s}".format(ANSI.YELLOW, ANSI.RESET))
613
617
 
614
618
  return (bad_read, s, data)
615
619
 
@@ -624,7 +628,8 @@ class FlashGBX_CLI():
624
628
 
625
629
  header = self.CONN.ReadInfo()
626
630
  self.ReadCartridge(header)
627
- ret = self.CONN.DetectCartridge(limitVoltage=limitVoltage, checkSaveType=True)
631
+ self.CONN._DetectCartridge(args={"limitVoltage":limitVoltage, "checkSaveType":True})
632
+ ret = self.CONN.INFO["detect_cart"]
628
633
  (header, _, save_type, save_chip, sram_unstable, cart_types, cart_type_id, cfi_s, _, flash_id, detected_size) = ret
629
634
 
630
635
  # Save Type
@@ -638,6 +643,8 @@ class FlashGBX_CLI():
638
643
  supp_cart_types = self.CONN.GetSupportedCartridgesDMG()
639
644
  elif self.CONN.GetMode() == "AGB":
640
645
  supp_cart_types = self.CONN.GetSupportedCartridgesAGB()
646
+ else:
647
+ raise NotImplementedError
641
648
 
642
649
  if len(cart_types) > 0:
643
650
  cart_type = cart_type_id
@@ -654,6 +661,7 @@ class FlashGBX_CLI():
654
661
 
655
662
  # Save Type
656
663
  msg_save_type_s = ""
664
+ temp = ""
657
665
  if save_chip is not None:
658
666
  temp = "{:s} ({:s})".format(Util.AGB_Header_Save_Types[save_type], save_chip)
659
667
  else:
@@ -695,6 +703,7 @@ class FlashGBX_CLI():
695
703
  else:
696
704
  if (len(flash_id.split("\n")) > 2) and ((self.CONN.GetMode() == "DMG") or ("dacs_8m" in header and header["dacs_8m"] is not True)):
697
705
  msg_cart_type_s = "Cartridge Type: Unknown flash cartridge."
706
+ try_this = ""
698
707
  if ("[ 0/90]" in flash_id):
699
708
  try_this = "Generic Flash Cartridge (0/90)"
700
709
  elif ("[ AAA/AA]" in flash_id):
@@ -767,7 +776,7 @@ class FlashGBX_CLI():
767
776
  print("{:s}Couldn’t determine ROM size, will use 8 MiB. It can also be manually set with the “--dmg-romsize” command line switch.{:s}".format(ANSI.YELLOW, ANSI.RESET))
768
777
  rom_size = 8 * 1024 * 1024
769
778
  else:
770
- sizes = [ "auto", "32kb", "64kb", "128kb", "256kb", "512kb", "1mb", "2mb", "4mb", "8mb", "16mb", "32mb" ]
779
+ sizes = [ "auto", "32kb", "64kb", "128kb", "256kb", "512kb", "1mb", "2mb", "4mb", "8mb", "16mb", "32mb", "64mb", "128mb" ]
771
780
  rom_size = Util.DMG_Header_ROM_Sizes_Flasher_Map[sizes.index(args.dmg_romsize) - 1]
772
781
 
773
782
  elif self.CONN.GetMode() == "AGB":
@@ -820,6 +829,9 @@ class FlashGBX_CLI():
820
829
  carts = self.CONN.GetSupportedCartridgesDMG()[1]
821
830
  elif self.CONN.GetMode() == "AGB":
822
831
  carts = self.CONN.GetSupportedCartridgesAGB()[1]
832
+ else:
833
+ raise NotImplementedError
834
+
823
835
  cart_type = 0
824
836
  for i in range(0, len(carts)):
825
837
  if not "names" in carts[i]: continue
@@ -895,7 +907,6 @@ class FlashGBX_CLI():
895
907
  elif os.path.getsize(path) < 0x400:
896
908
  print("{:s}ROM files smaller than 1 KiB are not supported.{:s}".format(ANSI.RED, ANSI.RESET))
897
909
  return
898
- #with open(path, "rb") as file: buffer = bytearray(file.read())
899
910
 
900
911
  with open(path, "rb") as file:
901
912
  ext = os.path.splitext(path)[1]
@@ -978,6 +989,9 @@ class FlashGBX_CLI():
978
989
  s_mbc = " using Mapper Type 0x{:X}".format(mbc)
979
990
  elif self.CONN.GetMode() == "AGB":
980
991
  hdr = RomFileAGB(buffer).GetHeader()
992
+ else:
993
+ raise NotImplementedError
994
+
981
995
  if not hdr["logo_correct"] and (self.CONN.GetMode() == "AGB" or (self.CONN.GetMode() == "DMG" and mbc not in (0x203, 0x205))):
982
996
  print("{:s}Warning: The ROM file you selected will not boot on actual hardware due to invalid boot logo data.{:s}".format(ANSI.YELLOW, ANSI.RESET))
983
997
  bootlogo = None
@@ -1021,6 +1035,7 @@ class FlashGBX_CLI():
1021
1035
  def BackupRestoreRAM(self, args, header):
1022
1036
  add_date_time = args.save_filename_add_datetime is True
1023
1037
  rtc = args.store_rtc is True
1038
+ cart_type = 0
1024
1039
 
1025
1040
  path_datetime = ""
1026
1041
  if add_date_time:
@@ -1053,7 +1068,7 @@ class FlashGBX_CLI():
1053
1068
  else:
1054
1069
  mbc = 0x19
1055
1070
 
1056
- if args.dmg_savesize == "auto":
1071
+ if args.dmg_savetype == "auto":
1057
1072
  try:
1058
1073
  if header['mapper_raw'] == 0x06: # MBC2
1059
1074
  save_type = 1
@@ -1063,19 +1078,22 @@ class FlashGBX_CLI():
1063
1078
  save_type = 0x102
1064
1079
  elif header['mapper_raw'] == 0xFD: # TAMA5
1065
1080
  save_type = 0x103
1066
- elif header['mapper_raw'] == 0x20: # TAMA5
1081
+ elif header['mapper_raw'] == 0x20: # MBC6
1067
1082
  save_type = 0x104
1068
1083
  else:
1069
1084
  save_type = header['ram_size_raw']
1070
1085
  except:
1071
- save_type = 0x20000
1086
+ save_type = 0
1072
1087
  else:
1073
- sizes = [ "auto", "4k", "16k", "64k", "256k", "512k", "1m", "eeprom2k", "eeprom4k", "tama5", "4m" ]
1074
- save_type = args.dmg_savesize
1088
+ sizes = [ "auto", "4k", "16k", "64k", "256k", "512k", "1m", "mbc6", "mbc7_2k", "mbc7_4k", "tama5", "sram4m", "eeprom1m", "photo" ]
1089
+ save_type = Util.DMG_Header_RAM_Sizes_Map[sizes.index(args.dmg_savetype)]
1075
1090
 
1076
1091
  if save_type == 0:
1077
- print("{:s}Unable to auto-detect the save size. Please use the “--dmg-savesize” command line switch to manually select it.{:s}".format(ANSI.RED, ANSI.RESET))
1092
+ print("{:s}Unable to auto-detect the save size. Please use the “--dmg-savetype” command line switch to manually select it.{:s}".format(ANSI.RED, ANSI.RESET))
1078
1093
  return
1094
+
1095
+ if save_type == 0x204:
1096
+ cart_type = self.DetectCartridge()
1079
1097
 
1080
1098
  elif self.CONN.GetMode() == "AGB":
1081
1099
  if args.agb_savetype == "auto":
@@ -1174,13 +1192,13 @@ class FlashGBX_CLI():
1174
1192
  self.CONN.TransferData(args={ 'mode':2, 'path':path, 'mbc':mbc, 'save_type':save_type, 'rtc':rtc }, signal=self.PROGRESS.SetProgress)
1175
1193
  elif args.action == "restore-save":
1176
1194
  verify_write = args.no_verify_write is False
1177
- targs = { 'mode':3, 'path':path, 'mbc':mbc, 'save_type':save_type, 'erase':False, 'rtc':rtc, 'verify_write':verify_write }
1195
+ targs = { 'mode':3, 'path':path, 'mbc':mbc, 'save_type':save_type, 'erase':False, 'rtc':rtc, 'verify_write':verify_write, 'cart_type':cart_type }
1178
1196
  if buffer is not None:
1179
1197
  targs["buffer"] = buffer
1180
1198
  targs["path"] = None
1181
1199
  self.CONN.TransferData(args=targs, signal=self.PROGRESS.SetProgress)
1182
1200
  elif args.action == "erase-save":
1183
- self.CONN.TransferData(args={ 'mode':3, 'path':path, 'mbc':mbc, 'save_type':save_type, 'erase':True, 'rtc':rtc }, signal=self.PROGRESS.SetProgress)
1201
+ self.CONN.TransferData(args={ 'mode':3, 'path':path, 'mbc':mbc, 'save_type':save_type, 'erase':True, 'rtc':rtc, 'cart_type':cart_type }, signal=self.PROGRESS.SetProgress)
1184
1202
  elif args.action == "debug-test-save": # debug
1185
1203
  self.ARGS["debug"] = True
1186
1204
 
@@ -1249,14 +1267,6 @@ class FlashGBX_CLI():
1249
1267
  print("\n{:s}Done! The writable save data size is {:s} out of {:s} checked.{:s}".format(ANSI.GREEN, Util.formatFileSize(size=found_length), Util.formatFileSize(size=Util.DMG_Header_RAM_Sizes_Flasher_Map[Util.DMG_Header_RAM_Sizes_Map.index(save_type)]), ANSI.RESET))
1250
1268
  elif self.CONN.GetMode() == "AGB":
1251
1269
  print("\n{:s}Done! The writable save data size using save type “{:s}” is {:s}.{:s}".format(ANSI.GREEN, Util.AGB_Header_Save_Types[save_type], Util.formatFileSize(size=found_length), ANSI.RESET))
1252
-
1253
- try:
1254
- (_, _, cfi) = self.CONN.CheckFlashChip(limitVoltage=False)
1255
- if len(cfi["raw"]) > 0:
1256
- with open(Util.CONFIG_PATH + "/cfi.bin", "wb") as f: f.write(cfi["raw"])
1257
- print("CFI data was extracted to “cfi.bin”.")
1258
- except:
1259
- pass
1260
1270
 
1261
1271
  def UpdateFirmware_PrintText(self, text, enableUI=False, setProgress=None):
1262
1272
  if setProgress is not None:
@@ -1415,8 +1425,8 @@ class FlashGBX_CLI():
1415
1425
  with zf.open("fw.ini") as f: ini_file = f.read()
1416
1426
  ini_file = ini_file.decode(encoding="utf-8")
1417
1427
  self.INI = Util.IniSettings(ini=ini_file, main_section="Firmware")
1418
- fw_ver = self.INI.GetValue("fw_ver")
1419
- fw_buildts = self.INI.GetValue("fw_buildts")
1428
+ #fw_ver = self.INI.GetValue("fw_ver")
1429
+ #fw_buildts = self.INI.GetValue("fw_buildts")
1420
1430
 
1421
1431
  print("Select the firmware to install:\n1) Lesserkuma’s FlashGBX firmware\n2) BennVenn’s Drag’n’Drop firmware\n3) BennVenn’s JoeyGUI firmware\n")
1422
1432
  answer = input("Enter number 1-3: ").lower().strip()
@@ -1454,6 +1464,7 @@ class FlashGBX_CLI():
1454
1464
  FWUPD = FirmwareUpdater(port=port)
1455
1465
  file_name = Util.APP_PATH + "/res/fw_JoeyJr.zip"
1456
1466
  with zipfile.ZipFile(file_name) as archive:
1467
+ fw_data = None
1457
1468
  if fw_choice == 1:
1458
1469
  with archive.open("FIRMWARE_LK.JR") as f: fw_data = bytearray(f.read())
1459
1470
  elif fw_choice == 2: