cake
/
libg1m
Archived
1
0
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.
libg1m/include/libg1m/format.h

101 lines
3.5 KiB
C

/* *****************************************************************************
* libg1m/format.h -- the G1M format description.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libg1m.
* libg1m 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.
*
* libg1m 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 libg1m; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************** */
#ifndef LIBG1M_FORMAT_H
# define LIBG1M_FORMAT_H
# include <stdint.h>
# pragma pack(1)
/* Welcome on this new episode of Monster Circus! Today we'll present to you
* something that you might not be able to forget: the G1M format.
*
* 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.
*
* It all starts with a header, called Standard Header by Simon Lothar.
* This Standard Header contains the total filesize, the G1M 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. */
struct standard_header {
/* the file identifier */
uint8_t main_id[8];
/* our subtype! */
uint8_t subtype[6];
/* first control byte: filesize LSB + 0x41 */
uint8_t control;
/* said to be 0x01, but doesn't need to */
uint8_t align_one;
/* total filesize */
uint32_t filesize;
/* second control byte: filesize LSB + 0xb8 */
uint8_t control2;
/* alignment */
uint8_t align[8];
/* is obfuscated - useful for G3P */
uint8_t obfuscated;
/* number of objects contained (useful for MCS filetype) */
uint16_t number;
};
/* 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/libg1m/formatutils.h`. */
# pragma pack()
/* After the Standard Header is read and the type is read, we have parts,
* each with their own subheaders and their own subtilities.
*
* Where do you want to start? Pick your poison. */
# include <libg1m/format/addin.h>
# include <libg1m/format/eact.h>
# include <libg1m/format/mcs.h>
# include <libg1m/format/storage.h>
# include <libg1m/format/picture.h>
# include <libg1m/format/lang.h>
# include <libg1m/format/fkey.h>
#endif /* LIBG1M_FORMAT_H */