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/cas.h

123 lines
5.2 KiB
C

/* *****************************************************************************
* libg1m/format/cas.h -- the older CAS file 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_CAS_H
# define LIBG1M_FORMAT_CAS_H
# include <stdint.h>
# pragma pack(1)
/* See `libg1m/format.h` for general information about what the CASIOLINK
* format is.
*
* The CASIOLINK file format is linked to how the legacy (CAS) protocol works:
* one-byte packets are sent between the two machines (for initiating
* communication, ACKing, NAKing, ...), unless the sent/receiving byte is
* the double-colon ':' (0x3A) -- then it is the beginning of something
* that is more than one-byte long. CAS files do not include the one-byte
* packets, or repeated headers/parts (because of bad checksum or timeouts,
* for example).
*
* Actually, there are three main things that start with a ':'. The main type
* is a header, that describes the content that follows. A content can have
* no content part (e.g. END packet), one content part (e.g. programs), or
* more (e.g. width*height content parts for lists and matrixes, which
* represent the individual cells). These content parts have different formats
* according to the global content part.
*
* But I told you there were three things. The third is a little subtle:
* one header can correspond to several contents. Then we have what we
* call the CAS file*s* part (or heads part).
* An example is 'FN' (set of editor files): we receive the main head,
* with the count of editor files that are sent to us, then we receive one part
* indicating the size of each files, then for each file, we receive one part,
* which is the file content.
*
* We have one protocol, the CASIOLINK protocol (also called 'legacy protocol'
* in the libg1m scope), but we have two different type of headers. The two
* have a fixed width, so they are named by the number of bytes they occupy.
* Notice that, for what I know, content formats don't vary between header
* types. The checksuming technique neither. */
/* ************************************************************************** */
/* CAS40 header */
/* ************************************************************************** */
/* The first header to have appeared is the CAS40 (40 bytes long).
* It is known in CaS as the protocol the CFX-9700G uses.
*
* The header format is the following: */
struct cas40 {
uint8_t data[2]; /* data type -- see `type/cas.c`. */
uint8_t misc[5]; /* type-specific subheader */
uint8_t filename[12]; /* editor filename. */
uint8_t password[12]; /* editor password. */
uint8_t _reserved[7]; /* 0xFFs */
uint8_t checksum;
};
/* The specific bytes are different according to the datatype, but its
* length is fixed. */
/* ************************************************************************** */
/* CAS50 header */
/* ************************************************************************** */
/* The CAS50 (50 bytes long) header appeared later.
* It is known in CaS as the protocol the CFX-9850G uses.
*
* This format was previously named `caspro` in libg1m, before finally
* using the CAS50 name, which was more appropriate.
* Notice that most headers the Graph 100 (~2002) still used CAS40.
*
* The main differences between CAS40 and CAS50 are:
* - CAS50 has a more `struct`-ural approach (no specific subheader);
* - CAS50 include the app you're interacting with.
*
* The header format is the following: */
struct cas50 {
/* types */
uint8_t type[4];
uint8_t data[2];
/* data length */
uint16_t width, height;
uint8_t name[8];
/* variable-related data */
uint8_t prefix[8]; /* "Variable" for vars, 0xFFs otherwise */
uint8_t aux[8]; /* variable: "R\x0A"/"C\x0A", editor: password */
/* something else (?) */
uint8_t nl[2]; /* 'NL'? */
uint8_t _reserved[12];
/* end of packet */
uint8_t checksum;
};
/* As you can guess, the two header formats are, in theory, incompatible.
* In practice, anyhow, they more or less are: libg1m reads the first 7 bytes
* from the header, and tries to identify a CAS50 header; if it doesn't manage,
* it falls back on CAS40.
*
* Here are the content formats for the two header types: */
# pragma pack()
# include <libg1m/format/cas/program.h>
# include <libg1m/format/cas/cell.h> /* list, matrix, variable */
# include <libg1m/format/cas/screenshot.h>
#endif /* LIBG1M_FORMAT_CAS_H */