FlashGBX 3.37__tar.gz → 4.0.1__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 (53) hide show
  1. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/FlashGBX.py +14 -7
  2. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/FlashGBX_CLI.py +201 -24
  3. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/FlashGBX_GUI.py +636 -204
  4. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/Flashcart.py +184 -83
  5. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/GBMemory.py +4 -5
  6. FlashGBX-3.37/FlashGBX/hw_GBxCartRW.py → FlashGBX-4.0.1/FlashGBX/LK_Device.py +1587 -953
  7. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/Mapper.py +534 -356
  8. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/RomFileAGB.py +92 -2
  9. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/RomFileDMG.py +1 -1
  10. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/UserInputDialog.py +20 -0
  11. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/Util.py +95 -47
  12. FlashGBX-4.0.1/FlashGBX/fw_GBFlash.py +426 -0
  13. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/fw_GBxCartRW_v1_3.py +1 -1
  14. FlashGBX-4.0.1/FlashGBX/fw_JoeyJr.py +472 -0
  15. FlashGBX-4.0.1/FlashGBX/hw_GBFlash.py +244 -0
  16. FlashGBX-4.0.1/FlashGBX/hw_GBxCartRW.py +322 -0
  17. FlashGBX-4.0.1/FlashGBX/hw_JoeyJr.py +309 -0
  18. FlashGBX-4.0.1/FlashGBX/res/Third Party Notices.md +342 -0
  19. FlashGBX-4.0.1/FlashGBX/res/config.zip +0 -0
  20. FlashGBX-4.0.1/FlashGBX/res/fw_GBFlash.zip +0 -0
  21. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/res/fw_GBxCart_RW_v1_3.zip +0 -0
  22. FlashGBX-4.0.1/FlashGBX/res/fw_GBxCart_RW_v1_4.zip +0 -0
  23. FlashGBX-4.0.1/FlashGBX/res/fw_GBxCart_RW_v1_4a.zip +0 -0
  24. FlashGBX-4.0.1/FlashGBX/res/fw_JoeyJr.zip +0 -0
  25. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX.egg-info/PKG-INFO +36 -16
  26. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX.egg-info/SOURCES.txt +8 -1
  27. {FlashGBX-3.37 → FlashGBX-4.0.1}/PKG-INFO +36 -16
  28. {FlashGBX-3.37 → FlashGBX-4.0.1}/README.md +34 -14
  29. {FlashGBX-3.37 → FlashGBX-4.0.1}/setup.py +2 -2
  30. FlashGBX-3.37/FlashGBX/hw_GBxCartRW_ofw.py +0 -2599
  31. FlashGBX-3.37/FlashGBX/res/config.zip +0 -0
  32. FlashGBX-3.37/FlashGBX/res/fw_GBxCart_RW_v1_4.zip +0 -0
  33. FlashGBX-3.37/FlashGBX/res/fw_GBxCart_RW_v1_4a.zip +0 -0
  34. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/DataTransfer.py +0 -0
  35. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/PocketCamera.py +0 -0
  36. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/PocketCameraWindow.py +0 -0
  37. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/__init__.py +0 -0
  38. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/__main__.py +0 -0
  39. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/fw_GBxCartRW_v1_4.py +0 -0
  40. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/pyside.py +0 -0
  41. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/res/fw_GBxCart_RW_Mini_v1_0.zip +0 -0
  42. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/res/fw_GBxCart_RW_XMAS_v1_0.zip +0 -0
  43. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/res/fw_GBxCart_RW_v1_1_v1_2.zip +0 -0
  44. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/res/icon.ico +0 -0
  45. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/res/icon.png +0 -0
  46. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX/res/pc_frame.png +0 -0
  47. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX.egg-info/dependency_links.txt +0 -0
  48. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX.egg-info/entry_points.txt +0 -0
  49. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX.egg-info/requires.txt +0 -0
  50. {FlashGBX-3.37 → FlashGBX-4.0.1}/FlashGBX.egg-info/top_level.txt +0 -0
  51. {FlashGBX-3.37 → FlashGBX-4.0.1}/LICENSE +0 -0
  52. {FlashGBX-3.37 → FlashGBX-4.0.1}/MANIFEST.in +0 -0
  53. {FlashGBX-3.37 → FlashGBX-4.0.1}/setup.cfg +0 -0
