mirror of
https://github.com/spicyjpeg/573in1.git
synced 2025-03-01 07:20:42 +01:00
Add magic number and validation to cart dumps
This commit is contained in:
parent
28d89ae860
commit
6875939523
@ -9,9 +9,9 @@ header. The data can be broken down as follows:
|
||||
|
||||
| Offset | Length | Description |
|
||||
| -----: | ------: | :-------------------------------------------------------- |
|
||||
| 0 | 1 | EEPROM chip type: 1 = X76F041, 2 = reserved, 3 = ZS01 |
|
||||
| 1 | 1 | Dump flags, see below |
|
||||
| 2 | 2 | _Reserved_ (should be zero) |
|
||||
| 0 | 2 | Magic number, must be `3d 57` (`0x573d` little endian) |
|
||||
| 2 | 1 | EEPROM chip type: 1 = X76F041, 2 = reserved, 3 = ZS01 |
|
||||
| 3 | 1 | Dump flags, see below |
|
||||
| 4 | 8 | System identifier, zerofilled if none such |
|
||||
| 12 | 8 | Cartridge DS2401 identifier, zerofilled if none such |
|
||||
| 20 | 8 | Cartridge ZS01 identifier, zerofilled if none such |
|
||||
@ -41,11 +41,11 @@ DS2401 chip.
|
||||
|
||||
The format used by QR code dumps is essentially the same as `.573` files, but
|
||||
with an additional layer of compression and a custom base-41 encoding on top of
|
||||
the raw data. Scanning a QR code generated by the tool yields a string similar
|
||||
to this one:
|
||||
the raw data. Scanning a QR code generated by the tool yields a string formatted
|
||||
like this:
|
||||
|
||||
```
|
||||
573::OGI8APY-U7W9553SDY9J+F.TGR1XY92YKJFAGN16ALNTMDDWGM0-U2MPP:60M3NJO1.TU05T5QZ376SRN4S3LFHHGXNTSA6ZSTSQPZBBA96RCXZQ6M01E1CTKR7941MH9D7B0Y.:JZ0PN8K2000::
|
||||
573::OGI8APY- [...] 8K2000::
|
||||
```
|
||||
|
||||
In order to extract the dump data from such a string, a decoder must:
|
||||
@ -75,3 +75,11 @@ while not isEndOfData(input):
|
||||
|
||||
The contents of the dump can then obtained by running the decoded data through
|
||||
zlib's `decompress()` function or a zlib-compatible decompressor.
|
||||
|
||||
## Flash, PCMCIA card, RTC and BIOS dumps
|
||||
|
||||
All dumps of the internal flash, PCMCIA flash cards, RTC RAM and BIOS ROM are
|
||||
stored in raw format without any framing or headers other than the ones present
|
||||
in the data itself. In RTC RAM dumps the last 8 bytes (mapped to the M48T58
|
||||
chip's clock registers) are omitted, thus the resulting dump is 8184 bytes long
|
||||
rather than 8192.
|
||||
|
@ -283,7 +283,7 @@ bool App::_cartRestoreWorker(void) {
|
||||
|
||||
if (length < (sizeof(newDump) - sizeof(newDump.data)))
|
||||
goto _fileError;
|
||||
if (false) // TODO: validate dump
|
||||
if (!newDump.validateMagic())
|
||||
goto _fileError;
|
||||
if (length != newDump.getDumpLength())
|
||||
goto _fileError;
|
||||
|
@ -148,6 +148,8 @@ public:
|
||||
|
||||
/* Cartridge dump structure */
|
||||
|
||||
static constexpr uint16_t DUMP_HEADER_MAGIC = 0x573d;
|
||||
|
||||
struct ChipSize {
|
||||
public:
|
||||
size_t dataLength, publicDataOffset, publicDataLength;
|
||||
@ -157,9 +159,9 @@ extern const ChipSize CHIP_SIZES[NUM_CHIP_TYPES];
|
||||
|
||||
class [[gnu::packed]] Dump {
|
||||
public:
|
||||
uint16_t magic;
|
||||
ChipType chipType;
|
||||
uint8_t flags;
|
||||
uint8_t _reserved[2];
|
||||
|
||||
Identifier systemID, cartID, zsID;
|
||||
|
||||
@ -167,14 +169,17 @@ public:
|
||||
uint8_t data[512];
|
||||
|
||||
inline Dump(void)
|
||||
: chipType(NONE), flags(0) {
|
||||
_reserved[0] = 0;
|
||||
_reserved[1] = 0;
|
||||
}
|
||||
: magic(DUMP_HEADER_MAGIC), chipType(NONE), flags(0) {}
|
||||
|
||||
inline const ChipSize &getChipSize(void) const {
|
||||
return CHIP_SIZES[chipType];
|
||||
}
|
||||
inline bool validateMagic(void) const {
|
||||
return
|
||||
(magic == DUMP_HEADER_MAGIC) &&
|
||||
(chipType > 0) &&
|
||||
(chipType < NUM_CHIP_TYPES);
|
||||
}
|
||||
inline size_t getDumpLength(void) const {
|
||||
return (sizeof(Dump) - sizeof(data)) + getChipSize().dataLength;
|
||||
}
|
||||
|
@ -166,7 +166,8 @@ class PublicIdentifierSet:
|
||||
|
||||
## Cartridge dump structure
|
||||
|
||||
_DUMP_HEADER_STRUCT: Struct = Struct("< 2B 2x 8s 8s 8s 8s 8s")
|
||||
_DUMP_HEADER_STRUCT: Struct = Struct("< H 2B 8s 8s 8s 8s 8s")
|
||||
_DUMP_HEADER_MAGIC: int = 0x573d
|
||||
|
||||
_CHIP_SIZES: Mapping[ChipType, tuple[int, int, int]] = {
|
||||
ChipType.X76F041: ( 512, 384, 128 ),
|
||||
@ -191,6 +192,7 @@ class Dump:
|
||||
|
||||
def serialize(self) -> bytes:
|
||||
return _DUMP_HEADER_STRUCT.pack(
|
||||
_DUMP_HEADER_MAGIC,
|
||||
self.chipType,
|
||||
self.flags,
|
||||
self.systemID,
|
||||
@ -201,8 +203,12 @@ class Dump:
|
||||
) + self.data
|
||||
|
||||
def parseDump(data: bytes) -> Dump:
|
||||
chipType, flags, systemID, cartID, zsID, dataKey, config = \
|
||||
magic, chipType, flags, systemID, cartID, zsID, dataKey, config = \
|
||||
_DUMP_HEADER_STRUCT.unpack(data[0:_DUMP_HEADER_STRUCT.size])
|
||||
|
||||
if magic != _DUMP_HEADER_MAGIC:
|
||||
raise ValueError(f"invalid or unsupported dump format: 0x{magic:04x}")
|
||||
|
||||
dataLength, _, _ = _CHIP_SIZES[chipType]
|
||||
|
||||
return Dump(
|
||||
|
Loading…
x
Reference in New Issue
Block a user