cake
/
libcasio
Archived
1
1
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
libcasio/include/libcasio/format/std.h

274 lines
8.8 KiB
C

/* ****************************************************************************
* libcasio/format/std.h -- the CASIO "standard" file format description.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#ifndef LIBCASIO_FORMAT_STD_H
# define LIBCASIO_FORMAT_STD_H
# include "../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* This format is used by CASIO with its calculator for storing things
* like add-ins (compiled programs), MCS (main memory saves), and others.
* In fact, there is no name for the general format, only names for the
* "subformats" based on this one (which are mainly made of their extensions,
* such as G1M or G3P). */
/* ---
* Standard Header.
* --- */
/* It all starts with a header, called Standard Header by Simon Lothar.
* This Standard Header contains the total filesize, the standard type (add-in,
* MCS, e-acts), some data that will be useful for the MCS type, and some
* magic and control bytes.
*
* For some reason, this StandardHeader is INVERTED on every file it's on,
* you will have to apply a NOT operation on its bytes for it to make sense.
* Keep in mind that, everywhere in the header, multi-bytes integers
* are BIG ENDIAN.
*
* The LSB is the Least Significant Byte: once adapted to the host endianness,
* it can simply be obtained by bitwise-AND-ing with 0xff. */
typedef struct casio_standard_header_s {
/* the file identifier */
casio_uint8_t casio_standard_header_main_id[8];
/* our subtype! */
casio_uint8_t casio_standard_header_subtype[6];
/* first control byte: filesize LSB + 0x41 */
casio_uint8_t casio_standard_header_control;
/* said to be 0x01, but doesn't need to */
casio_uint8_t casio_standard_header_align_one;
/* total filesize */
casio_uint32_t casio_standard_header_filesize;
/* second control byte: filesize LSB + 0xb8 */
casio_uint8_t casio_standard_header_control2;
/* alignment */
casio_uint8_t casio_standard_header__align0;
/* sum of 8 16-bit values starting at 0x300? */
casio_uint8_t casio_standard_header_checksum[2];
/* alignment */
casio_uint8_t casio_standard_header__align1[4];
/* is obfuscated - useful for G3P */
casio_uint8_t casio_standard_header_obfuscated0;
casio_uint8_t casio_standard_header_obfuscated1;
/* number of objects contained (useful for MCS filetype) */
casio_uint16_t casio_standard_header_number;
} casio_standard_header_t;
/* At the beginning, we thought "USBPower" was some magic sequence we would
* systematically find in the "main_id" field. But counter examples came:
* the G3L, whose main ID was "Ly755 ", and the C2P.
*
* We also thought the subtype was only one-byte long, but the C2P came along
* with its "c2p\0\0\0" subtype.
* All main ID/types correspondances are in the `src/utils/type.c` file.
* From a user program, you can use the functions
* in `include/libcasio/formatutils.h`.
*
* After the Standard Header is read and the type is read, we have parts,
* each with their own subheaders and their own subtilities. */
/* ---
* Standard Subheader.
* --- */
/* Some Prizm/Classpad-related formats (language, fkeys, add-ins) use a
* common subheader followed by a platform-specific subheader (which is the
* same size of Prizm and Classpad, but doesn't seem to have the same
* field organization). Here is the common subheader structure: */
typedef struct casio_standard_subheader_s {
/* checksum */
casio_uint32_t casio_standard_subheader_checksum;
/* file type:
* - 0x00: picture (not used with this header);
* - 0x01: add-in;
* - 0x02: function keys;
* - 0x04: language files; */
casio_uint8_t casio_standard_subheader_filetype;
/* platform:
* - 0x00: fx-CP;
* - 0x01: Prizm */
casio_uint8_t casio_standard_subheader_platform;
/* unknown */
casio_uint8_t casio_standard_subheader__unknown0[4];
/* size of the data + footer? */
casio_uint32_t casio_standard_subheader_df_size;
/* control:
* - for a G3A: filesize - 0x7000 - 4
* - for a C1A: filesize - 0x1000 - 4 */
casio_uint32_t casio_standard_subheader_control;
/* unknown */
casio_uint8_t casio_standard_subheader__unknown1[4];
/* message zone size - unreliable (valid could have zero) */
casio_uint32_t casio_standard_subheader_message_zone_size;
/* model; for C1A: GY437 */
casio_uint8_t casio_standard_subheader_models[6];
/* title/language name */
casio_uint8_t casio_standard_subheader_title[28];
/* filesize */
casio_uint32_t casio_standard_subheader_filesize;
/* internal name */
casio_uint8_t casio_standard_subheader_internal_name[11];
/* language labels */
casio_uint8_t casio_standard_subheader_labels[8][24];
/* eAct strip flag (0x00: can't be used, 0x01: can be used) */
casio_uint8_t casio_standard_subheader_eact_strip_flag;
/* unknown */
casio_uint8_t casio_standard_subheader__unknown2[4];
/* version: MM.mm.ffff */
casio_uint8_t casio_standard_subheader_version[10];
/* unknown */
casio_uint8_t casio_standard_subheader__unknown3[2];
/* timestamp: YYYY.MMDD.HHmm */
casio_uint8_t casio_standard_subheader_timestamp[14];
} casio_standard_subheader_t;
/* Here is the Prizm-specific subheader: */
typedef struct casio_standard_prizm_subheader_s {
/* unknown */
casio_uint8_t casio_standard_prizm_subheader__unknown0[38];
/* eAct strip labels */
casio_uint8_t casio_standard_prizm_subheader_eact_strip_labels[8][36];
/* eAct icon */
casio_uint8_t casio_standard_prizm_subheader_icon[0x300];
/* unknown stuff */
casio_uint8_t casio_standard_prizm_subheader__unknown1[0x90C];
/* language name (null terminated?) */
casio_uint8_t casio_standard_prizm_subheader_language_name[16];
/* language salutation (null terminated?) */
casio_uint8_t casio_standard_prizm_subheader_language_salutation[16];
/* filename (extension included) */
casio_uint8_t casio_standard_prizm_subheader_filename[0x144];
} casio_standard_prizm_subheader_t;
/* And here is the Classpad-specific subheader: */
typedef struct casio_standard_classpad_subheader_s {
/* unknown */
casio_uint8_t casio_standard_classpad_subheader__unknown0[0x46];
/* the C1A filename */
casio_uint8_t casio_standard_classpad_subheader_filename[0x144];
/* unknown */
casio_uint8_t casio_standard_classpad_subheader__unknown1[0x2C];
/* icon (maybe 46x30 pixels? packed 1-bit) */
casio_uint8_t casio_standard_classpad_subheader_icon[172];
/* unknown */
casio_uint8_t casio_standard_classpad_subheader__unknown2[0xC54];
} casio_standard_classpad_subheader_t;
/* Also, if the platform is the Prizm, there is a footer at the end of the
* file, which is only made of a 32-bit checksum that should be equal to
* the subheader checksum. */
/* ---
* Standard Picture Header.
* --- */
/* Picture formats (C2P, G3P) have a common picture standard subheader, which
* is the following: */
typedef struct casio_standard_picheader_s {
/* magic sequence: "CC" for the Classpad, "CP" for the Prizm */
casio_uint8_t casio_standard_picheader_cp[2];
/* "0100", either in raw (0x00, 0x01) for G3P
* or in ASCII (0x30, 0x31) for C2P */
casio_uint8_t casio_standard_picheader_magic[4];
/* magic sequences:
* - "ColorCP\0" for the C2P;
* - "LY755\0\0\0" for the G3P. */
casio_uint8_t casio_standard_picheader_magic2[8];
/* unknown byte: 0x02 on the G3P, 0x00 on the C2P */
casio_uint8_t casio_standard_picheader__unknown0;
/* unused byte */
casio_uint8_t casio_standard_picheader__unused;
/* filesize after the StandardHeader */
casio_uint32_t casio_standard_picheader_filesize;
/* "Always contains the 32-bit big-endian integer 0x00000001" */
casio_uint32_t casio_standard_picheader__alwaysone;
/* subsize (what's after the standard picture header) */
casio_uint32_t casio_standard_picheader_subsize;
/* unknown gap */
casio_uint8_t casio_standard_picheader__unknown2[0x7C];
} casio_standard_picheader_t;
/* Then we have the specific header -- see `libcasio/format/std/picture.h`. */
/* ---
* Flavors.
* --- */
/* Where do you want to go next? Pick your poison. */
CASIO_END_NAMESPACE
# pragma pack()
# include "std/addin.h"
# include "std/eact.h"
# include "std/mcs.h"
# include "std/picture.h"
# include "std/lang.h"
# include "std/fkey.h"
#endif /* LIBCASIO_FORMAT_STD_H */