@@ -2,7 +2,7 @@
2
2
  # FlashGBX
3
3
  # Author: Lesserkuma (github.com/lesserkuma)
4
4
 
5
- import sys, os, glob, re, json, zlib, argparse, zipfile, traceback, platform, datetime
5
+ import sys, os, glob, re, json, zlib, argparse, zipfile, traceback, platform, datetime, copy
6
6
  from . import Util
7
7
 
8
8
  def ReadConfigFiles(args):
@@ -33,7 +33,7 @@ def LoadConfig(args):
33
33
  (config_version, fc_files) = ReadConfigFiles(args=args)
34
34
  if config_version != Util.VERSION:
35
35
  # Rename old files that have since been replaced/renamed/merged
36
- deprecated_files = [ "fc_AGB_TEST.txt", "fc_DMG_TEST.txt", "fc_AGB_Nintendo_E201850.txt", "fc_AGB_Nintendo_E201868.txt", "config.ini", "fc_DMG_MX29LV320ABTC.txt", "fc_DMG_iG_4MB_MBC3_RTC.txt", "fc_AGB_Flash2Advance.txt", "fc_AGB_MX29LV640_AUDIO.txt", "fc_AGB_M36L0R7050T.txt", "fc_AGB_M36L0R8060B.txt", "fc_AGB_M36L0R8060T.txt", "fc_AGB_iG_32MB_S29GL512N.txt", "fc_DMG_SST39SF010_MBC1_AUDIO.txt", "fc_DMG_SST39SF040_MBC5_AUDIO.txt", "fc_DMG_AM29F010_MBC1_AUDIO.txt", "fc_DMG_AM29F040_MBC1_AUDIO.txt", "fc_DMG_AM29F040_MBC1_WR.txt", "fc_DMG_AM29F080_MBC1_AUDIO.txt", "fc_DMG_AM29F080_MBC1_WR.txt", "fc_DMG_SST39SF040_MBC1_AUDIO.txt", "fc_DMG_SST39SF020_MBC1_AUDIO.txt", "fc_DMG_29LV016T.txt" ]
36
+ deprecated_files = [ "fc_AGB_TEST.txt", "fc_DMG_TEST.txt", "fc_AGB_Nintendo_E201850.txt", "fc_AGB_Nintendo_E201868.txt", "config.ini", "fc_DMG_MX29LV320ABTC.txt", "fc_DMG_iG_4MB_MBC3_RTC.txt", "fc_AGB_Flash2Advance.txt", "fc_AGB_MX29LV640_AUDIO.txt", "fc_AGB_M36L0R7050T.txt", "fc_AGB_M36L0R8060B.txt", "fc_AGB_M36L0R8060T.txt", "fc_AGB_iG_32MB_S29GL512N.txt", "fc_DMG_SST39SF010_MBC1_AUDIO.txt", "fc_DMG_SST39SF040_MBC5_AUDIO.txt", "fc_DMG_AM29F010_MBC1_AUDIO.txt", "fc_DMG_AM29F040_MBC1_AUDIO.txt", "fc_DMG_AM29F040_MBC1_WR.txt", "fc_DMG_AM29F080_MBC1_AUDIO.txt", "fc_DMG_AM29F080_MBC1_WR.txt", "fc_DMG_SST39SF040_MBC1_AUDIO.txt", "fc_DMG_SST39SF020_MBC1_AUDIO.txt", "fc_DMG_29LV016T.txt", "fc_DMG_Retrostage.txt" ]
37
37
  for file in deprecated_files:
38
38
  if os.path.exists(config_path + "/" + file):
39
39
  os.rename(config_path + "/" + file, config_path + "/" + file + "_" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + ".bak")
@@ -71,14 +71,21 @@ def LoadConfig(args):
71
71
  if "names" not in specs: continue
72
72
  for name in specs["names"]:
