FlashGBX 4.0__py3-none-any.whl → 4.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_GUI.py +2 -24
- FlashGBX/GBMemory.py +35 -29
- FlashGBX/LK_Device.py +44 -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 +7 -2
- 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.dist-info → FlashGBX-4.1.dist-info}/METADATA +10 -8
- {FlashGBX-4.0.dist-info → FlashGBX-4.1.dist-info}/RECORD +20 -20
- {FlashGBX-4.0.dist-info → FlashGBX-4.1.dist-info}/LICENSE +0 -0
- {FlashGBX-4.0.dist-info → FlashGBX-4.1.dist-info}/WHEEL +0 -0
- {FlashGBX-4.0.dist-info → FlashGBX-4.1.dist-info}/entry_points.txt +0 -0
- {FlashGBX-4.0.dist-info → FlashGBX-4.1.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,7 +238,6 @@ 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) ])
|
|
@@ -274,8 +262,6 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
274
262
|
self.btnConnect = QtWidgets.QPushButton("&Connect")
|
|
275
263
|
self.connect(self.btnConnect, QtCore.SIGNAL("clicked()"), self.ConnectDevice)
|
|
276
264
|
self.layout_devices.addWidget(self.btnMainMenu)
|
|
277
|
-
#self.layout_devices.addWidget(self.btnTools)
|
|
278
|
-
#self.layout_devices.addWidget(self.btnConfig)
|
|
279
265
|
self.layout_devices.addWidget(self.btnConnect)
|
|
280
266
|
|
|
281
267
|
self.layout.addLayout(self.layout_devices, 1, 0, 1, 0)
|
|
@@ -355,12 +341,6 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
355
341
|
lblDMGHeaderRtc.setContentsMargins(0, 1, 0, 1)
|
|
356
342
|
rowDMGHeaderRtc.addWidget(lblDMGHeaderRtc)
|
|
357
343
|
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
344
|
self.lblDMGHeaderRtcResult.mousePressEvent = lambda event: [ self.EditRTC(event) ]
|
|
365
345
|
rowDMGHeaderRtc.addWidget(self.lblDMGHeaderRtcResult)
|
|
366
346
|
rowDMGHeaderRtc.setStretch(0, 9)
|
|
@@ -475,8 +455,6 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
475
455
|
lblAGBGpioRtc.setContentsMargins(0, 1, 0, 1)
|
|
476
456
|
rowAGBGpioRtc.addWidget(lblAGBGpioRtc)
|
|
477
457
|
self.lblAGBGpioRtcResult = QtWidgets.QLabel("")
|
|
478
|
-
#self.lblAGBGpioRtcResult.setCursor(QtGui.QCursor(QtCore.Qt.WhatsThisCursor))
|
|
479
|
-
#self.lblAGBGpioRtcResult.setToolTip(self.lblDMGHeaderRtcResult.toolTip())
|
|
480
458
|
self.lblAGBGpioRtcResult.mousePressEvent = lambda event: [ self.EditRTC(event) ]
|
|
481
459
|
rowAGBGpioRtc.addWidget(self.lblAGBGpioRtcResult)
|
|
482
460
|
rowAGBGpioRtc.setStretch(0, 9)
|
|
@@ -731,7 +709,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
731
709
|
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
710
|
msg += f"© 2020–{datetime.datetime.now().year} Lesserkuma<br>"
|
|
733
711
|
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"
|
|
712
|
+
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, 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"
|
|
735
713
|
QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), msg, QtWidgets.QMessageBox.Ok)
|
|
736
714
|
|
|
737
715
|
def OpenPath(self, path=None):
|
|
@@ -926,7 +904,7 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
|
|
926
904
|
qt_app.processEvents()
|
|
927
905
|
|
|
928
906
|
messages = []
|
|
929
|
-
last_msg = ""
|
|
907
|
+
#last_msg = ""
|
|
930
908
|
|
|
931
909
|
# pylint: disable=global-variable-not-assigned
|
|
932
910
|
global hw_devices
|
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):
|
|
@@ -532,8 +534,11 @@ class LK_Device(ABC):
|
|
|
532
534
|
buffer.extend(struct.pack(">I", key))
|
|
533
535
|
buffer.extend(struct.pack(">I", value))
|
|
534
536
|
|
|
535
|
-
self.
|
|
536
|
-
|
|
537
|
+
if self.FW["fw_ver"] >= 12:
|
|
538
|
+
return self._try_write(buffer)
|
|
539
|
+
else:
|
|
540
|
+
return self._write(buffer)
|
|
541
|
+
|
|
537
542
|
def _cart_read(self, address, length=0, agb_save_flash=False):
|
|
538
543
|
if self.MODE == "DMG":
|
|
539
544
|
if length == 0:
|
|
@@ -595,7 +600,10 @@ class LK_Device(ABC):
|
|
|
595
600
|
buffer.extend(struct.pack(">I", address >> 1))
|
|
596
601
|
buffer.extend(struct.pack(">H", value & 0xFFFF))
|
|
597
602
|
|
|
598
|
-
self.
|
|
603
|
+
if self.FW["fw_ver"] >= 12:
|
|
604
|
+
self._try_write(buffer)
|
|
605
|
+
else:
|
|
606
|
+
self._write(buffer)
|
|
599
607
|
|
|
600
608
|
if self.MODE == "DMG" and sram: self._set_fw_variable("DMG_WRITE_CS_PULSE", 0)
|
|
601
609
|
|
|
@@ -864,7 +872,8 @@ class LK_Device(ABC):
|
|
|
864
872
|
self.SIGNAL = None
|
|
865
873
|
|
|
866
874
|
def Debug(self):
|
|
867
|
-
#
|
|
875
|
+
# for i in range(0, 0x100000):
|
|
876
|
+
# print(hex(i), self._set_fw_variable("ADDRESS", i), end="\r", flush=True)
|
|
868
877
|
return
|
|
869
878
|
|
|
870
879
|
def ReadInfo(self, setPinsAsInputs=False, checkRtc=True):
|
|
@@ -2174,22 +2183,26 @@ class LK_Device(ABC):
|
|
|
2174
2183
|
|
|
2175
2184
|
if ".dev" in Util.VERSION_PEP440 or Util.DEBUG:
|
|
2176
2185
|
with open("debug_cfi.bin", "wb") as f: f.write(cfi_buffer)
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
for
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
for
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
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:
|
|
2193
2206
|
cfi_buffer = None
|
|
2194
2207
|
|
|
2195
2208
|
if self.MODE == "DMG":
|
|
@@ -2523,6 +2536,7 @@ class LK_Device(ABC):
|
|
|
2523
2536
|
|
|
2524
2537
|
self.INFO["dump_info"]["vf_addr_reorder"] = addr_reorder
|
|
2525
2538
|
self.INFO["dump_info"]["vf_value_reorder"] = value_reorder
|
|
2539
|
+
self.INFO["dump_info"]["agb_read_method"] = self.AGB_READ_METHODS[self.AGB_READ_METHOD]
|
|
2526
2540
|
|
|
2527
2541
|
else:
|
|
2528
2542
|
self.INFO["dump_info"]["agb_read_method"] = self.AGB_READ_METHODS[self.AGB_READ_METHOD]
|
|
@@ -3326,6 +3340,8 @@ class LK_Device(ABC):
|
|
|
3326
3340
|
rtc_buffer = self._read(8)
|
|
3327
3341
|
if len(rtc_buffer) == 8 and _agb_gpio.HasRTC(rtc_buffer) is True:
|
|
3328
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())))
|
|
3329
3345
|
else:
|
|
3330
3346
|
rtc_buffer = None
|
|
3331
3347
|
else:
|
|
@@ -3540,6 +3556,9 @@ class LK_Device(ABC):
|
|
|
3540
3556
|
if (self.FW["fw_ver"] < 12 and "set_irq_high" in cart_type and cart_type["set_irq_high"] is True):
|
|
3541
3557
|
self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"This cartridge type requires at least firmware version L12.", "abortable":False})
|
|
3542
3558
|
return False
|
|
3559
|
+
if (self.FW["fw_ver"] < 12 and "status_register_mask" in cart_type and cart_type["status_register_mask"] is True):
|
|
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
|
|
3543
3562
|
# Firmware check L12
|
|
3544
3563
|
|
|
3545
3564
|
# Ensure cart is powered
|
|
@@ -4100,7 +4119,7 @@ class LK_Device(ABC):
|
|
|
4100
4119
|
len_rest = end_address - pos
|
|
4101
4120
|
skip_se = False
|
|
4102
4121
|
ts_se_start = time.time()
|
|
4103
|
-
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"):
|
|
4104
4123
|
verified = self.CompareCRC32(buffer=data_import, offset=sector[0], length=sector[1], address=start_address, flashcart=flashcart, reset=True)
|
|
4105
4124
|
if verified is True:
|
|
4106
4125
|
skip_se = True
|
|
@@ -4380,7 +4399,7 @@ class LK_Device(ABC):
|
|
|
4380
4399
|
dprint(f"Verifying ROM bank #{bank} at 0x{pos_from:x} (physical 0x{start_address:X}, 0x{verify_len:X} bytes)")
|
|
4381
4400
|
|
|
4382
4401
|
verified = False
|
|
4383
|
-
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:
|
|
4384
4403
|
verified = self.CompareCRC32(buffer=data_import, offset=pos_from, length=verify_len, address=start_address, flashcart=flashcart, reset=False)
|
|
4385
4404
|
if verified is True:
|
|
4386
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.1"
|
|
12
12
|
VERSION = "v{:s}".format(VERSION_PEP440)
|
|
13
|
-
VERSION_TIMESTAMP =
|
|
13
|
+
VERSION_TIMESTAMP = 1722759922
|
|
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:1722759904, 10:1722759904, 11:1722759904, 12:1722759904, 13:1722759904 }
|
|
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:1722759904, 6:1722759904, 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
|
|
@@ -191,7 +191,7 @@ class GbxDevice(LK_Device):
|
|
|
191
191
|
if self.FW["fw_ver"] >= 12:
|
|
192
192
|
temp = bytearray([self.DEVICE_CMD["QUERY_CART_PWR"]])
|
|
193
193
|
self._get_fw_variable("CART_MODE")
|
|
194
|
-
|
|
194
|
+
elif self.CanPowerCycleCart():
|
|
195
195
|
temp = bytearray([self.DEVICE_CMD["OFW_QUERY_CART_PWR"]])
|
|
196
196
|
self._write(temp)
|
|
197
197
|
self._read(1)
|
|
@@ -320,3 +320,8 @@ class GbxDevice(LK_Device):
|
|
|
320
320
|
except SerialException:
|
|
321
321
|
pass
|
|
322
322
|
return super().Close(cartPowerOff)
|
|
323
|
+
|
|
324
|
+
def SetTimeout(self, seconds=1):
|
|
325
|
+
if seconds < 1: seconds = 1
|
|
326
|
+
self.DEVICE_TIMEOUT = seconds
|
|
327
|
+
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 = 1722759904
|
|
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,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: FlashGBX
|
|
3
|
-
Version: 4.
|
|
4
|
-
Summary: Reads and writes Game Boy and Game Boy Advance cartridge data
|
|
3
|
+
Version: 4.1
|
|
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
|
|
7
7
|
Project-URL: Source, https://github.com/lesserkuma/FlashGBX/
|
|
@@ -73,7 +73,8 @@ These work for installing fresh and upgrading from an older version.
|
|
|
73
73
|
* If installation fails, try this command instead:<br>`pip3 install "FlashGBX[qt5]"`
|
|
74
74
|
* If installation still fails, you can install the minimal version (command line interface) with this command:<br>`pip3 install FlashGBX`
|
|
75
75
|
|
|
76
|
-
* Pre-made Linux packages and instructions for select distributions are available [here](https://github.com/JJ-Fox/FlashGBX-Linux-builds/releases/latest).
|
|
76
|
+
* Pre-made Linux packages and instructions for select distributions are available [here](https://github.com/JJ-Fox/FlashGBX-Linux-builds/releases/latest), contributed by JJ-Fox.
|
|
77
|
+
* Pre-made macOS packages and instructions are available [here](https://github.com/Cliffback/FlashGBX-macOS) (in the “Releases” section), contributed by Cliffback.
|
|
77
78
|
|
|
78
79
|
#### Running
|
|
79
80
|
Use this command in a Terminal or Command Prompt window to launch the installed FlashGBX application:
|
|
@@ -146,7 +147,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
|
|
146
147
|
- DIY cart with MX29F040
|
|
147
148
|
- DIY cart with MX29LV640
|
|
148
149
|
- DIY cart with SST39SF040
|
|
149
|
-
- DMG-MBC5-32M-FLASH Development Cartridge, E201264
|
|
150
|
+
- DMG-MBC5-32M-FLASH (G/A) Development Cartridge, E201264
|
|
150
151
|
- Ferrante Crafts cart 32 KB
|
|
151
152
|
- Ferrante Crafts cart 64 KB
|
|
152
153
|
- Ferrante Crafts cart 512 KB
|
|
@@ -174,8 +175,9 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
|
|
174
175
|
- Game Boy Advance
|
|
175
176
|
|
|
176
177
|
- Action Replay Ultimate Codes (with SST39VF800A)
|
|
177
|
-
- Development AGB Cartridge 64M Flash, E201629
|
|
178
|
-
- 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¹
|
|
179
181
|
- Development AGB Cartridge 128M Flash S, E201850
|
|
180
182
|
- Development AGB Cartridge 256M Flash S, E201868
|
|
181
183
|
- DL9SEC GBA flashcart with TE28F128
|
|
@@ -325,7 +327,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
|
|
325
327
|
- GA-07 with unlabeled flash chip
|
|
326
328
|
- GE28F128W30 with 128W30B0
|
|
327
329
|
- K5L2BX_32D_16D_V2 with K5L2833ATA
|
|
328
|
-
- M36XXX_32A_EARTH with
|
|
330
|
+
- M36XXX_32A_EARTH with M36L0R806
|
|
329
331
|
- M36XXX_T32_32D_16D with M36L0R806
|
|
330
332
|
- M5M29-39VF512 with M5M29HD528
|
|
331
333
|
- M5M29G130AN (no PCB text)
|
|
@@ -369,7 +371,7 @@ Many different reproduction cartridges share their flash chip command set, so ev
|
|
|
369
371
|
|
|
370
372
|
The author would like to thank the following very kind people for their help, contributions or documentation (in alphabetical order):
|
|
371
373
|
|
|
372
|
-
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, 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
|
|
373
375
|
|
|
374
376
|
## Third Party Notices and Licenses
|
|
375
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=2Ww-5XEzp828MTXmpBa5VLXdvM6QMDrWDZ_anC8jBAk,170901
|
|
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=odZ-N_2WwUR_oUnkRhPindNiXMzhkbnote53VLCmNKg,188187
|
|
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=5kUj2aV9g_AzWRBeQEgw10Hz9PCO3zFKb3Y9h11DueI,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=mhJZY92KRXKkq295a8yui5aXfVq1oTTzhi_YnsAN9iY,7668
|
|
22
|
+
FlashGBX/hw_GBxCartRW.py,sha256=kKwIF7iq2OkHU-j6360GCla-MA8UEeUmlX0UchMmXfI,10974
|
|
23
|
+
FlashGBX/hw_JoeyJr.py,sha256=X-057WiQbC_Kony0wq1JZ1qUyphphmigdq8imOaxX6Y,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=_uLA9ZZZr93228IG0nCqdX4fVsYwBkCbhpoaoQQuRXA,379195
|
|
27
|
+
FlashGBX/res/fw_GBFlash.zip,sha256=yLhQT18oNyFgErCWtN9N6B1Kzybe1ijeWP64mWXXVac,17482
|
|
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=mqapwg_dKu3AOCvLQjfWafIqNe5Vt78Vw-pM75TWFeE,36772
|
|
33
|
+
FlashGBX/res/fw_GBxCart_RW_v1_4a.zip,sha256=63U8MWewmnD22e9kGqTxATUmzxbz0tkAoQXmAXU2yps,36260
|
|
34
|
+
FlashGBX/res/fw_JoeyJr.zip,sha256=G73Rp_6FaoZ4DIMQ3MSQGauglXaXUgXS7pyE90m8iEA,68964
|
|
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.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
39
|
+
FlashGBX-4.1.dist-info/METADATA,sha256=wgbdITgl9-GZ9lq-vWICaHuik0f6L8ijariVFz5CUkg,19262
|
|
40
|
+
FlashGBX-4.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
41
|
+
FlashGBX-4.1.dist-info/entry_points.txt,sha256=lsg7RmPUIvEI_Q8bA3jIRh8MLF1qIBzUX_yEjD4lJ-g,52
|
|
42
|
+
FlashGBX-4.1.dist-info/top_level.txt,sha256=y6Ssb3YnEYYHNJIPsG_b5ifITM1STAyQXMpjtNOtyzA,9
|
|
43
|
+
FlashGBX-4.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|