mirror of
https://github.com/lesserkuma/FlashGBX.git
synced 2026-09-13 03:15:26 -05:00
3.15
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
# Release notes
|
||||
### v3.15 (released 2022-07-05)
|
||||
- Improved support for several flash cartridge types
|
||||
- Confirmed support for the Catskull 32k Gameboy Flash Cart *(thanks CodyWick13)*
|
||||
- Minor bug fixes and improvements
|
||||
|
||||
### v3.14 (released 2022-06-11)
|
||||
- Fixed a bug with extracting the Game Boy Camera’s Game Face image *(thanks 2358)*
|
||||
- Improved the default file names, now includes the ROM revision information as well
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# FlashGBX
|
||||
# Author: Lesserkuma (github.com/lesserkuma)
|
||||
|
||||
import sys, os, time, datetime, re, json, platform, subprocess, requests, webbrowser, pkg_resources, struct, math
|
||||
import sys, os, time, datetime, json, platform, subprocess, requests, webbrowser, pkg_resources, struct, math
|
||||
from .pyside import QtCore, QtWidgets, QtGui, QApplication
|
||||
from .RomFileDMG import RomFileDMG
|
||||
from .RomFileAGB import RomFileAGB
|
||||
@@ -2297,9 +2297,9 @@ class FlashGBX_GUI(QtWidgets.QWidget):
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
if callable(getattr(qt_app, "exec", None)):
|
||||
qt_app.exec() # PySide6
|
||||
except AttributeError:
|
||||
else:
|
||||
qt_app.exec_() # PySide2
|
||||
|
||||
qt_app = QApplication(sys.argv)
|
||||
|
||||
@@ -179,8 +179,8 @@ class Flashcart:
|
||||
time.sleep(0.001)
|
||||
|
||||
def VerifyFlashID(self):
|
||||
if "read_identifier" not in self.CONFIG["commands"]: return False
|
||||
if len(self.CONFIG["flash_ids"]) == 0: return False
|
||||
if "read_identifier" not in self.CONFIG["commands"]: return (False, [])
|
||||
if len(self.CONFIG["flash_ids"]) == 0: return (False, [])
|
||||
if "power_cycle" in self.CONFIG and self.CONFIG["power_cycle"] is True:
|
||||
self.CART_POWERCYCLE_FNCPTR()
|
||||
self.Reset()
|
||||
|
||||
@@ -7,7 +7,7 @@ from enum import Enum
|
||||
|
||||
# Common constants
|
||||
APPNAME = "FlashGBX"
|
||||
VERSION_PEP440 = "3.14"
|
||||
VERSION_PEP440 = "3.15"
|
||||
VERSION = "v{:s}".format(VERSION_PEP440)
|
||||
DEBUG = False
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"voltage":3.3,
|
||||
"flash_size":0x2000000,
|
||||
"sector_size":0x20000,
|
||||
"chip_erase_timeout":120,
|
||||
"command_set":"AMD",
|
||||
"commands":{
|
||||
"reset":[
|
||||
@@ -38,6 +39,22 @@
|
||||
[ null, null, null ],
|
||||
[ "SA", 0xFFFF, 0xFFFF ]
|
||||
],
|
||||
"chip_erase":[
|
||||
[ 0xAAA, 0xA9 ],
|
||||
[ 0x555, 0x56 ],
|
||||
[ 0xAAA, 0x80 ],
|
||||
[ 0xAAA, 0xA9 ],
|
||||
[ 0x555, 0x56 ],
|
||||
[ 0xAAA, 0x10 ]
|
||||
],
|
||||
"chip_erase_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ 0, 0xFFFF, 0xFFFF ]
|
||||
],
|
||||
"buffer_write":[
|
||||
[ 0xAAA, 0xA9 ],
|
||||
[ 0x555, 0x56 ],
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"type":"DMG",
|
||||
"names":[
|
||||
"Ferrante Crafts cart 32 KB"
|
||||
"Ferrante Crafts cart 32 KB",
|
||||
"Catskull 32k Gameboy Flash Cart"
|
||||
],
|
||||
"flash_ids":[
|
||||
[ 0xBF, 0xB5, 0x01, 0xFF ]
|
||||
|
||||
52
FlashGBX/config/fc_DMG_iG_1MB_2.txt
Normal file
52
FlashGBX/config/fc_DMG_iG_1MB_2.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"type":"DMG",
|
||||
"names":[
|
||||
"insideGadgets 1 MB, 32 KB FRAM v2.0"
|
||||
],
|
||||
"flash_ids":[],
|
||||
"voltage":5,
|
||||
"flash_size":0x100000,
|
||||
"start_addr":0,
|
||||
"first_bank":1,
|
||||
"write_pin":"WR",
|
||||
"chip_erase_timeout":120,
|
||||
"command_set":"AMD",
|
||||
"commands":{
|
||||
"reset":[
|
||||
[ 0, 0xF0 ]
|
||||
],
|
||||
"read_identifier":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x90 ]
|
||||
],
|
||||
"chip_erase":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x80 ],
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x10 ]
|
||||
],
|
||||
"chip_erase_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ 0, 0xFF, 0xFF ]
|
||||
],
|
||||
"single_write":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0xA0 ],
|
||||
[ "PA", "PD" ]
|
||||
],
|
||||
"single_write_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ]
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,22 @@
|
||||
{
|
||||
"type":"DMG",
|
||||
"names":[
|
||||
"insideGadgets 2 MB, 128 KB SRAM/32 KB FRAM"
|
||||
"insideGadgets 2 MB, 128 KB SRAM/32 KB FRAM (T)"
|
||||
],
|
||||
"flash_ids":[
|
||||
[ 0x01, 0x01, 0xD2, 0xD2 ],
|
||||
[ 0x01, 0x01, 0xD8, 0xD8 ]
|
||||
[ 0x01, 0x01, 0xD2, 0xD2 ]
|
||||
],
|
||||
"voltage":5,
|
||||
"flash_size":0x200000,
|
||||
"start_addr":0,
|
||||
"first_bank":1,
|
||||
"write_pin":"WR",
|
||||
"sector_size":[
|
||||
[0x10000, 31],
|
||||
[0x8000, 1],
|
||||
[0x2000, 2],
|
||||
[0x4000, 1]
|
||||
],
|
||||
"chip_erase_timeout":120,
|
||||
"command_set":"AMD",
|
||||
"commands":{
|
||||
@@ -39,6 +44,22 @@
|
||||
[ null, null, null ],
|
||||
[ 0, 0xFF, 0xFF ]
|
||||
],
|
||||
"sector_erase":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x80 ],
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ "SA", 0x30 ]
|
||||
],
|
||||
"sector_erase_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ "SA", 0xFF, 0xFF ]
|
||||
],
|
||||
"single_write":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
|
||||
76
FlashGBX/config/fc_DMG_iG_2MB_2.txt
Normal file
76
FlashGBX/config/fc_DMG_iG_2MB_2.txt
Normal file
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"type":"DMG",
|
||||
"names":[
|
||||
"insideGadgets 2 MB, 128 KB SRAM/32 KB FRAM (B)"
|
||||
],
|
||||
"flash_ids":[
|
||||
[ 0x01, 0x01, 0xD8, 0xD8 ]
|
||||
],
|
||||
"voltage":5,
|
||||
"flash_size":0x200000,
|
||||
"start_addr":0,
|
||||
"first_bank":1,
|
||||
"write_pin":"WR",
|
||||
"sector_size":[
|
||||
[0x4000, 1],
|
||||
[0x2000, 2],
|
||||
[0x8000, 1],
|
||||
[0x10000, 31]
|
||||
],
|
||||
"chip_erase_timeout":120,
|
||||
"command_set":"AMD",
|
||||
"commands":{
|
||||
"reset":[
|
||||
[ 0, 0xF0 ]
|
||||
],
|
||||
"read_identifier":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x90 ]
|
||||
],
|
||||
"chip_erase":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x80 ],
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x10 ]
|
||||
],
|
||||
"chip_erase_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ 0, 0xFF, 0xFF ]
|
||||
],
|
||||
"sector_erase":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x80 ],
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ "SA", 0x30 ]
|
||||
],
|
||||
"sector_erase_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ "SA", 0xFF, 0xFF ]
|
||||
],
|
||||
"single_write":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0xA0 ],
|
||||
[ "PA", "PD" ]
|
||||
],
|
||||
"single_write_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ]
|
||||
]
|
||||
}
|
||||
}
|
||||
71
FlashGBX/config/fc_DMG_iG_4MB_2.txt
Normal file
71
FlashGBX/config/fc_DMG_iG_4MB_2.txt
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"type":"DMG",
|
||||
"names":[
|
||||
"insideGadgets 4 MB (S29JL032J)"
|
||||
],
|
||||
"flash_ids":[
|
||||
[ 0x01, 0x01, 0x56, 0x56 ]
|
||||
],
|
||||
"voltage":5,
|
||||
"flash_size":0x400000,
|
||||
"start_addr":0x4000,
|
||||
"first_bank":0,
|
||||
"write_pin":"WR",
|
||||
"sector_size_from_cfi":true,
|
||||
"chip_erase_timeout":60,
|
||||
"command_set":"AMD",
|
||||
"commands":{
|
||||
"reset":[
|
||||
[ 0, 0xF0 ]
|
||||
],
|
||||
"read_identifier":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x90 ]
|
||||
],
|
||||
"chip_erase":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x80 ],
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x10 ]
|
||||
],
|
||||
"chip_erase_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ 0, 0xFF, 0xFF ]
|
||||
],
|
||||
"sector_erase":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0x80 ],
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ "SA", 0x30 ]
|
||||
],
|
||||
"sector_erase_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ "SA", 0xFF, 0xFF ]
|
||||
],
|
||||
"single_write":[
|
||||
[ 0xAAA, 0xAA ],
|
||||
[ 0x555, 0x55 ],
|
||||
[ 0xAAA, 0xA0 ],
|
||||
[ "PA", "PD" ]
|
||||
],
|
||||
"single_write_wait_for":[
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ],
|
||||
[ null, null, null ]
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1394,7 +1394,7 @@ class GbxDevice:
|
||||
self._write(self.DEVICE_CMD["SET_VOLTAGE_5V"])
|
||||
time.sleep(0.1)
|
||||
self._write(self.DEVICE_CMD["SET_MODE_DMG"])
|
||||
elif self.MODE == "DMG":
|
||||
elif self.MODE == "AGB":
|
||||
self._write(self.DEVICE_CMD["SET_MODE_AGB"])
|
||||
|
||||
for f in range(1, len(supported_carts)):
|
||||
@@ -1446,13 +1446,14 @@ class GbxDevice:
|
||||
size = supp_flash_types[1][flash_types[0]]["flash_size"]
|
||||
size_undetected = False
|
||||
for i in range(0, len(flash_types)):
|
||||
if size != supp_flash_types[1][flash_types[i]]["flash_size"]:
|
||||
size_undetected = True
|
||||
if "flash_size" in supp_flash_types[1][flash_types[i]]:
|
||||
if size != supp_flash_types[1][flash_types[i]]["flash_size"]:
|
||||
size_undetected = True
|
||||
|
||||
if size_undetected:
|
||||
if isinstance(cfi, dict) and "device_size" in cfi:
|
||||
for i in range(0, len(flash_types)):
|
||||
if cfi['device_size'] == supp_flash_types[1][flash_types[i]]["flash_size"]:
|
||||
if "flash_size" in supp_flash_types[1][flash_types[i]] and cfi['device_size'] == supp_flash_types[1][flash_types[i]]["flash_size"]:
|
||||
flash_type_id = flash_types[i]
|
||||
size_undetected = False
|
||||
break
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# This code is used for official firmware of GBxCart v1.3 only and this code is pure chaos, sorry
|
||||
# Refer to hw_GBxCartRW.py for the much cleaner rewrite (used for GBxCart RW v1.4 and firmware L1 on v1.3)
|
||||
|
||||
import time, math, struct, traceback, zlib, copy, hashlib, os, platform, datetime
|
||||
import time, math, struct, traceback, zlib, copy, hashlib, os, datetime
|
||||
import serial, serial.tools.list_ports
|
||||
from serial import SerialException
|
||||
from .RomFileDMG import RomFileDMG
|
||||
@@ -1146,7 +1146,7 @@ class GbxDevice:
|
||||
if header is False or len(header) != 0x180: raise Exception("Couldn’t read the cartridge information. Please try again.")
|
||||
if Util.DEBUG:
|
||||
with open("debug_header.bin", "wb") as f: f.write(header)
|
||||
|
||||
|
||||
# Check for DACS
|
||||
dacs_8m = False
|
||||
if header[0x04:0x04+0x9C] == bytearray([0x00] * 0x9C):
|
||||
@@ -1490,10 +1490,10 @@ class GbxDevice:
|
||||
break
|
||||
self.INFO["dump_info"]["agb_savelib"] = temp_ver
|
||||
self.INFO["dump_info"]["agb_save_flash_id"] = None
|
||||
if "FLASH" in temp_ver:
|
||||
agb_save_flash_id = self.ReadFlashSaveID()
|
||||
if agb_save_flash_id is not False and len(agb_save_flash_id) == 3:
|
||||
self.INFO["dump_info"]["agb_save_flash_id"] = agb_save_flash_id
|
||||
#if "FLASH" in temp_ver:
|
||||
# agb_save_flash_id = self.ReadFlashSaveID()
|
||||
# if agb_save_flash_id is not False and len(agb_save_flash_id) == 3:
|
||||
# self.INFO["dump_info"]["agb_save_flash_id"] = agb_save_flash_id
|
||||
|
||||
self.INFO["rom_checksum_calc"] = chk
|
||||
|
||||
|
||||
Binary file not shown.
@@ -32,6 +32,8 @@ Available in the GitHub [Releases](https://github.com/lesserkuma/FlashGBX/releas
|
||||
* Windows Setup: An installer that will add the application to the start menu and optionally create a desktop icon
|
||||
* Windows Portable: Have everything in one place including the config files
|
||||
|
||||
These work for installing fresh and upgrading from an older version.
|
||||
|
||||
### Run using Python (Linux, macOS, Windows)
|
||||
|
||||
#### Installing
|
||||
@@ -93,6 +95,7 @@ Use this command in a Terminal or Command Prompt window to launch the installed
|
||||
- 29LV Series Flash BOY with 29LV160DB
|
||||
- BLAZE Xploder GB
|
||||
- BUNG Doctor GB Card 64M
|
||||
- Catskull 32k Gameboy Flash Cart
|
||||
- DIY cart with AM29F010
|
||||
- DIY cart with AM29F016
|
||||
- DIY cart with AM29F032
|
||||
|
||||
2
setup.py
2
setup.py
@@ -4,7 +4,7 @@ with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read(
|
||||
|
||||
setuptools.setup(
|
||||
name="FlashGBX",
|
||||
version="3.14",
|
||||
version="3.15",
|
||||
author="Lesserkuma",
|
||||
description="Reads and writes Game Boy and Game Boy Advance cartridge data. Supported hardware: GBxCart RW v1.3 and v1.4 by insideGadgets.",
|
||||
url="https://github.com/lesserkuma/FlashGBX",
|
||||
|
||||
Reference in New Issue
Block a user