73
73
  if not specs["type"] in flashcarts: continue # only DMG and AGB are supported right now
74
- flashcarts[specs["type"]][name] = specs
74
+ temp = copy.deepcopy(specs)
75
+ temp["names"] = [name]
76
+ flashcarts[specs["type"]][name] = temp
75
77
 
76
78
  return { "flashcarts":flashcarts, "config_ret":ret }
77
79
 
78
80
  class ArgParseCustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter): pass
79
81
  def main(portableMode=False):
80
- if platform.system() == "Windows": os.system("color")
81
- os.environ['QT_MAC_WANTS_LAYER'] = '1'
82
+ if platform.system() == "Windows":
83
+ os.system("color")
84
+ elif platform.system() == "Darwin":
85
+ macos_version = tuple(map(int, platform.mac_ver()[0].split('.')))
86
+ # macOS above Big Sur don't need a compat layer fix in the environment
87
+ if macos_version < (12, 0):
88
+ os.environ['QT_MAC_WANTS_LAYER'] = '1'
82
89
 
83
90
  print("{:s} {:s} by Lesserkuma".format(Util.APPNAME, Util.VERSION))
84
91
  print("https://github.com/lesserkuma/FlashGBX")
@@ -129,9 +136,9 @@ def main(portableMode=False):
129
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")
130
137
  ap_cli2.add_argument("--dmg-mbc", type=str.lower, default="auto", help="set memory bank controller type of Game Boy cartridge")
