FlashGBX 4.0.1__py3-none-any.whl → 4.2__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_GUI.py +12 -27
- FlashGBX/GBMemory.py +35 -29
- FlashGBX/LK_Device.py +37 -25
- FlashGBX/Mapper.py +2 -57
- FlashGBX/Util.py +3 -3
- FlashGBX/fw_JoeyJr.py +35 -15
- FlashGBX/hw_GBFlash.py +1 -1
- FlashGBX/hw_GBxCartRW.py +8 -1
- FlashGBX/hw_JoeyJr.py +1 -1
- FlashGBX/res/config.zip +0 -0
- FlashGBX/res/fw_GBFlash.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-4.0.1.dist-info → FlashGBX-4.2.dist-info}/METADATA +7 -6
- {FlashGBX-4.0.1.dist-info → FlashGBX-4.2.dist-info}/RECORD +20 -20
- {FlashGBX-4.0.1.dist-info → FlashGBX-4.2.dist-info}/LICENSE +0 -0
- {FlashGBX-4.0.1.dist-info → FlashGBX-4.2.dist-info}/WHEEL +0 -0
- {FlashGBX-4.0.1.dist-info → FlashGBX-4.2.dist-info}/entry_points.txt +0 -0
- {FlashGBX-4.0.1.dist-info → FlashGBX-4.2.dist-info}/top_level.txt +0 -0
FlashGBX/FlashGBX_GUI.py
CHANGED
|
@@ -183,22 +183,11 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
183
183
|
self.layout_devices.addWidget(self.cmbDevice)
|
|
184
184
|
self.layout_devices.addStretch()
|
|
185
185
|
|
|
186
|
-
#btnText = "Too&ls"
|
|
187
|
-
#self.btnTools = QtWidgets.QPushButton(btnText)
|
|
188
|
-
#btnWidth = self.btnTools.fontMetrics().boundingRect(btnText).width() + 24
|
|
189
|
-
#if platform.system() == "Darwin": btnWidth += 12
|
|
190
|
-
#self.btnTools.setMaximumWidth(btnWidth)
|
|
191
186
|
self.mnuTools = QtWidgets.QMenu("&Tools")
|
|
192
187
|
self.mnuTools.addAction("Game Boy &Camera Album Viewer", self.ShowPocketCameraWindow)
|
|
193
188
|
self.mnuTools.addSeparator()
|
|
194
189
|
self.mnuTools.addAction("Firmware &Updater", self.ShowFirmwareUpdateWindow)
|
|
195
|
-
#self.btnTools.setMenu(self.mnuTools)
|
|
196
190
|
|
|
197
|
-
#btnText = "C&onfig"
|
|
198
|
-
#self.btnConfig = QtWidgets.QPushButton(btnText)
|
|
199
|
-
#btnWidth = self.btnConfig.fontMetrics().boundingRect(btnText).width() + 24
|
|
200
|
-
#if platform.system() == "Darwin": btnWidth += 12
|
|
201
|
-
#self.btnConfig.setMaximumWidth(btnWidth)
|
|
202
191
|
self.mnuConfig = QtWidgets.QMenu("&Settings")
|
|
203
192
|
self.mnuConfig.addAction("Check for &updates on application startup", lambda: [ self.EnableUpdateCheck() ])
|
|
204
193
|
self.mnuConfig.addAction("&Append date && time to filename of save data backups", lambda: self.SETTINGS.setValue("SaveFileNameAddDateTime", str(self.mnuConfig.actions()[1].isChecked()).lower().replace("true", "enabled").replace("false", "disabled")))
|
|
@@ -249,10 +238,10 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
249
238
|
self.mnuConfig.actions()[7].setChecked(self.SETTINGS.value("UseNoIntroFilenames", default="enabled") == "enabled")
|
|
250
239
|
self.mnuConfig.actions()[8].setChecked(self.SETTINGS.value("AutoPowerOff", default="350") != "0")
|
|
251
240
|
self.mnuConfig.actions()[9].setChecked(self.SETTINGS.value("CompareSectors", default="enabled") == "enabled")
|
|
252
|
-
#self.btnConfig.setMenu(self.mnuConfig)
|
|
253
241
|
|
|
254
242
|
self.mnuThirdParty = QtWidgets.QMenu("Third Party &Notices")
|
|
255
243
|
self.mnuThirdParty.addAction("About &Qt", lambda: [ QtWidgets.QMessageBox.aboutQt(None) ])
|
|
244
|
+
self.mnuThirdParty.addAction("About Game &Database", self.AboutGameDB)
|
|
256
245
|
self.mnuThirdParty.addAction("Licenses", lambda: [ self.OpenPath(Util.APP_PATH + "/res/Third Party Notices.md") ])
|
|
257
246
|
|
|
258
247
|
btnText = "&Options"
|
|
@@ -274,8 +263,6 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
274
263
|
self.btnConnect = QtWidgets.QPushButton("&Connect")
|
|
275
264
|
self.connect(self.btnConnect, QtCore.SIGNAL("clicked()"), self.ConnectDevice)
|
|
276
265
|
self.layout_devices.addWidget(self.btnMainMenu)
|
|
277
|
-
#self.layout_devices.addWidget(self.btnTools)
|
|
278
|
-
#self.layout_devices.addWidget(self.btnConfig)
|
|
279
266
|
self.layout_devices.addWidget(self.btnConnect)
|
|
280
267
|
|
|
281
268
|
self.layout.addLayout(self.layout_devices, 1, 0, 1, 0)
|
|
@@ -355,12 +342,6 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
355
342
|
lblDMGHeaderRtc.setContentsMargins(0, 1, 0, 1)
|
|
356
343
|
rowDMGHeaderRtc.addWidget(lblDMGHeaderRtc)
|
|
357
344
|
self.lblDMGHeaderRtcResult = QtWidgets.QLabel("")
|
|
358
|
-
#self.lblDMGHeaderRtcResult.setCursor(QtGui.QCursor(QtCore.Qt.WhatsThisCursor))
|
|
359
|
-
#self.lblDMGHeaderRtcResult.setToolTip("This shows the internal register values; in-game clock may use an offset")
|
|
360
|
-
#self.lblDMGHeaderRtcResult.setStyleSheet("QLabel {{ color: {:s}; text-decoration: underline; cursor: hand; }}".format(QApplication.palette().color(QtGui.QPalette.Link).name()))
|
|
361
|
-
#self.lblDMGHeaderRtcResult.setCursor(QtCore.Qt.PointingHandCursor)
|
|
362
|
-
#self.connect(self.lblDMGHeaderRtcResult, QtCore.SIGNAL("clicked()"), self.EditRTC)
|
|
363
|
-
#self.lblDMGHeaderRtcResult.clicked.connect(self.EditRTC)
|
|
364
345
|
self.lblDMGHeaderRtcResult.mousePressEvent = lambda event: [ self.EditRTC(event) ]
|
|
365
346
|
rowDMGHeaderRtc.addWidget(self.lblDMGHeaderRtcResult)
|
|
366
347
|
rowDMGHeaderRtc.setStretch(0, 9)
|
|
@@ -475,8 +456,6 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
475
456
|
lblAGBGpioRtc.setContentsMargins(0, 1, 0, 1)
|
|
476
457
|
rowAGBGpioRtc.addWidget(lblAGBGpioRtc)
|
|
477
458
|
self.lblAGBGpioRtcResult = QtWidgets.QLabel("")
|
|
478
|
-
#self.lblAGBGpioRtcResult.setCursor(QtGui.QCursor(QtCore.Qt.WhatsThisCursor))
|
|
479
|
-
#self.lblAGBGpioRtcResult.setToolTip(self.lblDMGHeaderRtcResult.toolTip())
|
|
480
459
|
self.lblAGBGpioRtcResult.mousePressEvent = lambda event: [ self.EditRTC(event) ]
|
|
481
460
|
rowAGBGpioRtc.addWidget(self.lblAGBGpioRtcResult)
|
|
482
461
|
rowAGBGpioRtc.setStretch(0, 9)
|
|
@@ -731,7 +710,13 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
731
710
|
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>"
|
|
732
711
|
msg += f"© 2020–{datetime.datetime.now().year} Lesserkuma<br>"
|
|
733
712
|
msg += "• Website: <a href=\"https://github.com/lesserkuma/FlashGBX\">https://github.com/lesserkuma/FlashGBX</a><br><br>"
|
|
734
|
-
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, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, Jayro, Jenetrix, JFox, joyrider3774, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, olDirdey, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, 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"
|
|
713
|
+
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, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, 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"
|
|
714
|
+
QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), msg, QtWidgets.QMessageBox.Ok)
|
|
715
|
+
|
|
716
|
+
def AboutGameDB(self):
|
|
717
|
+
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>"
|
|
718
|
+
msg += f"No-Intro databases referenced for this version of {APPNAME}:<br>"
|
|
719
|
+
msg += "• Nintendo - Game Boy (20240713-090345)<br>• Nintendo - Game Boy Advance (20240803-104002)<br>• Nintendo - Game Boy Advance (Video) (20240727-194101)<br>• Nintendo - Game Boy Color (20240801-100010)" # No-Intro DBs
|
|
735
720
|
QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), msg, QtWidgets.QMessageBox.Ok)
|
|
736
721
|
|
|
737
722
|
def OpenPath(self, path=None):
|
|
@@ -926,7 +911,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
926
911
|
qt_app.processEvents()
|
|
927
912
|
|
|
928
913
|
messages = []
|
|
929
|
-
last_msg = ""
|
|
914
|
+
#last_msg = ""
|
|
930
915
|
|
|
931
916
|
# pylint: disable=global-variable-not-assigned
|
|
932
917
|
global hw_devices
|
|
@@ -948,8 +933,8 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
948
933
|
msg = ret[i][1]
|
|
949
934
|
if msg in messages: # don’t show the same message twice
|
|
950
935
|
continue
|
|
951
|
-
else:
|
|
952
|
-
|
|
936
|
+
#else:
|
|
937
|
+
# last_msg = msg
|
|
953
938
|
if status == 3:
|
|
954
939
|
messages.append(msg)
|
|
955
940
|
self.CONN = None
|
|
@@ -961,7 +946,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
961
946
|
if dev.IsConnected():
|
|
962
947
|
self.DEVICES[dev.GetFullNameExtended()] = dev
|
|
963
948
|
if dev.GetPort() in ports: break
|
|
964
|
-
|
|
949
|
+
|
|
965
950
|
for dev in self.DEVICES.values():
|
|
966
951
|
dev.Close()
|
|
967
952
|
|
FlashGBX/GBMemory.py
CHANGED
|
@@ -118,24 +118,27 @@ class GBMemoryMap:
|
|
|
118
118
|
else:
|
|
119
119
|
rom_size = 0b101
|
|
120
120
|
|
|
121
|
-
if
|
|
122
|
-
|
|
123
|
-
sram_type = 0b000
|
|
121
|
+
if mbc_type == 2:
|
|
122
|
+
sram_type = 0b010
|
|
124
123
|
else:
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
if info["rom_header"]["ram_size_raw"] not in Util.DMG_Header_RAM_Sizes_Map:
|
|
125
|
+
sram_size = 0
|
|
127
126
|
sram_type = 0b000
|
|
128
|
-
elif sram_size == 0x2000:
|
|
129
|
-
sram_type = 0b010
|
|
130
|
-
elif sram_size == 0x8000:
|
|
131
|
-
sram_type = 0b011
|
|
132
|
-
elif sram_size == 0x10000:
|
|
133
|
-
sram_type = 0b100
|
|
134
|
-
elif sram_size == 0x20000:
|
|
135
|
-
sram_type = 0b101
|
|
136
127
|
else:
|
|
137
|
-
|
|
138
|
-
|
|
128
|
+
sram_size = Util.DMG_Header_RAM_Sizes_Flasher_Map[Util.DMG_Header_RAM_Sizes_Map.index(info["rom_header"]["ram_size_raw"])]
|
|
129
|
+
if sram_size == 0:
|
|
130
|
+
sram_type = 0b000
|
|
131
|
+
elif sram_size == 0x2000:
|
|
132
|
+
sram_type = 0b010
|
|
133
|
+
elif sram_size == 0x8000:
|
|
134
|
+
sram_type = 0b011
|
|
135
|
+
elif sram_size == 0x10000:
|
|
136
|
+
sram_type = 0b100
|
|
137
|
+
elif sram_size == 0x20000:
|
|
138
|
+
sram_type = 0b101
|
|
139
|
+
else:
|
|
140
|
+
sram_type = 0b000
|
|
141
|
+
|
|
139
142
|
info["map"] = {
|
|
140
143
|
"mbc_type":mbc_type,
|
|
141
144
|
"rom_size":rom_size,
|
|
@@ -236,23 +239,26 @@ class GBMemoryMap:
|
|
|
236
239
|
else:
|
|
237
240
|
rom_size = 0b101
|
|
238
241
|
|
|
239
|
-
if
|
|
240
|
-
|
|
241
|
-
sram_type = 0b000
|
|
242
|
+
if mbc_type == 2:
|
|
243
|
+
sram_type = 0b010
|
|
242
244
|
else:
|
|
243
|
-
|
|
244
|
-
|
|
245
|
+
if info["rom_header"]["game_title"] == "NP M-MENU MENU" or info["rom_header"]["ram_size_raw"] not in Util.DMG_Header_RAM_Sizes_Map:
|
|
246
|
+
sram_size = 0
|
|
245
247
|
sram_type = 0b000
|
|
246
|
-
elif sram_size == 0x2000:
|
|
247
|
-
sram_type = 0b010
|
|
248
|
-
elif sram_size == 0x8000:
|
|
249
|
-
sram_type = 0b011
|
|
250
|
-
elif sram_size == 0x10000:
|
|
251
|
-
sram_type = 0b100
|
|
252
|
-
elif sram_size == 0x20000:
|
|
253
|
-
sram_type = 0b101
|
|
254
248
|
else:
|
|
255
|
-
|
|
249
|
+
sram_size = Util.DMG_Header_RAM_Sizes_Flasher_Map[Util.DMG_Header_RAM_Sizes_Map.index(info["rom_header"]["ram_size_raw"])]
|
|
250
|
+
if sram_size == 0:
|
|
251
|
+
sram_type = 0b000
|
|
252
|
+
elif sram_size == 0x2000:
|
|
253
|
+
sram_type = 0b010
|
|
254
|
+
elif sram_size == 0x8000:
|
|
255
|
+
sram_type = 0b011
|
|
256
|
+
elif sram_size == 0x10000:
|
|
257
|
+
sram_type = 0b100
|
|
258
|
+
elif sram_size == 0x20000:
|
|
259
|
+
sram_type = 0b101
|
|
260
|
+
else:
|
|
261
|
+
sram_type = 0b000
|
|
256
262
|
|
|
257
263
|
info["map"] = {
|
|
258
264
|
"mbc_type":mbc_type,
|
FlashGBX/LK_Device.py
CHANGED
|
@@ -420,14 +420,16 @@ class LK_Device(ABC):
|
|
|
420
420
|
retries -= 1
|
|
421
421
|
dprint("Retries left:", retries)
|
|
422
422
|
|
|
423
|
-
hp =
|
|
423
|
+
hp = 20
|
|
424
424
|
temp = 0
|
|
425
425
|
while temp not in (1, 2) and hp > 0:
|
|
426
|
+
self.DEVICE.reset_output_buffer()
|
|
427
|
+
self.DEVICE.reset_input_buffer()
|
|
426
428
|
self.DEVICE.write(b'\x00')
|
|
427
429
|
temp = self._read(1)
|
|
428
|
-
dprint("Current response:", temp)
|
|
429
430
|
hp -= 1
|
|
430
|
-
|
|
431
|
+
dprint("Current response:", temp, ", HP:", hp)
|
|
432
|
+
#if hp == 0: break
|
|
431
433
|
return False
|
|
432
434
|
|
|
433
435
|
def _write(self, data, wait=False):
|
|
@@ -533,9 +535,9 @@ class LK_Device(ABC):
|
|
|
533
535
|
buffer.extend(struct.pack(">I", value))
|
|
534
536
|
|
|
535
537
|
if self.FW["fw_ver"] >= 12:
|
|
536
|
-
self._try_write(buffer)
|
|
538
|
+
return self._try_write(buffer)
|
|
537
539
|
else:
|
|
538
|
-
self._write(buffer)
|
|
540
|
+
return self._write(buffer)
|
|
539
541
|
|
|
540
542
|
def _cart_read(self, address, length=0, agb_save_flash=False):
|
|
541
543
|
if self.MODE == "DMG":
|
|
@@ -870,7 +872,8 @@ class LK_Device(ABC):
|
|
|
870
872
|
self.SIGNAL = None
|
|
871
873
|
|
|
872
874
|
def Debug(self):
|
|
873
|
-
#
|
|
875
|
+
# for i in range(0, 0x100000):
|
|
876
|
+
# print(hex(i), self._set_fw_variable("ADDRESS", i), end="\r", flush=True)
|
|
874
877
|
return
|
|
875
878
|
|
|
876
879
|
def ReadInfo(self, setPinsAsInputs=False, checkRtc=True):
|
|
@@ -2180,22 +2183,26 @@ class LK_Device(ABC):
|
|
|
2180
2183
|
|
|
2181
2184
|
if ".dev" in Util.VERSION_PEP440 or Util.DEBUG:
|
|
2182
2185
|
with open("debug_cfi.bin", "wb") as f: f.write(cfi_buffer)
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
for
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
for
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2186
|
+
try:
|
|
2187
|
+
magic = "{:s}{:s}{:s}".format(chr(cfi_buffer[0x20]), chr(cfi_buffer[0x22]), chr(cfi_buffer[0x24]))
|
|
2188
|
+
d_swap = (0, 0)
|
|
2189
|
+
if magic == "QRY": # D0D1 not swapped
|
|
2190
|
+
pass
|
|
2191
|
+
elif magic == "RQZ": # D0D1 swapped
|
|
2192
|
+
d_swap = [(0, 1)]
|
|
2193
|
+
for j2 in range(0, len(d_swap)):
|
|
2194
|
+
for j in range(0, len(cfi_buffer)):
|
|
2195
|
+
cfi_buffer[j] = bitswap(cfi_buffer[j], d_swap[j2])
|
|
2196
|
+
elif magic == "\x92\x91\x9A": # D0D1+D6D7 swapped
|
|
2197
|
+
d_swap = [( 0, 1 ), ( 6, 7 )]
|
|
2198
|
+
for j2 in range(0, len(d_swap)):
|
|
2199
|
+
for j in range(0, len(cfi_buffer)):
|
|
2200
|
+
cfi_buffer[j] = bitswap(cfi_buffer[j], d_swap[j2])
|
|
2201
|
+
if ".dev" in Util.VERSION_PEP440 or Util.DEBUG:
|
|
2202
|
+
with open("debug_cfi_d0d1+d6d7.bin", "wb") as f: f.write(cfi_buffer)
|
|
2203
|
+
else:
|
|
2204
|
+
cfi_buffer = None
|
|
2205
|
+
except:
|
|
2199
2206
|
cfi_buffer = None
|
|
2200
2207
|
|
|
2201
2208
|
if self.MODE == "DMG":
|
|
@@ -3333,6 +3340,8 @@ class LK_Device(ABC):
|
|
|
3333
3340
|
rtc_buffer = self._read(8)
|
|
3334
3341
|
if len(rtc_buffer) == 8 and _agb_gpio.HasRTC(rtc_buffer) is True:
|
|
3335
3342
|
rtc_buffer = rtc_buffer[1:]
|
|
3343
|
+
rtc_buffer.append(_agb_gpio.RTCReadStatus()) # 24h mode = 0x40, reset flag = 0x80
|
|
3344
|
+
rtc_buffer.extend(struct.pack("<Q", int(time.time())))
|
|
3336
3345
|
else:
|
|
3337
3346
|
rtc_buffer = None
|
|
3338
3347
|
else:
|
|
@@ -3547,6 +3556,9 @@ class LK_Device(ABC):
|
|
|
3547
3556
|
if (self.FW["fw_ver"] < 12 and "set_irq_high" in cart_type and cart_type["set_irq_high"] is True):
|
|
3548
3557
|
self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L12.", "abortable":False})
|
|
3549
3558
|
return False
|
|
3559
|
+
if (self.FW["fw_ver"] < 12 and "status_register_mask" in cart_type):
|
|
3560
|
+
self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L12.", "abortable":False})
|
|
3561
|
+
return False
|
|
3550
3562
|
# Firmware check L12
|
|
3551
3563
|
|
|
3552
3564
|
# Ensure cart is powered
|
|
@@ -3781,6 +3793,7 @@ class LK_Device(ABC):
|
|
|
3781
3793
|
self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type is currently not supported for ROM writing.", "abortable":False})
|
|
3782
3794
|
return False
|
|
3783
3795
|
|
|
3796
|
+
we = 0x00
|
|
3784
3797
|
if flashcart.WEisWR():
|
|
3785
3798
|
we = 0x01 # FLASH_WE_PIN_WR
|
|
3786
3799
|
self._write(we)
|
|
@@ -3794,7 +3807,6 @@ class LK_Device(ABC):
|
|
|
3794
3807
|
self._write(we) # FLASH_WE_PIN_WR_RESET
|
|
3795
3808
|
dprint("Using WR+RESET as WE")
|
|
3796
3809
|
else:
|
|
3797
|
-
we = 0x00
|
|
3798
3810
|
self._write(we) # unset
|
|
3799
3811
|
|
|
3800
3812
|
for i in range(0, 6):
|
|
@@ -4107,7 +4119,7 @@ class LK_Device(ABC):
|
|
|
4107
4119
|
len_rest = end_address - pos
|
|
4108
4120
|
skip_se = False
|
|
4109
4121
|
ts_se_start = time.time()
|
|
4110
|
-
if "compare_sectors" in args and args["compare_sectors"] is True and sector[1] <= len_rest and not (flashcart and cart_type["command_set"] == "GBAMP"):
|
|
4122
|
+
if self.FW["fw_ver"] >= 12 and "compare_sectors" in args and args["compare_sectors"] is True and sector[1] <= len_rest and not (flashcart and cart_type["command_set"] == "GBAMP"):
|
|
4111
4123
|
verified = self.CompareCRC32(buffer=data_import, offset=sector[0], length=sector[1], address=start_address, flashcart=flashcart, reset=True)
|
|
4112
4124
|
if verified is True:
|
|
4113
4125
|
skip_se = True
|
|
@@ -4387,7 +4399,7 @@ class LK_Device(ABC):
|
|
|
4387
4399
|
dprint(f"Verifying ROM bank #{bank} at 0x{pos_from:x} (physical 0x{start_address:X}, 0x{verify_len:X} bytes)")
|
|
4388
4400
|
|
|
4389
4401
|
verified = False
|
|
4390
|
-
if sector[1] >= verify_len and crc32_errors < 5:
|
|
4402
|
+
if self.FW["fw_ver"] >= 12 and sector[1] >= verify_len and crc32_errors < 5:
|
|
4391
4403
|
verified = self.CompareCRC32(buffer=data_import, offset=pos_from, length=verify_len, address=start_address, flashcart=flashcart, reset=False)
|
|
4392
4404
|
if verified is True:
|
|
4393
4405
|
dprint("CRC32 verification successful between 0x{:X} and 0x{:X}".format(pos_from, verify_len))
|
FlashGBX/Mapper.py
CHANGED
|
@@ -404,8 +404,6 @@ class DMG_MBC3(DMG_MBC):
|
|
|
404
404
|
seconds = dt_new.second
|
|
405
405
|
minutes = dt_new.minute
|
|
406
406
|
hours = dt_new.hour
|
|
407
|
-
#temp = dt_new - dt_buffer1
|
|
408
|
-
#days = temp.days
|
|
409
407
|
temp = datetime.date.fromtimestamp(timestamp_now) - datetime.date.fromtimestamp(timestamp_then)
|
|
410
408
|
days = temp.days + days
|
|
411
409
|
if days >= 512:
|
|
@@ -413,13 +411,6 @@ class DMG_MBC3(DMG_MBC):
|
|
|
413
411
|
days = days % 512
|
|
414
412
|
dprint(seconds, minutes, hours, days, carry)
|
|
415
413
|
|
|
416
|
-
#buffer[0x00] = seconds % 60
|
|
417
|
-
#buffer[0x04] = minutes % 60
|
|
418
|
-
#buffer[0x08] = hours % 24
|
|
419
|
-
#buffer[0x0C] = days & 0xFF
|
|
420
|
-
#buffer[0x10] = days >> 8 & 0x1
|
|
421
|
-
#if carry:
|
|
422
|
-
# buffer[0x10] |= 0x80
|
|
423
414
|
except Exception as e:
|
|
424
415
|
print("Couldn’t update the RTC register values\n", e)
|
|
425
416
|
|
|
@@ -1065,15 +1056,10 @@ class DMG_HuC3(DMG_MBC):
|
|
|
1065
1056
|
dprint(dt_then, dt_now, dt_buffer1, dt_buffer2, dt_new, sep="\n")
|
|
1066
1057
|
minutes = dt_new.minute
|
|
1067
1058
|
hours = dt_new.hour
|
|
1068
|
-
#temp = dt_new - dt_buffer1
|
|
1069
|
-
#days = temp.days
|
|
1070
1059
|
temp = datetime.date.fromtimestamp(timestamp_now) - datetime.date.fromtimestamp(timestamp_then)
|
|
1071
1060
|
days = temp.days + days
|
|
1072
1061
|
dprint(minutes, hours, days)
|
|
1073
1062
|
|
|
1074
|
-
#total_minutes = 60 * hours + minutes
|
|
1075
|
-
#data = (total_minutes & 0xFFF) | ((days & 0xFFF) << 12)
|
|
1076
|
-
#buffer[0:4] = struct.pack("<I", data)
|
|
1077
1063
|
d = {
|
|
1078
1064
|
"rtc_h":hours,
|
|
1079
1065
|
"rtc_m":minutes,
|
|
@@ -1322,23 +1308,8 @@ class DMG_TAMA5(DMG_MBC):
|
|
|
1322
1308
|
dt_new_notime = dt_new.replace(hour=0, minute=0, second=0)
|
|
1323
1309
|
days_passed = int((dt_new_notime.timestamp() - dt_buffer_notime.timestamp()) / 60 / 60 / 24)
|
|
1324
1310
|
weekday += days_passed % 7
|
|
1325
|
-
#print("leap_year_state#1", leap_year_state)
|
|
1326
1311
|
leap_year_state = (leap_year_state + year_new) % 4
|
|
1327
|
-
|
|
1328
|
-
#print("New:", seconds, minutes, hours, day_of_week, days, months, years, leap_year_state, z24h_flag)
|
|
1329
|
-
|
|
1330
|
-
# buffer[0x00] = Util.EncodeBCD(seconds)
|
|
1331
|
-
# buffer[0x01] = Util.EncodeBCD(minutes)
|
|
1332
|
-
# buffer[0x02] = Util.EncodeBCD(hours)
|
|
1333
|
-
# buffer[0x03] = (weekday & 0xF) | ((Util.EncodeBCD(days) & 0xF) << 4)
|
|
1334
|
-
# buffer[0x04] = (Util.EncodeBCD(days) >> 4) | ((Util.EncodeBCD(months) & 0xF) << 4)
|
|
1335
|
-
# buffer[0x05] = (Util.EncodeBCD(months) >> 4) | ((Util.EncodeBCD(years) & 0xF) << 4)
|
|
1336
|
-
# buffer[0x06] = (Util.EncodeBCD(years) >> 4)
|
|
1337
|
-
# buffer[0x0D] = leap_year_state << 4 | z24h_flag
|
|
1338
|
-
|
|
1339
|
-
#dstr = ' '.join(format(x, '02X') for x in buffer)
|
|
1340
|
-
#print("[{:02X}] {:s}".format(int(len(dstr)/3) + 1, dstr))
|
|
1341
|
-
|
|
1312
|
+
|
|
1342
1313
|
except Exception as e:
|
|
1343
1314
|
print("Couldn’t update the RTC register values\n", e)
|
|
1344
1315
|
|
|
@@ -1560,31 +1531,6 @@ class DMG_Unlicensed_DatelOrbitV2(DMG_MBC):
|
|
|
1560
1531
|
def GetMaxROMSize(self):
|
|
1561
1532
|
return 128*1024
|
|
1562
1533
|
|
|
1563
|
-
# class DMG_Unlicensed_DatelMegaMem(DMG_MBC):
|
|
1564
|
-
# def GetName(self):
|
|
1565
|
-
# return "Datel MegaMem"
|
|
1566
|
-
|
|
1567
|
-
# def __init__(self, args=None, cart_write_fncptr=None, cart_read_fncptr=None, cart_powercycle_fncptr=None, clk_toggle_fncptr=None):
|
|
1568
|
-
# if args is None: args = {}
|
|
1569
|
-
# super().__init__(args=args, cart_write_fncptr=cart_write_fncptr, cart_read_fncptr=cart_read_fncptr, cart_powercycle_fncptr=cart_powercycle_fncptr, clk_toggle_fncptr=None)
|
|
1570
|
-
# self.ROM_BANK_SIZE = 0x4000
|
|
1571
|
-
# self.RAM_BANK_SIZE = 0x4000
|
|
1572
|
-
|
|
1573
|
-
# def SelectBankROM(self, index):
|
|
1574
|
-
# dprint(self.GetName(), "|", index)
|
|
1575
|
-
# return (0, self.ROM_BANK_SIZE)
|
|
1576
|
-
|
|
1577
|
-
# def SelectBankRAM(self, index):
|
|
1578
|
-
# dprint(self.GetName(), "|", index)
|
|
1579
|
-
# self.CartWrite([[ 0x2000, index & 0x20 ]])
|
|
1580
|
-
# return (0x4000, self.RAM_BANK_SIZE)
|
|
1581
|
-
|
|
1582
|
-
# def GetROMBanks(self, rom_size):
|
|
1583
|
-
# return 1
|
|
1584
|
-
|
|
1585
|
-
# def GetMaxROMSize(self):
|
|
1586
|
-
# return 16*1024
|
|
1587
|
-
|
|
1588
1534
|
|
|
1589
1535
|
class AGB_GPIO:
|
|
1590
1536
|
CART_WRITE_FNCPTR = None
|
|
@@ -1769,9 +1715,8 @@ class AGB_GPIO:
|
|
|
1769
1715
|
])
|
|
1770
1716
|
|
|
1771
1717
|
# Add timestamp of backup time
|
|
1772
|
-
ts = int(time.time())
|
|
1773
1718
|
buffer.append(self.RTCReadStatus()) # 24h mode = 0x40, reset flag = 0x80
|
|
1774
|
-
buffer.extend(struct.pack("<Q",
|
|
1719
|
+
buffer.extend(struct.pack("<Q", int(time.time())))
|
|
1775
1720
|
|
|
1776
1721
|
dprint(' '.join(format(x, '02X') for x in buffer))
|
|
1777
1722
|
|
FlashGBX/Util.py
CHANGED
|
@@ -8,9 +8,9 @@ from enum import Enum
|
|
|
8
8
|
|
|
9
9
|
# Common constants
|
|
10
10
|
APPNAME = "FlashGBX"
|
|
11
|
-
VERSION_PEP440 = "4.
|
|
11
|
+
VERSION_PEP440 = "4.2"
|
|
12
12
|
VERSION = "v{:s}".format(VERSION_PEP440)
|
|
13
|
-
VERSION_TIMESTAMP =
|
|
13
|
+
VERSION_TIMESTAMP = 1722797669
|
|
14
14
|
DEBUG = False
|
|
15
15
|
DEBUG_LOG = []
|
|
16
16
|
APP_PATH = ""
|
|
@@ -410,7 +410,7 @@ def ParseCFI(buffer):
|
|
|
410
410
|
info["magic"] = "{:s}{:s}{:s}".format(chr(buffer[0x20]), chr(buffer[0x22]), chr(buffer[0x24]))
|
|
411
411
|
|
|
412
412
|
if buffer[0x36] == 0xFF and buffer[0x48] == 0xFF:
|
|
413
|
-
print("
|
|
413
|
+
print("Note: Invalid values found in Common Flash Interface data.")
|
|
414
414
|
try:
|
|
415
415
|
with open("./cfi_debug.bin", "wb") as f: f.write(buffer)
|
|
416
416
|
except:
|
FlashGBX/fw_JoeyJr.py
CHANGED
|
@@ -32,31 +32,39 @@ class FirmwareUpdater():
|
|
|
32
32
|
|
|
33
33
|
with open(file, "rb") as f: temp = f.read().decode("UTF-8", "ignore")
|
|
34
34
|
if not temp.startswith("UPDATE"):
|
|
35
|
-
with open(file, "
|
|
35
|
+
with open(file, "wb") as f:
|
|
36
|
+
temp = bytearray(b"UPDATE")
|
|
37
|
+
temp += bytearray([0] * (256 - len(temp)))
|
|
38
|
+
f.write(temp)
|
|
36
39
|
hp = 30
|
|
37
40
|
while hp > 0:
|
|
38
41
|
if os.path.exists(path + "FIRMWARE.JR"): break
|
|
39
42
|
time.sleep(1)
|
|
40
43
|
hp -= 1
|
|
41
44
|
if hp == 0:
|
|
42
|
-
fncSetStatus(text="
|
|
45
|
+
fncSetStatus(text="Couldn’t communicate with the Joey Jr device.")
|
|
43
46
|
return 2
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
try:
|
|
49
|
+
with open(file, "rb") as f: temp = f.read().decode("UTF-8", "ignore")
|
|
50
|
+
except FileNotFoundError:
|
|
51
|
+
fncSetStatus(text="Couldn’t access MODE.TXT. Remove cartridge and try again.")
|
|
52
|
+
return 2
|
|
53
|
+
|
|
46
54
|
if not temp.startswith("UPDATE"):
|
|
47
|
-
fncSetStatus(text="
|
|
55
|
+
fncSetStatus(text="Couldn’t enter UPDATE mode, please try again.")
|
|
48
56
|
return 2
|
|
49
57
|
|
|
50
58
|
fncSetStatus(text="Updating firmware... Do not unplug the device!", setProgress=0)
|
|
51
59
|
os.unlink(path + "FIRMWARE.JR")
|
|
52
60
|
if os.path.exists(path + "FIRMWARE.JR"):
|
|
53
|
-
fncSetStatus(text="
|
|
61
|
+
fncSetStatus(text="Couldn’t write new firmware, please try again.")
|
|
54
62
|
return 2
|
|
55
63
|
|
|
56
64
|
try:
|
|
57
65
|
f = open(path + "FIRMWARE.JR", "wb")
|
|
58
66
|
except OSError:
|
|
59
|
-
fncSetStatus(text="
|
|
67
|
+
fncSetStatus(text="Couldn’t write new firmware, please try again.")
|
|
60
68
|
return 2
|
|
61
69
|
|
|
62
70
|
for i in range(0, len(buffer), 64):
|
|
@@ -69,9 +77,18 @@ class FirmwareUpdater():
|
|
|
69
77
|
except OSError:
|
|
70
78
|
pass
|
|
71
79
|
|
|
72
|
-
|
|
80
|
+
if b"Joey Jr. Firmware" not in buffer:
|
|
81
|
+
hp = 5
|
|
82
|
+
while hp > 0:
|
|
83
|
+
if not os.path.exists(path + "FIRMWARE.JR"): break
|
|
84
|
+
time.sleep(1)
|
|
85
|
+
hp -= 1
|
|
86
|
+
if hp == 0:
|
|
87
|
+
fncSetStatus(text="Couldn’t verify, please try again.")
|
|
88
|
+
return 2
|
|
89
|
+
|
|
73
90
|
fncSetStatus("Done.")
|
|
74
|
-
time.sleep(
|
|
91
|
+
time.sleep(2)
|
|
75
92
|
|
|
76
93
|
return True
|
|
77
94
|
|
|
@@ -141,16 +158,16 @@ class FirmwareUpdater():
|
|
|
141
158
|
pass
|
|
142
159
|
elif counter + 64 < size:
|
|
143
160
|
print("\nBad response at", counter)
|
|
144
|
-
fncSetStatus(text="Error
|
|
161
|
+
fncSetStatus(text="Error! Bad response at 0x{:X}!".format(counter), setProgress=percent)
|
|
145
162
|
return 2
|
|
146
163
|
|
|
147
164
|
counter += 64
|
|
148
165
|
fncSetStatus(text="Updating firmware... Do not unplug the device!", setProgress=percent)
|
|
149
166
|
|
|
150
167
|
dev.close()
|
|
151
|
-
time.sleep(0.8)
|
|
152
|
-
fncSetStatus("Done.", setProgress=100)
|
|
153
168
|
time.sleep(1)
|
|
169
|
+
fncSetStatus("Done.", setProgress=100)
|
|
170
|
+
time.sleep(2)
|
|
154
171
|
return 1
|
|
155
172
|
|
|
156
173
|
try:
|
|
@@ -302,9 +319,9 @@ try:
|
|
|
302
319
|
self.lblDeviceNameResult.setText(self.DEV_NAME + " " + self.PCB_VER)
|
|
303
320
|
self.lblDeviceFWVerResult.setText(self.FW_VER)
|
|
304
321
|
|
|
305
|
-
if platform.system() == 'Darwin':
|
|
306
|
-
|
|
307
|
-
|
|
322
|
+
# if platform.system() == 'Darwin':
|
|
323
|
+
# self.optFW_MSC.setVisible(False)
|
|
324
|
+
# self.lblFW_MSC_Blerb.setVisible(False)
|
|
308
325
|
|
|
309
326
|
def run(self):
|
|
310
327
|
try:
|
|
@@ -446,8 +463,11 @@ try:
|
|
|
446
463
|
elif ret == 4:
|
|
447
464
|
if platform.system() == 'Darwin':
|
|
448
465
|
self.SetStatus("No device found.", enableUI=True)
|
|
466
|
+
text = "If your Joey Jr device is currently running the Drag'n'Drop firmware, please update the firmware on Windows or Linux, or use the standalone firmware updater."
|
|
467
|
+
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok)
|
|
468
|
+
answer = msgbox.exec()
|
|
449
469
|
return False
|
|
450
|
-
answer = QtWidgets.QMessageBox.information(self, "FlashGBX", "If your Joey Jr device is currently running
|
|
470
|
+
answer = QtWidgets.QMessageBox.information(self, "FlashGBX", "If your Joey Jr device is currently running the Drag'n'Drop firmware, please continue and choose its <b>MODE.TXT</b> file.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Ok)
|
|
451
471
|
if answer == QtWidgets.QMessageBox.Cancel:
|
|
452
472
|
self.SetStatus("No device found.", enableUI=True)
|
|
453
473
|
return False
|
FlashGBX/hw_GBFlash.py
CHANGED
|
@@ -9,7 +9,7 @@ class GbxDevice(LK_Device):
|
|
|
9
9
|
DEVICE_NAME = "GBFlash"
|
|
10
10
|
DEVICE_MIN_FW = 1
|
|
11
11
|
DEVICE_MAX_FW = 12
|
|
12
|
-
DEVICE_LATEST_FW_TS = { 5:
|
|
12
|
+
DEVICE_LATEST_FW_TS = { 5:1722774120, 10:1722774120, 11:1722774120, 12:1722774120, 13:1722774120 }
|
|
13
13
|
PCB_VERSIONS = { 5:'', 12:'v1.2', 13:'v1.3' }
|
|
14
14
|
|
|
15
15
|
def __init__(self):
|
FlashGBX/hw_GBxCartRW.py
CHANGED
|
@@ -9,7 +9,7 @@ class GbxDevice(LK_Device):
|
|
|
9
9
|
DEVICE_NAME = "GBxCart RW"
|
|
10
10
|
DEVICE_MIN_FW = 1
|
|
11
11
|
DEVICE_MAX_FW = 1
|
|
12
|
-
DEVICE_LATEST_FW_TS = { 4:1709317610, 5:
|
|
12
|
+
DEVICE_LATEST_FW_TS = { 4:1709317610, 5:1722774120, 6:1722774120, 2:0, 90:0, 100:0 }
|
|
13
13
|
PCB_VERSIONS = { 5:'v1.4', 6:'v1.4a/b/c', 2:'v1.1/v1.2', 4:'v1.3', 90:'XMAS v1.0', 100:'Mini v1.0' }
|
|
14
14
|
BAUDRATE = 1000000
|
|
15
15
|
MAX_BUFFER_READ = 0x1000
|
|
@@ -74,6 +74,8 @@ class GbxDevice(LK_Device):
|
|
|
74
74
|
self.MAX_BUFFER_WRITE = 0x100
|
|
75
75
|
|
|
76
76
|
conn_msg.append([0, "For help with your GBxCart RW device, please visit the insideGadgets Discord: https://gbxcart.com/discord"])
|
|
77
|
+
if self.FW["pcb_ver"] == 4:
|
|
78
|
+
conn_msg.append([0, "Note: Your GBxCart RW hardware revision does not fully support the latest features due to technical limitations. Please consider upgrading to a newer device."])
|
|
77
79
|
|
|
78
80
|
self.PORT = ports[i]
|
|
79
81
|
self.DEVICE.timeout = self.DEVICE_TIMEOUT
|
|
@@ -320,3 +322,8 @@ class GbxDevice(LK_Device):
|
|
|
320
322
|
except SerialException:
|
|
321
323
|
pass
|
|
322
324
|
return super().Close(cartPowerOff)
|
|
325
|
+
|
|
326
|
+
def SetTimeout(self, seconds=1):
|
|
327
|
+
if seconds < 1: seconds = 1
|
|
328
|
+
self.DEVICE_TIMEOUT = seconds
|
|
329
|
+
self.DEVICE.timeout = self.DEVICE_TIMEOUT
|
FlashGBX/hw_JoeyJr.py
CHANGED
|
@@ -9,7 +9,7 @@ class GbxDevice(LK_Device):
|
|
|
9
9
|
DEVICE_NAME = "Joey Jr"
|
|
10
10
|
DEVICE_MIN_FW = 1
|
|
11
11
|
DEVICE_MAX_FW = 12
|
|
12
|
-
DEVICE_LATEST_FW_TS =
|
|
12
|
+
DEVICE_LATEST_FW_TS = 1722774120
|
|
13
13
|
PCB_VERSIONS = { -1:"", 0x01:"V2", 0x81:"V2", 0x02:"V2C", 0x82:"V2C", 0x03:"V2CC", 0x83:"V2CC/V2++" }
|
|
14
14
|
|
|
15
15
|
def __init__(self):
|
FlashGBX/res/config.zip
CHANGED
|
Binary file
|
FlashGBX/res/fw_GBFlash.zip
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
FlashGBX/res/fw_JoeyJr.zip
CHANGED
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: FlashGBX
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.2
|
|
4
4
|
Summary: Reads and writes Game Boy and Game Boy Advance cartridge data
|
|
5
5
|
Home-page: https://github.com/lesserkuma/FlashGBX
|
|
6
6
|
Author: Lesserkuma
|
|
@@ -147,7 +147,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
|
|
147
147
|
- DIY cart with MX29F040
|
|
148
148
|
- DIY cart with MX29LV640
|
|
149
149
|
- DIY cart with SST39SF040
|
|
150
|
-
- DMG-MBC5-32M-FLASH Development Cartridge, E201264
|
|
150
|
+
- DMG-MBC5-32M-FLASH (G/A) Development Cartridge, E201264
|
|
151
151
|
- Ferrante Crafts cart 32 KB
|
|
152
152
|
- Ferrante Crafts cart 64 KB
|
|
153
153
|
- Ferrante Crafts cart 512 KB
|
|
@@ -175,8 +175,9 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
|
|
175
175
|
- Game Boy Advance
|
|
176
176
|
|
|
177
177
|
- Action Replay Ultimate Codes (with SST39VF800A)
|
|
178
|
-
- Development AGB Cartridge 64M Flash, E201629
|
|
179
|
-
- Development AGB Cartridge 64M Flash
|
|
178
|
+
- Development AGB Cartridge 64M Flash, E201629¹
|
|
179
|
+
- Development AGB Cartridge 64M Flash, E201629 (128M, with 4× LH28F320BJE)¹
|
|
180
|
+
- Development AGB Cartridge 64M Flash S, E201843¹
|
|
180
181
|
- Development AGB Cartridge 128M Flash S, E201850
|
|
181
182
|
- Development AGB Cartridge 256M Flash S, E201868
|
|
182
183
|
- DL9SEC GBA flashcart with TE28F128
|
|
@@ -326,7 +327,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
|
|
326
327
|
- GA-07 with unlabeled flash chip
|
|
327
328
|
- GE28F128W30 with 128W30B0
|
|
328
329
|
- K5L2BX_32D_16D_V2 with K5L2833ATA
|
|
329
|
-
- M36XXX_32A_EARTH with
|
|
330
|
+
- M36XXX_32A_EARTH with M36L0R806
|
|
330
331
|
- M36XXX_T32_32D_16D with M36L0R806
|
|
331
332
|
- M5M29-39VF512 with M5M29HD528
|
|
332
333
|
- M5M29G130AN (no PCB text)
|
|
@@ -370,7 +371,7 @@ Many different reproduction cartridges share their flash chip command set, so ev
|
|
|
370
371
|
|
|
371
372
|
The author would like to thank the following very kind people for their help, contributions or documentation (in alphabetical order):
|
|
372
373
|
|
|
373
|
-
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, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, Jayro, Jenetrix, JFox, joyrider3774, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, olDirdey, orangeglo, paarongiroux, Paradoxical, Rairch, Raphaël BOICHOT, redalchemy, RetroGorek, RevZ, RibShark, s1cp, Satumox, Sgt.DoudouMiel, SH, Shinichi999, Sillyhatday, simonK, Sithdown, skite2001, Smelly-Ghost, 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
|
|
374
|
+
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, DevDavisNunez, Diddy_Kong, djedditt, Dr-InSide, dyf2007, easthighNerd, EchelonPrime, edo999, Eldram, Ell, EmperorOfTigers, endrift, Erba Verde, ethanstrax, eveningmoose, Falknör, FerrantePescara, frarees, Frost Clock, gandalf1980, gboh, gekkio, Godan, Grender, HDR, Herax, Hiccup, hiks, howie0210, iamevn, Icesythe7, ide, inYourBackline, iyatemu, Jayro, Jenetrix, JFox, joyrider3774, jrharbort, JS7457, julgr, Kaede, kane159, KOOORAY, kscheel, kyokohunter, Leitplanke, litlemoran, LovelyA72, Lu, Luca DS, LucentW, manuelcm1, marv17, Merkin, metroid-maniac, Mr_V, 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
|
|
374
375
|
|
|
375
376
|
## Third Party Notices and Licenses
|
|
376
377
|
|
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
FlashGBX/DataTransfer.py,sha256=9o3BSBed-SMIWkl-TcmolUjBdrGwem8TqjnktWScgBA,1766
|
|
2
2
|
FlashGBX/FlashGBX.py,sha256=QbLvnqN5K9JLOYhQX6xvrC-H5fl9bYhWDzkOgo8pdUo,12736
|
|
3
3
|
FlashGBX/FlashGBX_CLI.py,sha256=eJ4DJP6u-HDn8hZjsReHTRckme0c_T718NzKzEgF6eQ,64741
|
|
4
|
-
FlashGBX/FlashGBX_GUI.py,sha256=
|
|
4
|
+
FlashGBX/FlashGBX_GUI.py,sha256=p2H-ThzXcWLAbJaBiiTy8TvJ0XBbl8cARdkSyGIxYoA,171638
|
|
5
5
|
FlashGBX/Flashcart.py,sha256=S-af7YjsIOCx3sYsS4GjrHt80HD4-RrdLd0EBipXZ-Q,36396
|
|
6
|
-
FlashGBX/GBMemory.py,sha256=
|
|
7
|
-
FlashGBX/LK_Device.py,sha256=
|
|
8
|
-
FlashGBX/Mapper.py,sha256=
|
|
6
|
+
FlashGBX/GBMemory.py,sha256=c1AMjW-TCtKfyexFLCS0pUA7dNmWyUXqUikN_QUf0MU,13320
|
|
7
|
+
FlashGBX/LK_Device.py,sha256=31SdJ4LG00YXcP6SAF1TwG6-zphA6GOi-QlLN6_AK1g,188140
|
|
8
|
+
FlashGBX/Mapper.py,sha256=eLw3xwxb43SLGbSmjXfzjPHK2w87NWbVsHt53Ac7F64,56964
|
|
9
9
|
FlashGBX/PocketCamera.py,sha256=uTkhpvlKfDy7fQRLoHTIxTXh-WdvYj2OUeNo45KhLoY,4899
|
|
10
10
|
FlashGBX/PocketCameraWindow.py,sha256=sqWv94gUeFBmUa8Zn1u-Zb4-qVcw5j-Q_tE7hz3sYpc,16185
|
|
11
11
|
FlashGBX/RomFileAGB.py,sha256=ad9WBGnPbW6a2y7B5R3rwizhocPFANMAwKCXJYBPQdA,8908
|
|
12
12
|
FlashGBX/RomFileDMG.py,sha256=gm9_m41Jv70mLxQzrol3acCoCpOoivllrVtizrSuWss,21466
|
|
13
13
|
FlashGBX/UserInputDialog.py,sha256=aYe3CeYlzQoCLI4DQulL5K9euB0HcMpcKZCFZfIJzqE,2911
|
|
14
|
-
FlashGBX/Util.py,sha256=
|
|
14
|
+
FlashGBX/Util.py,sha256=XFP-FQaNLz6F4CuNKep1ma7IgcN7jErhUkBrv__eJnA,40132
|
|
15
15
|
FlashGBX/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
FlashGBX/__main__.py,sha256=L3ibKoTXOlTCepGzrgcktk_Jwp25xBCmGpNQO7W8Bbc,120
|
|
17
17
|
FlashGBX/fw_GBFlash.py,sha256=ebRADjLw_2eOckLYCoUlepRpLD_eTtLTXOxCJ4zskKM,15629
|
|
18
18
|
FlashGBX/fw_GBxCartRW_v1_3.py,sha256=qiYReJi1C-UDTjJVY0VujIsM5wPolnUrl_3TQYV-Drw,21498
|
|
19
19
|
FlashGBX/fw_GBxCartRW_v1_4.py,sha256=K6eWc6_hy5WZUhCHHxTbigUvvWa3csjnomPEj7TMocM,14733
|
|
20
|
-
FlashGBX/fw_JoeyJr.py,sha256=
|
|
21
|
-
FlashGBX/hw_GBFlash.py,sha256=
|
|
22
|
-
FlashGBX/hw_GBxCartRW.py,sha256=
|
|
23
|
-
FlashGBX/hw_JoeyJr.py,sha256=
|
|
20
|
+
FlashGBX/fw_JoeyJr.py,sha256=YJP68_gE2djJ3dPjnQVenEk91LtFUAyy1WHK6bwXwSg,20689
|
|
21
|
+
FlashGBX/hw_GBFlash.py,sha256=DZQGb1NG1tp9ProCirrbrSH6XPrfEFSi5lGq7BlWe0c,7668
|
|
22
|
+
FlashGBX/hw_GBxCartRW.py,sha256=KOR0wmh9FsBopFnfe0Ed1GM4uySrMdFMTSOs6jrHbaw,11193
|
|
23
|
+
FlashGBX/hw_JoeyJr.py,sha256=1Bv9AD5cTGqIYgnjuPMW9BBLrLx59jMnyqVUv6H11jM,9334
|
|
24
24
|
FlashGBX/pyside.py,sha256=hlvYbV29AFJ1Epv0R41Sz-wuo4I9-gH8hgS8sfwJyCk,1662
|
|
25
25
|
FlashGBX/res/Third Party Notices.md,sha256=X-1MRGTAQB8ZuskoWvbhq4IBYj-G0jJoklya3jGwzcQ,18994
|
|
26
|
-
FlashGBX/res/config.zip,sha256=
|
|
27
|
-
FlashGBX/res/fw_GBFlash.zip,sha256=
|
|
26
|
+
FlashGBX/res/config.zip,sha256=iVZ2yoVsNK9jR0bkW5gQvbPswurYS3L8Pr3tfAWYyp4,379194
|
|
27
|
+
FlashGBX/res/fw_GBFlash.zip,sha256=u9d0Y6N74EjqEWt68355mqIfxfTMPMTnypmjIopm4JU,17507
|
|
28
28
|
FlashGBX/res/fw_GBxCart_RW_Mini_v1_0.zip,sha256=-QpHSw2JsjPG2WQ7E6mRqre4D3VThau2U7bFZYPY6r0,4774
|
|
29
29
|
FlashGBX/res/fw_GBxCart_RW_XMAS_v1_0.zip,sha256=ai6ithbSsEst22lCcDyJhr8KIlixqhg3HF4XV16Fdto,8093
|
|
30
30
|
FlashGBX/res/fw_GBxCart_RW_v1_1_v1_2.zip,sha256=H9tTjRMovpRkR89tUCsMMpwPslCoRml_cEWu8oYfMLs,8137
|
|
31
31
|
FlashGBX/res/fw_GBxCart_RW_v1_3.zip,sha256=zi2f7fdulQcSATuiIFMaCrpz3mCF5RGftVpbZNVedq0,15681
|
|
32
|
-
FlashGBX/res/fw_GBxCart_RW_v1_4.zip,sha256=
|
|
33
|
-
FlashGBX/res/fw_GBxCart_RW_v1_4a.zip,sha256=
|
|
34
|
-
FlashGBX/res/fw_JoeyJr.zip,sha256=
|
|
32
|
+
FlashGBX/res/fw_GBxCart_RW_v1_4.zip,sha256=5H2ZSDaxhJCzeYshKwj8CBDQPsxS30hJKuYbPEVYYtg,36772
|
|
33
|
+
FlashGBX/res/fw_GBxCart_RW_v1_4a.zip,sha256=skp6LC3qvEyVZf7Txs8chSqsT-JoeZt0ZbvoqMb_3Lk,36260
|
|
34
|
+
FlashGBX/res/fw_JoeyJr.zip,sha256=quBrdbe3Kbr30_eP3nqix-ye4v8H5C3fvOZ7m-dxwes,69078
|
|
35
35
|
FlashGBX/res/icon.ico,sha256=2FNNCkh2W0IFQNYNdy8cmodh69NC0gYfpw81GZtr9rU,129959
|
|
36
36
|
FlashGBX/res/icon.png,sha256=WtE7XqPKr2538lw4gVbm6slWvMLJpwYjre8_z1q70GY,19286
|
|
37
37
|
FlashGBX/res/pc_frame.png,sha256=Hp8cUT_e7kc3-nrTD9ekB8gNVgKNEZRr75ggNDihJOg,653
|
|
38
|
-
FlashGBX-4.
|
|
39
|
-
FlashGBX-4.
|
|
40
|
-
FlashGBX-4.
|
|
41
|
-
FlashGBX-4.
|
|
42
|
-
FlashGBX-4.
|
|
43
|
-
FlashGBX-4.
|
|
38
|
+
FlashGBX-4.2.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
39
|
+
FlashGBX-4.2.dist-info/METADATA,sha256=LaWjis17ix7y3b7UmPWpE-NHYP0YP8fHE8fkpayLfZc,19273
|
|
40
|
+
FlashGBX-4.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
41
|
+
FlashGBX-4.2.dist-info/entry_points.txt,sha256=lsg7RmPUIvEI_Q8bA3jIRh8MLF1qIBzUX_yEjD4lJ-g,52
|
|
42
|
+
FlashGBX-4.2.dist-info/top_level.txt,sha256=y6Ssb3YnEYYHNJIPsG_b5ifITM1STAyQXMpjtNOtyzA,9
|
|
43
|
+
FlashGBX-4.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|