mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-02-02 12:37:19 +01:00
132 lines
3.6 KiB
Python
Executable File
132 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# 573in1 - Copyright (C) 2022-2024 spicyjpeg
|
|
#
|
|
# 573in1 is free software: you can redistribute it and/or modify it under the
|
|
# terms of the GNU General Public License as published by the Free Software
|
|
# Foundation, either version 3 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# 573in1 is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# 573in1. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
__version__ = "0.4.1"
|
|
__author__ = "spicyjpeg"
|
|
|
|
import sys
|
|
from argparse import ArgumentParser, FileType, Namespace
|
|
from typing import Mapping, TextIO
|
|
|
|
from common.cart import *
|
|
from common.util import serialNumberToString, hexdumpToFile
|
|
|
|
## Dump parser
|
|
|
|
_CHIP_NAMES: Mapping[ChipType, str] = {
|
|
ChipType.NONE: "None",
|
|
ChipType.X76F041: "Xicor X76F041",
|
|
ChipType.X76F100: "Xicor X76F100",
|
|
ChipType.ZS01: "Konami ZS01 (PIC16CE625)"
|
|
}
|
|
|
|
def printDumpInfo(dump: CartDump, output: TextIO):
|
|
if dump.flags & DumpFlag.DUMP_SYSTEM_ID_OK:
|
|
output.write("Digital I/O board:\n")
|
|
output.write(f" DS2401 ID: {dump.systemID.hex('-')}\n")
|
|
output.write(
|
|
f" Serial number: {serialNumberToString(dump.systemID)}\n\n"
|
|
)
|
|
|
|
output.write("Security cartridge:\n")
|
|
output.write(f" Chip type: {_CHIP_NAMES[dump.chipType]}\n")
|
|
|
|
if dump.flags & DumpFlag.DUMP_CART_ID_OK:
|
|
output.write(f" DS2401 ID: {dump.cartID.hex('-')}\n")
|
|
if dump.flags & DumpFlag.DUMP_ZS_ID_OK:
|
|
output.write(f" ZS01 ID: {dump.zsID.hex('-')}\n")
|
|
if dump.flags & DumpFlag.DUMP_CONFIG_OK:
|
|
output.write(f" Configuration: {dump.config.hex('-')}\n")
|
|
|
|
output.write("\nEEPROM dump:\n")
|
|
hexdumpToFile(dump.data, output)
|
|
output.write("\n")
|
|
|
|
## Main
|
|
|
|
def createParser() -> ArgumentParser:
|
|
parser = ArgumentParser(
|
|
description = \
|
|
"Decodes and displays or saves the contents of a QR code cartridge "
|
|
"dump generated by the tool.",
|
|
add_help = False
|
|
)
|
|
|
|
group = parser.add_argument_group("Tool options")
|
|
group.add_argument(
|
|
"-h", "--help",
|
|
action = "help",
|
|
help = "Show this help message and exit"
|
|
)
|
|
|
|
group = parser.add_argument_group("File paths")
|
|
group.add_argument(
|
|
"-i", "--input",
|
|
type = FileType("rb"),
|
|
help = "Read dump (.573 file) or QR string from specified path",
|
|
metavar = "file"
|
|
)
|
|
group.add_argument(
|
|
"-l", "--log",
|
|
type = FileType("at"),
|
|
default = sys.stdout,
|
|
help = "Log cartridge info to specified file (stdout by default)",
|
|
metavar = "file"
|
|
)
|
|
group.add_argument(
|
|
"-e", "--export",
|
|
type = FileType("wb"),
|
|
help = "Export binary dump (.573 file) to specified path",
|
|
metavar = "file"
|
|
)
|
|
|
|
group = parser.add_argument_group("Input data")
|
|
group.add_argument(
|
|
"data",
|
|
type = str,
|
|
nargs = "?",
|
|
help = "QR string to decode (if -i was not passed)"
|
|
)
|
|
|
|
return parser
|
|
|
|
def main():
|
|
parser: ArgumentParser = createParser()
|
|
args: Namespace = parser.parse_args()
|
|
|
|
if args.input:
|
|
with args.input as file:
|
|
data: bytes = file.read()
|
|
|
|
try:
|
|
dump: CartDump = parseCartDump(data)
|
|
except:
|
|
dump: CartDump = parseCartQRString(data.decode("ascii"))
|
|
elif args.data:
|
|
dump: CartDump = parseCartQRString(args.data)
|
|
else:
|
|
parser.error("a dump must be passed on the command line or using -i")
|
|
|
|
if args.log:
|
|
printDumpInfo(dump, args.log)
|
|
if args.export:
|
|
with args.export as file:
|
|
file.write(dump.serialize())
|
|
|
|
if __name__ == "__main__":
|
|
main()
|