131
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")
132
- ap_cli2.add_argument("--agb-romsize", choices=["auto", "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")
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")
133
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")
134
- ap_cli2.add_argument("--store-rtc", action="store_true", help="store RTC register values if supported")
141
+ ap_cli2.add_argument("--store-rtc", action="store_true", default=False, help="store RTC register values if supported")
135
142
  ap_cli2.add_argument("--ignore-bad-header", action="store_true", help="don’t stop if invalid data found in cartridge header data")
136
143
  ap_cli2.add_argument("--flashcart-type", type=str, default="autodetect", help="name of flash cart; see txt files in config directory")
137
144
  ap_cli2.add_argument("--prefer-chip-erase", action="store_true", help="prefer full chip erase over sector erase when both available")
@@ -16,8 +16,8 @@ from .RomFileAGB import RomFileAGB
16
16
  from .PocketCamera import PocketCamera
17
17
  from .Util import APPNAME, ANSI
18
18
  from . import Util
19
- from . import hw_GBxCartRW, hw_GBxCartRW_ofw
20
- hw_devices = [hw_GBxCartRW, hw_GBxCartRW_ofw]
19
+ from . import hw_GBxCartRW, hw_GBFlash, hw_JoeyJr
20
+ hw_devices = [hw_GBxCartRW, hw_GBFlash, hw_JoeyJr]
21
21
 
22
22
  class FlashGBX_CLI():
23
23
  ARGS = {}
@@ -34,7 +34,7 @@ class FlashGBX_CLI():
34
34
  Util.APP_PATH = args['app_path']
35
35
  Util.CONFIG_PATH = args['config_path']
36
36
  self.FLASHCARTS = args["flashcarts"]
37
- self.PROGRESS = Util.Progress(self.UpdateProgress)
37
+ self.PROGRESS = Util.Progress(self.UpdateProgress, self.WaitProgress)
38
38
 
39
39
  global prog_bar_part_char
40
40
  if platform.system() == "Windows":
@@ -59,9 +59,9 @@ class FlashGBX_CLI():
59
59
  # Ask interactively if no args set
60
60
  if args.action is None:
61
61
  self.ARGS["called_with_args"] = False
62
- actions = ["info", "backup-rom", "flash-rom", "backup-save", "restore-save", "erase-save", "gbcamera-extract", "fwupdate-gbxcartrw", "debug-test-save"]
63
- print("Select Operation:\n 1) Read Cartridge Information\n 2) Backup ROM\n 3) Write ROM\n 4) Backup Save Data\n 5) Restore Save Data\n 6) Erase Save Data\n 7) Extract Game Boy Camera Pictures From Existing Save Data Backup\n 8) Firmware Update (for GBxCart RW v1.4/v1.4a only)\n")
64
- args.action = input("Enter number 1-8 [1]: ").lower().strip()
62
+ actions = ["info", "backup-rom", "flash-rom", "backup-save", "restore-save", "erase-save", "gbcamera-extract", "fwupdate-gbxcartrw", "fwupdate-gbflash", "fwupdate-joeyjr", "debug-test-save"]
63
+ print("Select Operation:\n 1) Read Cartridge Information\n 2) Backup ROM\n 3) Write ROM\n 4) Backup Save Data\n 5) Restore Save Data\n 6) Erase Save Data\n 7) Extract Game Boy Camera Pictures From Existing Save Data Backup\n 8) Firmware Update for GBxCart RW v1.4/v1.4a only\n 9) Firmware Update for GBFlash\n 10) Firmware Update for Joey Jr\n")
64
+ args.action = input("Enter number 1-10 [1]: ").lower().strip()
65
65
  try:
66
66
  if int(args.action) == 0:
67
67
  print("Canceled.")
@@ -76,7 +76,7 @@ class FlashGBX_CLI():
76
76
  else:
77
77
  self.ARGS["called_with_args"] = True
78
78
 
79
- if args.action is None or args.action not in ("gbcamera-extract", "fwupdate-gbxcartrw"):
79
+ if args.action is None or args.action not in ("gbcamera-extract", "fwupdate-gbxcartrw", "fwupdate-gbflash", "fwupdate-joeyjr"):
80
80
  if not self.FindDevices(port=args.device_port):
81
81
  print("No devices found.")
82
82
  return
@@ -86,11 +86,19 @@ class FlashGBX_CLI():
86
86
  return
87
87
  dev = self.DEVICE[1]
88
88
  builddate = dev.GetFWBuildDate()
89
+
90
+ if dev.FirmwareUpdateAvailable() and dev.FW_UPDATE_REQ is True:
91
+ print("The current firmware version of your device is not supported.\nPlease update the a supported firmware version first.")
92
+ return
93
+
89
94
  if builddate != "":
90
95
  print("\nConnected to {:s}".format(dev.GetFullNameExtended(more=True)))
91
96
  else:
92
97
  print("\nConnected to {:s}".format(dev.GetFullNameExtended()))
93
-
98
+
99
+ self.CONN.SetAutoPowerOff(value=1500)
100
+ self.CONN.SetAGBReadMethod(method=2)
101
+
94
102
  if args.action == "gbcamera-extract":
95
103
  if args.path == "auto":
96
104
  args.path = input("Enter file path of Game Boy Camera save data file: ").strip().replace("\"", "")
@@ -121,6 +129,14 @@ class FlashGBX_CLI():
121
129
  self.UpdateFirmwareGBxCartRW(pcb=5, port=args.device_port)
122
130
  return 0
123
131
 
132
+ if args.action == "fwupdate-gbflash":
133
+ self.UpdateFirmwareGBFlash(port=args.device_port)
134
+ return 0
135
+
136
+ if args.action == "fwupdate-joeyjr":
137
+ self.UpdateFirmwareJoeyJr(port=args.device_port)
138
+ return 0
139
+
124
140
  elif args.mode is None:
125
141
  print("Select Cartridge Mode:\n 1) Game Boy or Game Boy Color\n 2) Game Boy Advance\n")
126
142
  answer = input("Enter number 1-2 [2]: ").lower().strip()
@@ -201,6 +217,17 @@ class FlashGBX_CLI():
201
217
  self.DisconnectDevice()
202
218
  return 0
203
219
 
220
+ def WaitProgress(self, args):
221
+ if args["user_action"] == "REINSERT_CART":
222
+ msg = "\n\n"
223
+ msg += args["msg"]
224
+ msg += "\n\nPress ENTER or RETURN to continue.\n"
225
+ answer = input(msg).strip().lower()
226
+ if len(answer.strip()) != 0:
227
+ self.CONN.USER_ANSWER = False
228
+ else:
229
+ self.CONN.USER_ANSWER = True
230
+
204
231
  def UpdateProgress(self, args):
205
232
  if args is None: return
206
233
 
@@ -283,6 +310,10 @@ class FlashGBX_CLI():
283
310
  print("{:s}The ROM was written and verified successfully!{:s}".format(ANSI.GREEN, ANSI.RESET))
284
311
  else:
285
312
  print("ROM writing complete!")
313
+
314
+ if "verified" in self.PROGRESS.PROGRESS and self.PROGRESS.PROGRESS["verified"] != True:
315
+ print(self.PROGRESS.PROGRESS)
316
+ input("An error occured.")
286
317
 
287
318
  elif self.CONN.INFO["last_action"] == 1: # Backup ROM
288
319
  self.CONN.INFO["last_action"] = 0
@@ -377,7 +408,7 @@ class FlashGBX_CLI():
377
408
  global hw_devices
378
409
  for hw_device in hw_devices:
379
410
  dev = hw_device.GbxDevice()
380
- ret = dev.Initialize(self.FLASHCARTS, port=port, max_baud=1000000 if self.ARGS["argparsed"].device_limit_baudrate else 1700000)
411
+ ret = dev.Initialize(self.FLASHCARTS, port=port, max_baud=1000000 if self.ARGS["argparsed"].device_limit_baudrate else 2000000)
381
412
  if ret is False:
382
413
  self.CONN = None
383
414
  elif isinstance(ret, list):
@@ -396,11 +427,11 @@ class FlashGBX_CLI():
396
427
 
397
428
  if self.DEVICE is None: return False
398
429
  return True
399
-
430
+
400
431
  def ConnectDevice(self):
401
432
  dev = self.DEVICE[1]
402
433
  port = dev.GetPort()
403
- ret = dev.Initialize(self.FLASHCARTS, port=port, max_baud=1000000 if self.ARGS["argparsed"].device_limit_baudrate else 1700000)
434
+ ret = dev.Initialize(self.FLASHCARTS, port=port, max_baud=1000000 if self.ARGS["argparsed"].device_limit_baudrate else 2000000)
404
435
 
405
436
  if ret is False:
406
437
  print("\n{:s}An error occured while trying to connect to the device.{:s}".format(ANSI.RED, ANSI.RESET))
@@ -424,7 +455,7 @@ class FlashGBX_CLI():
424
455
  return False
425
456
 
426
457
  if dev.FW_UPDATE_REQ:
427
- print("{:s}A firmware update for your {:s} device is required to fully use this software.\nPlease visit the official website at {:s} for updates.\n{:s}Current firmware version: {:s}{:s}".format(ANSI.RED, dev.GetFullName(), dev.GetOfficialWebsite(), ANSI.YELLOW, dev.GetFirmwareVersion(), ANSI.RESET))
458
+ print("{:s}A firmware update for your {:s} device is required to fully use this software.\n{:s}Current firmware version: {:s}{:s}".format(ANSI.RED, dev.GetFullName(), ANSI.YELLOW, dev.GetFirmwareVersion(), ANSI.RESET))
428
459
  time.sleep(5)
429
460
 
430
461
  self.CONN = dev
@@ -433,6 +464,7 @@ class FlashGBX_CLI():
433
464
  def DisconnectDevice(self):
434
465
  try:
435
466
  devname = self.CONN.GetFullNameExtended()
467
+ self.CONN.SetAutoPowerOff(value=0)
436
468
  self.CONN.Close(cartPowerOff=True)
437
469
  print("Disconnected from {:s}".format(devname))
438
470
  except:
@@ -575,9 +607,9 @@ class FlashGBX_CLI():
575
607
  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():
576
608
  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))
