FlashGBX 3.37__py3-none-any.whl → 4.0.1__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/FlashGBX.py +14 -7
- FlashGBX/FlashGBX_CLI.py +201 -24
- FlashGBX/FlashGBX_GUI.py +636 -204
- FlashGBX/Flashcart.py +184 -83
- FlashGBX/GBMemory.py +4 -5
- FlashGBX/LK_Device.py +4533 -0
- FlashGBX/Mapper.py +534 -356
- FlashGBX/RomFileAGB.py +92 -2
- FlashGBX/RomFileDMG.py +1 -1
- FlashGBX/UserInputDialog.py +20 -0
- FlashGBX/Util.py +95 -47
- FlashGBX/fw_GBFlash.py +426 -0
- FlashGBX/fw_GBxCartRW_v1_3.py +1 -1
- FlashGBX/fw_JoeyJr.py +472 -0
- FlashGBX/hw_GBFlash.py +244 -0
- FlashGBX/hw_GBxCartRW.py +200 -3777
- FlashGBX/hw_JoeyJr.py +309 -0
- FlashGBX/res/Third Party Notices.md +342 -0
- FlashGBX/res/config.zip +0 -0
- FlashGBX/res/fw_GBFlash.zip +0 -0
- FlashGBX/res/fw_GBxCart_RW_v1_3.zip +0 -0
- FlashGBX/res/fw_GBxCart_RW_v1_4.zip +0 -0
- FlashGBX/res/fw_GBxCart_RW_v1_4a.zip +0 -0
- FlashGBX/res/fw_JoeyJr.zip +0 -0
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/METADATA +36 -16
- FlashGBX-4.0.1.dist-info/RECORD +43 -0
- FlashGBX/hw_GBxCartRW_ofw.py +0 -2599
- FlashGBX-3.37.dist-info/RECORD +0 -36
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/LICENSE +0 -0
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/WHEEL +0 -0
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/entry_points.txt +0 -0
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/top_level.txt +0 -0
FlashGBX/FlashGBX.py
CHANGED
|
@@ -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
|
-
|
|
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":
|
|
81
|
-
|
|
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")
|
FlashGBX/FlashGBX_CLI.py
CHANGED
|
@@ -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,
|
|
20
|
-
hw_devices = [hw_GBxCartRW,
|
|
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
|
|
64
|
-
args.action = input("Enter number 1-
|
|
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
|
|
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
|
|
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.\
|
|
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
|
-
|
|
580
|
-
|
|
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 = "
|
|
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']
|
|
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
|
|
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.
|
|
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
|