577
609
 
578
- if "has_rtc" in data and data["has_rtc"] is not True and "no_rtc_reason" in data:
579
- if data["no_rtc_reason"] == 1:
580
- 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))
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))
581
613
 
582
614
  return (bad_read, s, data)
583
615
 
@@ -642,7 +674,6 @@ class FlashGBX_CLI():
642
674
  msg_flash_size_s = ""
643
675
  msg_flash_mapper_s = ""
644
676
  if cart_type is not None:
645
- (flash_id, cfi_s, _) = self.CONN.CheckFlashChip(limitVoltage=limitVoltage, cart_type=supp_cart_types[1][cart_type])
646
677
  msg_cart_type_s = "Cartridge Type: Supported flash cartridge – compatible with:\n{:s}\n".format(msg_cart_type)
647
678
 
648
679
  if detected_size > 0:
@@ -662,9 +693,8 @@ class FlashGBX_CLI():
662
693
  msg_flash_mapper_s = "Mapper Type: Default (MBC5)\n"
663
694
 
664
695
  else:
665
- (flash_id, cfi_s, _) = self.CONN.CheckFlashChip(limitVoltage=limitVoltage)
666
696
  if (len(flash_id.split("\n")) > 2) and ((self.CONN.GetMode() == "DMG") or ("dacs_8m" in header and header["dacs_8m"] is not True)):
667
- msg_cart_type_s = "<b>Cartridge Type:</b> Unknown flash cartridge – Please submit the displayed information along with a picture of the cartridge’s circuit board."
697
+ msg_cart_type_s = "Cartridge Type: Unknown flash cartridge."
668
698
  if ("[ 0/90]" in flash_id):
669
699
  try_this = "Generic Flash Cartridge (0/90)"
670
700
  elif ("[ AAA/AA]" in flash_id):
@@ -744,7 +774,7 @@ class FlashGBX_CLI():
744
774
  if args.agb_romsize == "auto":
745
775
  rom_size = header["rom_size"]
746
776
  else:
747
- sizes = [ "auto", "64kb", "128kb", "256kb", "512kb", "1mb", "2mb", "4mb", "8mb", "16mb", "32mb", "64mb", "128mb", "256mb", "512mb" ]
777
+ sizes = [ "auto", "32kb", "64kb", "128kb", "256kb", "512kb", "1mb", "2mb", "4mb", "8mb", "16mb", "32mb", "64mb", "128mb", "256mb", "512mb" ]
748
778
  rom_size = Util.AGB_Header_ROM_Sizes_Map[sizes.index(args.agb_romsize) - 1]
749
779
 
750
780
  if args.path != "auto":
@@ -807,9 +837,10 @@ class FlashGBX_CLI():
807
837
  if "flash_type" in header:
808
838
  print("Selected cartridge type: {:s}\n".format(cart_types[0][header["flash_type"]]))
809
839
  cart_type = header["flash_type"]
810
- elif header['logo_correct'] and header['3d_memory'] is True:
840
+ elif header['logo_correct']:
811
841
  for i in range(0, len(cart_types[0])):
812
- if "3d_memory" in cart_types[1][i]:
842
+ if ((header['3d_memory'] is True and "3d_memory" in cart_types[1][i]) or
843
+ (header['vast_fame'] is True and "vast_fame" in cart_types[1][i])):
813
844
  print("Selected cartridge type: {:s}\n".format(cart_types[0][i]))
814
845
  cart_type = i
815
846
  break
@@ -1069,6 +1100,7 @@ class FlashGBX_CLI():
1069
1100
 
1070
1101
  if (path == ""): return
1071
1102
 
1103
+ buffer = None
1072
1104
  s_mbc = ""
1073
1105
  if self.CONN.GetMode() == "DMG":
1074
1106
  if mbc in Util.DMG_Header_Mapper:
@@ -1102,7 +1134,6 @@ class FlashGBX_CLI():
1102
1134
 
1103
1135
  if self.CONN.GetMode() == "AGB":
1104
1136
  if args.action == "restore-save" or args.action == "erase-save":
1105
- buffer = None
1106
1137
  if self.CONN.GetMode() == "AGB" and "ereader" in self.CONN.INFO and self.CONN.INFO["ereader"] is True:
1107
1138
  if self.CONN.GetFWBuildDate() == "": # Legacy Mode
1108
1139
  print("This cartridge is not supported in Legacy Mode.")
@@ -1227,7 +1258,7 @@ class FlashGBX_CLI():
1227
1258
  except:
1228
1259
  pass
1229
1260
 
1230
- def UpdateFirmwareGBxCartRW_PrintText(self, text, enableUI=False, setProgress=None):
1261
+ def UpdateFirmware_PrintText(self, text, enableUI=False, setProgress=None):
1231
1262
  if setProgress is not None:
1232
1263
  self.FWUPD_R = True
1233
1264
  print("\r{:s} ({:d}%)".format(text, int(setProgress)), flush=True, end="")
@@ -1284,7 +1315,7 @@ class FlashGBX_CLI():
1284
1315
  print("Using port {:s}.\n".format(port))
1285
1316
  FirmwareUpdater = fw_GBxCartRW_v1_4.FirmwareUpdater
1286
1317
  FWUPD = FirmwareUpdater(port=port)
1287
- ret = FWUPD.WriteFirmware(file_name, self.UpdateFirmwareGBxCartRW_PrintText)
1318
+ ret = FWUPD.WriteFirmware(file_name, self.UpdateFirmware_PrintText)
1288
1319
  break
1289
1320
  except serial.serialutil.SerialException:
1290
1321
  port = input("Couldn’t access port {:s}.\nEnter new port: ".format(port)).strip()
@@ -1310,3 +1341,149 @@ class FlashGBX_CLI():
1310
1341
  traceback.print_exception(type(err), err, err.__traceback__)
1311
1342
  print(err)
1312
1343
  return False
1344
+
1345
+ def UpdateFirmwareGBFlash(self, port=False):
1346
+ print("\nFirmware Updater for GBFlash")
1347
+ print("==============================")
1348
+ print("Supported revisions: v1.0, v1.1, v1.2, v1.3\n")
1349
+ file_name = Util.APP_PATH + "/res/fw_GBFlash.zip"
1350
+
1351
+ with zipfile.ZipFile(file_name) as zf:
1352
+ with zf.open("fw.ini") as f: ini_file = f.read()
1353
+ ini_file = ini_file.decode(encoding="utf-8")
1354
+ self.INI = Util.IniSettings(ini=ini_file, main_section="Firmware")
1355
+ fw_ver = self.INI.GetValue("fw_ver")
1356
+ fw_buildts = self.INI.GetValue("fw_buildts")
1357
+
1358
+ print("Available firmware version:\n{:s}\n".format("{:s} ({:s})".format(fw_ver, datetime.datetime.fromtimestamp(int(fw_buildts)).astimezone().replace(microsecond=0).isoformat())))
1359
+ print("Please follow these steps to proceed with the firmware update:\n1. Unplug your GBFlash device.\n2. On your GBFlash circuit board, push and hold the small button (U22) while plugging the USB cable back in.\n3. If done right, the blue LED labeled “ACT” should now keep blinking twice.\n4. Press ENTER or RETURN to continue.")
1360
+ if len(input("").strip()) != 0:
1361
+ print("Canceled.")
1362
+ return False
1363
+
1364
+ try:
1365
+ ports = []
1366
+ if port is None or port is False:
1367
+ comports = serial.tools.list_ports.comports()
1368
+ for i in range(0, len(comports)):
1369
+ if comports[i].vid == 0x1A86 and comports[i].pid == 0x7523:
1370
+ ports.append(comports[i].device)
1371
+ if len(ports) == 0:
1372
+ print("No device found.")
1373
+ return False
1374
+ port = ports[0]
1375
+
1376
+ from . import fw_GBFlash
1377
+ while True:
1378
+ try:
1379
+ print("Using port {:s}.\n".format(port))
1380
+ FirmwareUpdater = fw_GBFlash.FirmwareUpdater
1381
+ FWUPD = FirmwareUpdater(port=port)
1382
+ ret = FWUPD.WriteFirmware(file_name, self.UpdateFirmware_PrintText)
1383
+ break
1384
+ except serial.serialutil.SerialException:
1385
+ port = input("Couldn’t access port {:s}.\nEnter new port: ".format(port)).strip()
1386
+ if len(port) == 0:
1387
+ print("Canceled.")
1388
+ return False
1389
+ continue
1390
+ except Exception as err:
1391
+ traceback.print_exception(type(err), err, err.__traceback__)
1392
+ print(err)
1393
+ return False
1394
+
1395
+ if ret == 1:
1396
+ print("The firmware update is complete!")
1397
+ return True
1398
+ elif ret == 3:
1399
+ print("Please re-install the application.")
1400
+ return False
1401
+ else:
1402
+ return False
1403
+
1404
+ except Exception as err:
1405
+ traceback.print_exception(type(err), err, err.__traceback__)
1406
+ print(err)
1407
+ return False
1408
+
1409
+ def UpdateFirmwareJoeyJr(self, port=False):
1410
+ print("\nFirmware Updater for Joey Jr")
1411
+ print("==============================")
1412
+ file_name = Util.APP_PATH + "/res/fw_JoeyJr.zip"
1413
+
1414
+ with zipfile.ZipFile(file_name) as zf:
1415
+ with zf.open("fw.ini") as f: ini_file = f.read()
1416
+ ini_file = ini_file.decode(encoding="utf-8")
1417
+ 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")
1420
+
1421
+ 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
+ answer = input("Enter number 1-3: ").lower().strip()
1423
+ print("")
1424
+ if answer == "1":
1425
+ fw_choice = 1
1426
+ elif answer == "2":
1427
+ fw_choice = 2
1428
+ elif answer == "3":
1429
+ fw_choice = 3
1430
+ else:
1431
+ fw_choice = 0
1432
+
1433
+ if fw_choice == 0:
1434
+ print("Canceled.")
1435
+ return False
1436
+
1437
+ try:
1438
+ ports = []
1439
+ if port is None or port is False:
1440
+ comports = serial.tools.list_ports.comports()
1441
+ for i in range(0, len(comports)):
1442
+ if comports[i].vid == 0x483 and comports[i].pid == 0x5740:
1443
+ ports.append(comports[i].device)
1444
+ if len(ports) == 0:
1445
+ print("No device found. If you use the Drag’n’Drop firmware, please update to JoeyGUI first.")
1446
+ return False
1447
+ port = ports[0]
1448
+
1449
+ from . import fw_JoeyJr
1450
+ while True:
1451
+ try:
1452
+ print("Using port {:s}.\n".format(port))
1453
+ FirmwareUpdater = fw_JoeyJr.FirmwareUpdater
1454
+ FWUPD = FirmwareUpdater(port=port)
1455
+ file_name = Util.APP_PATH + "/res/fw_JoeyJr.zip"
1456
+ with zipfile.ZipFile(file_name) as archive:
1457
+ if fw_choice == 1:
1458
+ with archive.open("FIRMWARE_LK.JR") as f: fw_data = bytearray(f.read())
1459
+ elif fw_choice == 2:
1460
+ with archive.open("FIRMWARE_MSC.JR") as f: fw_data = bytearray(f.read())
1461
+ elif fw_choice == 3:
1462
+ with archive.open("FIRMWARE_JOEYGUI.JR") as f: fw_data = bytearray(f.read())
1463
+
1464
+ ret = FWUPD.WriteFirmware(fw_data, self.UpdateFirmware_PrintText)
1465
+ break
1466
+ except serial.serialutil.SerialException:
1467
+ port = input("Couldn’t access port {:s}.\nEnter new port: ".format(port)).strip()
1468
+ if len(port) == 0:
1469
+ print("Canceled.")
1470
+ return False
1471
+ continue
1472
+ except Exception as err:
1473
+ traceback.print_exception(type(err), err, err.__traceback__)
1474
+ print(err)
1475
+ return False
1476
+
1477
+ if ret == 1:
1478
+ print("The firmware update is complete!")
1479
+ return True
1480
+ elif ret == 3:
1481
+ print("Please re-install the application.")
1482
+ return False
1483
+ else:
1484
+ return False
1485
+
1486
+ except Exception as err:
1487
+ traceback.print_exception(type(err), err, err.__traceback__)
1488
+ print(err)
1489
+ return False