cake
/
libcasio
Archived
1
1
Fork 0

Going on.

This commit is contained in:
Thomas Touhey 2018-05-04 21:19:12 +02:00
parent 31ad4cb0b6
commit c3a3b05917
No known key found for this signature in database
GPG Key ID: 2ECEB0517AD947FB
60 changed files with 1495 additions and 528 deletions

View File

@ -46,7 +46,7 @@
CWERROR := all extra no-attributes no-unused-macros no-vla no-multichar
ifneq ($(MORE_WARNINGS),)
CWERROR += shadow write-strings redundant-decls format format-nonliteral \
CWERROR += shadow write-strings redundant-decls format \
format-security implicit-function-declaration \
date-time missing-prototypes return-type pointer-arith \
stack-protector no-unused-parameter
@ -101,6 +101,11 @@ endif
DEP_libcasio_CFLAGS := -I include
DEP_libcasio_LIBS := -L build -lcasio
# standard math library.
DEP_math_CFLAGS :=
DEP_math_LIBS := -lm
# zlib, compression library.
DEP_zlib_CFLAGS := $(shell $(PKGCONFIG) zlib --cflags)
@ -128,7 +133,7 @@ endif
# Dependencies.
L_DEPS :=
L_DEPS_PRIV := zlib $(if $(NO_LIBUSB),,libusb)
L_DEPS_PRIV := zlib $(if $(NO_LIBUSB),,libusb) math
# Folders.

View File

@ -27,10 +27,12 @@
CASIO_BEGIN_NAMESPACE
CASIO_BEGIN_DECLS
/* ************************************************************************* */
/* Built-in streams */
/* ************************************************************************* */
/* ---
* Built-in streams.
* --- */
/* Make a stream using the standard FILE interface. */
# ifndef LIBCASIO_DISABLED_FILE
CASIO_EXTERN int CASIO_EXPORT casio_open_stream_file
OF((casio_stream_t **casio__stream,
@ -39,6 +41,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_open_stream_file
# endif
/* Make a stream using the POSIX STREAMS interface. */
# if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
CASIO_EXTERN int CASIO_EXPORT casio_opencom_streams
OF((casio_stream_t **casio__stream, const char *casio__path));
@ -55,12 +58,14 @@ CASIO_EXTERN int CASIO_EXPORT casio_open_stream_fd
# endif
/* Make a stream using libusb. */
# ifndef LIBCASIO_DISABLED_LIBUSB
CASIO_EXTERN int CASIO_EXPORT casio_openusb_libusb
OF((casio_stream_t **casio__stream));
# endif
/* Make a stream using the Microsoft Windows API. */
# if defined(_WIN16) || defined(_WIN32) || defined(_WIN64) \
|| defined(__WINDOWS__)
CASIO_EXTERN int CASIO_EXPORT casio_openusb_windows
@ -70,10 +75,13 @@ CASIO_EXTERN int CASIO_EXPORT casio_opencom_windows
# else
# define LIBCASIO_DISABLED_WINDOWS
# endif
/* ************************************************************************* */
/* Built-in filesystems */
/* ************************************************************************* */
/* ---
* Built-in filesystems.
* --- */
/* Make a POSIX filesystem interface. */
# if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
CASIO_EXTERN int CASIO_EXPORT casio_open_posix_fs
OF((casio_fs_t **casio__filesystem));
@ -82,33 +90,41 @@ CASIO_EXTERN int CASIO_EXPORT casio_open_posix_fs
# endif
/* Make a Windows API filesystem interface. */
# ifndef LIBCASIO_DISABLED_WINDOWS
CASIO_EXTERN int CASIO_EXPORT casio_open_windows_fs
OF((casio_fs_t **casio__filesystem));
# endif
/* ************************************************************************* */
/* Built-in serial devices listing */
/* ************************************************************************* */
/* ---
* Built-in serial devices listing.
* --- */
/* List serial devices on Linux. */
# ifdef __linux__
CASIO_EXTERN int CASIO_EXPORT casio_comlist_linux
OF((casio_list_com_t *casio__callback, void *casio__cookie));
# endif
/* List serial devices on MacOS/OS X. */
# if defined(__APPLE__) && defined(__MACH__)
CASIO_EXTERN int CASIO_EXPORT casio_comlist_macos
OF((casio_list_com_t *casio__callback, void *casio__cookie));
# endif
/* List serial devices on Microsoft Windows. */
# ifndef LIBCASIO_DISABLED_WINDOWS
CASIO_EXTERN int CASIO_EXPORT casio_comlist_windows
OF((casio_list_com_t *casio__callback, void *casio__cookie));
# endif
/* ************************************************************************* */
/* Built-in functions */
/* ************************************************************************* */
/* ---
* Built-in functions.
* --- */
/* As there is no portable sleep function, libcasio implements one.
* It takes a callback, of the following form: */

View File

@ -38,12 +38,15 @@
# include <time.h>
/* Check the library version. */
# define LIBCASIO_PREREQ(CASIO__MAJ, CASIO__MIN) \
((CASIO__MAJ) > (LIBCASIO_MAJOR) || \
((CASIO__MAJ) == (LIBCASIO_MAJOR) && (CASIO__MIN) >= (LIBCASIO_MINOR)))
/* ************************************************************************* */
/* Check for compilers */
/* ************************************************************************* */
/* ---
* Check for compilers.
* --- */
/* First, GCC. */
# if defined(CASIO_GNUC_PREREQ)
@ -62,18 +65,22 @@
# else
# define CASIO_MSC_PREREQ(CASIO__MAJ, CASIO__MIN) 0
# endif
/* ************************************************************************* */
/* Extern functions */
/* ************************************************************************* */
/* ---
* Extern functions.
* --- */
/* Some platforms require more than simply 'extern'.
* Here are macros to control this. */
# define CASIO_EXTERN extern
# define CASIO_EXPORT
# define CASIO_LOCAL static
/* ************************************************************************* */
/* Enumerations */
/* ************************************************************************* */
/* ---
* Enumerations.
* --- */
/* Enumerations can be great thanks to the compiler: better warnings,
* better debug, better coding! */
@ -83,9 +90,11 @@
# else /* K&R C, no enums! */
# define LIBCASIO_USE_ENUMS 0
# endif
/* ************************************************************************* */
/* C++ declarations and namespaces management */
/* ************************************************************************* */
/* ---
* C++ declarations and namespaces management.
* --- */
/* libcasio is made in C. */
# if 0 /* hey, what about this? */
@ -104,10 +113,12 @@
# define CASIO_END_DECLS
# define CASIO_END_NAMESPACE
# endif
/* ************************************************************************* */
/* `casio_attr_wur`: warn if the result is unused. */
/* ************************************************************************* */
/* That's pretty much all of it. */
/* ---
* Warn if the result is unused.
* --- */
/* To do that, we'll use the `casio_attr_wur` attribute. */
# if CASIO_GNUC_PREREQ(4, 0)
# define casio_attr_wur __attribute__((warn_unused_result))

View File

@ -19,6 +19,7 @@
#ifndef LIBCASIO_CDEFS_INTEGERS_H
# define LIBCASIO_CDEFS_INTEGERS_H 1
# include "../cdefs.h"
CASIO_BEGIN_NAMESPACE
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
@ -54,12 +55,15 @@ typedef uint32_t casio_uint32_t;
typedef unsigned char casio_uint8_t;
/* 16-bit integer. */
# if (USHRT_MAX > 0xffffUL)
# error "No 16-bit type, exiting!"
# endif
# define CASIO_P16 "h"
typedef unsigned short casio_uint16_t;
/* 32-bit integer. */
# if (UINT_MAX == 0xffffffffUL)
# define CASIO_P32 ""
typedef unsigned int casio_uint32_t;
@ -67,11 +71,13 @@ typedef unsigned int casio_uint32_t;
# define CASIO_P32 "l"
typedef unsigned long casio_uint32_t;
# else
/* There is nothing between `char` and `short` and `char` is always
/* There is nothing between `char` and `short`, and `char` is always
* byte-wide;
* `long long` is not defined in C89, and even if it can be used as a
* compiler extension for C89, it is supposed to be 64-bit or more.
* So basically we're running out of options here. */
# error "No 32-bit type, exiting!"
# endif
@ -87,6 +93,7 @@ typedef unsigned long casio_uint32_t;
# endif
/* printf thing for `size_t` */
# if defined(_WIN64)
# define CASIO_PRIuSIZE "l64u"
# define CASIO_PRIxSIZE "l64x"

View File

@ -21,9 +21,10 @@
# include "cdefs.h"
CASIO_BEGIN_NAMESPACE
/* ************************************************************************* */
/* Error codes */
/* ************************************************************************* */
/* ---
* Error codes.
* --- */
/* Warning: whenever you add/remove errors, think about updating
* core/strerror! */
@ -91,7 +92,12 @@ typedef int casio_error_t;
# define casio_error_seq 0x73 /* sequence error. */
# define casio_error_noeq 0x74 /* character does not translate */
/* ---
* Utilities.
* --- */
/* Get a string describing the error. */
CASIO_EXTERN const char* CASIO_EXPORT casio_error_strings[];
CASIO_EXTERN const char* CASIO_EXPORT casio_strerror

View File

@ -23,15 +23,17 @@
# include "version.h"
# include "date.h"
/* ************************************************************************* */
/* Description */
/* ************************************************************************* */
/* ---
* Description.
* --- */
/* This header is about files that are adapted for most filesystems out there,
* such as G1M, G1A, G3E, et caetera.
*
* Here are the managed file types: */
typedef unsigned int casio_filetype_t;
# define casio_filetype_addin 0x0001
# define casio_filetype_mcs 0x0002
# define casio_filetype_eact 0x0004
@ -51,6 +53,7 @@ typedef unsigned int casio_filetype_t;
* pictures for the fx-CP platform. */
typedef unsigned int casio_filefor_t;
# define casio_filefor_none 0x0000
# define casio_filefor_fx 0x0001
# define casio_filefor_cp 0x0002
@ -93,9 +96,11 @@ typedef struct casio_file_s {
char casio_file_intname[12];
casio_version_t casio_file_version;
} casio_file_t;
/* ************************************************************************* */
/* Methods */
/* ************************************************************************* */
/* ---
* Methods.
* --- */
/* Make a file. */
CASIO_EXTERN int CASIO_EXPORT casio_make_picture

View File

@ -23,6 +23,7 @@
typedef casio_uint16_t FONTCHARACTER;
/* A multi-character should resolve as a maximum of 16 characters. */
# define CASIO_FONTCHAR_MULTI_MAX 16
CASIO_EXTERN int CASIO_EXPORT casio_is_fontchar_lead

View File

@ -24,9 +24,11 @@
* to you the different formats surrounding CASIO calculators: open or closed,
* legacy or legacy, obfuscated or not, I hope you'll enjoy them as much
* as I don't! */
/* ************************************************************************* */
/* The CASIOLINK (CAS) format */
/* ************************************************************************* */
/* ---
* The CASIOLINK (CAS) format.
* --- */
/* This is the first file format used by the CASIO community; it was
* more or less a dump of the communications protocol CASIO used until
* the fx-9860G (Graph 85) came out, around 2004/2005.
@ -38,9 +40,11 @@
* You can find its description in the following header: */
# include "format/cas.h"
/* ************************************************************************* */
/* The GraphCard (GRC) format */
/* ************************************************************************* */
/* ---
* The GraphCard (GRC) format.
* --- */
/* The GraphCard is an external micro SD card reader for CASIO calculators,
* made by Util Pocket (not sold anymore).
*
@ -50,9 +54,11 @@
* the end.
*
* See the description of the CAS format above. */
/* ************************************************************************* */
/* The FXI format */
/* ************************************************************************* */
/* ---
* The FXI format.
* --- */
/* fx-Interface, an old but well done proprietary interface by CASIO, has its
* own format: the FXI format. It's an obfuscated format (althrough the
* obfuscation algorithm has been found).
@ -68,9 +74,11 @@
# if 0
# include "format/fxi.h" -- TODO */
# endif
/* ************************************************************************* */
/* The Casemul format */
/* ************************************************************************* */
/* ---
* The Casemul format.
* --- */
/* Casemul is a CASIO emulator for Microsoft Windows. It is an old software
* that has not been updated since 2005. It can import and export other files,
* but save its files in its own format, which use the .cas extension
@ -86,17 +94,21 @@
/* Discover the rest in its dedicated header: */
# include "format/casemul.h"
/* ************************************************************************* */
/* The G1S format */
/* ************************************************************************* */
/* ---
* The G1S format.
* --- */
/* This format is basically a raw dump of the storage memory from the fx-9860G.
* It won't work with fx-CP or fx-CG calculators, as the storage memory
* has changed since. */
# include "format/storage.h"
/* ************************************************************************* */
/* The standard format */
/* ************************************************************************* */
/* ---
* The Standard format.
* --- */
/* Since around 2004/2005, CASIO has adopted a single "superformat"; we call it
* CASIO's standard format, previously known as the G1M format (it doesn't
* really have a *public* name, other than its magics, like 'USBPower' or

View File

@ -53,9 +53,11 @@ CASIO_BEGIN_NAMESPACE
* 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 */
/* ************************************************************************* */
/* ---
* 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.
*
@ -72,9 +74,11 @@ typedef struct casio_cas40_s {
/* The specific bytes are different according to the datatype, but its
* length is fixed. */
/* ************************************************************************* */
/* CASDYN header */
/* ************************************************************************* */
/* ---
* CASDYN header.
* --- */
/* The CASDYN (dynamic size, super header) header appeared later.
* It is known in CaS as the protocol the CFX-9850G uses.
*
@ -131,27 +135,32 @@ typedef struct casio_casdyn_s {
* is read: */
typedef struct casio_cas50_s {
/* types */
/* Types. */
casio_uint8_t casio_cas50_data[2];
/* data length */
/* Data length */
casio_uint16_t casio_cas50_width;
casio_uint16_t casio_cas50_height;
casio_uint8_t casio_cas50_name[8];
/* variable-related data */
/* Variable-related data. */
casio_uint8_t casio_cas50_prefix[8]; /* "Variable" for vars,
* "PROG\x99" "0\xFF\xFF" for progs,
* 0xFFs otherwise */
casio_uint8_t casio_cas50_aux[8]; /* variable: "R\x0A"/"C\x0A",
* editor: password */
/* something else (?) */
/* Something else (?) */
casio_uint8_t casio_cas50_option1[2]; /* 'NL'? "\xFF\xFF" for progs */
casio_uint8_t casio_cas50__reserved[12]; /* other options?
* -> cf. CAT format */
/* end of packet */
/* End of packet. */
casio_uint8_t casio_cas50_checksum;
} casio_cas50_t;
@ -163,31 +172,39 @@ typedef struct casio_cas50_s {
* Anyway, here is the CAS100 header after the CASDYN header is read: */
typedef struct casio_cas100_s {
/* drive?
/* Drive?
* - "INF": system
* - "FR0": segment
* - "MSG": language
* - "MR0": ?
* - "S00": ? */
casio_uint8_t casio_cas100_drive[3];
/* driver number, in ASCII (0x30 + <num>)
/* Driver number, in ASCII (0x30 + <num>)
* "INF" is 1, "FR0" is 1-6, "MSG" is 1, "MR0" is 4, "S00" is 0 */
casio_uint8_t casio_cas100_id;
/* group size (size of each fragment group part to be sent): 0x400, 1024 */
/* Group size (size of each fragment group part to be sent):
* 0x400, 1024 */
casio_uint32_t casio_cas100_size;
/* ExportDrive: 0x80, type? */
casio_uint32_t casio_cas100_type;
/* drive size: 0x20000 bytes */
/* Drive size: 0x20000 bytes */
casio_uint32_t casio_cas100_drive_size;
/* 0xFFs */
casio_uint8_t casio_cas100__unknown[18];
/* checksum */
/* Checksum */
casio_uint8_t casio_cas100_checksum;
} casio_cas100_t;
@ -196,28 +213,35 @@ typedef struct casio_cas100_s {
* source code, once again. */
typedef struct casio_cas100info_s {
/* board identifier? "ZX945" */
/* Board identifier? "ZX945" */
casio_uint8_t casio_cas100info_board[5];
casio_uint8_t casio_cas100info_delim0; /* 0xFF */
/* serial settings? "038400N"
/* Serial settings? "038400N"
* this would mean 38400 bauds, no parity (2 stop bits?) */
casio_uint8_t casio_cas100info_settings[11];
/* ROM version? "1.00" or "1.01" */
casio_uint8_t casio_cas100info_version[4];
/* values? */
/* Values? */
casio_uint32_t casio_cas100info__val1; /* 0xF00 or 0x1000;common: 0x1000 */
casio_uint32_t casio_cas100info__val2; /* 0x400 */
casio_uint32_t casio_cas100info__val3; /* 0x100 */
/* hex value with prefix... what? */
casio_uint8_t casio_cas100info_hex[4]; /* "0x07", litterally,
* or 0x07 followed by three 0xFFs */
casio_uint8_t casio_cas100info_delim1; /* 0xFF */
/* Hex value with prefix... what?
* `hex` is "0x07" literally, or 0x07 followed by three 0xFFs.
* `delim1` is 0xFF. */
casio_uint8_t casio_cas100info_hex[4];
casio_uint8_t casio_cas100info_delim1;
/* Checksum */
/* checksum */
casio_uint8_t casio_cas100info_checksum;
} casio_cas100info_t;
@ -229,6 +253,7 @@ typedef struct casio_cas100info_s {
* Here are the content formats for the two header types: */
CASIO_END_NAMESPACE
# pragma pack()
# include "cas/program.h" /* programs, f-mem */
# include "cas/cell.h" /* lists, matrixes, variables */

View File

@ -20,6 +20,7 @@
# define LIBCASIO_FORMAT_CAS_GMEM_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* You can save some graph function's expression inside a graph memory (G-MEM).
@ -29,10 +30,12 @@ CASIO_BEGIN_NAMESPACE
* It starts with 20 graph entries, which have this format: */
typedef struct casio_cas_gmem_entry_s {
/* function type code */
/* Function type code. */
casio_uint8_t casio_cas_gmem_entry_type;
/* flags */
/* Flags. */
casio_uint8_t casio_cas_gmem_entry_flags;
} casio_cas_gmem_entry_t;
@ -69,5 +72,6 @@ typedef struct casio_cas_gmem_entry_s {
* TODO: find out what these are. */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_CAS_GMEM_H */

View File

@ -20,11 +20,13 @@
# define LIBCASIO_FORMAT_CAS_PICTURE_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* ************************************************************************* */
/* CAS40 specific header bytes */
/* ************************************************************************* */
/* ---
* CAS40 specific header bytes.
* --- */
/* In old CAS headers, the five specific bytes are the following: */
typedef struct casio_cas_spe_screenshot_s {
@ -35,13 +37,16 @@ typedef struct casio_cas_spe_screenshot_s {
/* The specific bytes for a number start with either "RA" or "CA", 'R' or 'C'
* meaning the number is complex or not. */
/* ************************************************************************* */
/* Content */
/* ************************************************************************* */
/* ---
* Content.
* --- */
/* The width and height are given in the CAS50 header/CAS40 specific bytes.
* The picture format is either `casio_pictureformat_4bit_mono` or
* `casio_pictureformat_4bit_color` -- see `libcasio/picture.h`. */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_CAS_PICTURE_H */

View File

@ -20,6 +20,7 @@
# define LIBCASIO_FORMAT_CAS_PROGRAM_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* TODO: describe programs to the newcomer.
@ -43,5 +44,6 @@ typedef struct casio_cas_spe_program_s {
* F-MEM (saves of series of commands) are stored like very small programs. */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_CAS_PROGRAM_H */

View File

@ -21,6 +21,7 @@
# include "../cdefs.h"
# include "../number.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* Casemul files are made of an overall header, a source part and an
@ -28,13 +29,17 @@ CASIO_BEGIN_NAMESPACE
* an internal header, which always has this structure: */
typedef struct casio_casemul_intheader_s {
/* this signature, a set of 4 characters identifying the header type */
/* This signature, a set of 4 characters identifying the header type. */
casio_uint32_t casio_casemul_intheader_signature;
/* version (more or less 0xMMmm, where MM is the major and mm the minor) */
/* Version (more or less 0xMMmm, where MM is the major and
* mm the minor). */
casio_uint32_t casio_casemul_intheader_version;
/* header size */
/* Header size. */
casio_uint32_t casio_casemul_intheader_size;
} casio_casemul_intheader_t;
@ -51,9 +56,11 @@ typedef struct casio_casemul_intheader_s {
* "CASF", then the platform was big endian, otherwise ("ACFS"), the platform
* was little endian (very probable, as Microsoft Windows is mostly used on
* the x86 architecture, which is little endian). */
/* ************************************************************************* */
/* Overall, source and compiled headers */
/* ************************************************************************* */
/* ---
* Overall, source and compiled headers.
* --- */
/* The overall header contains information about the other sections, and the
* current state of the file (whether it contains the compiled part or not).
*
@ -61,18 +68,23 @@ typedef struct casio_casemul_intheader_s {
* simplicity, see the 'problem' with endianness above).
* The expected version is 1.00. */
# define casemul_compiled 0x80 /* if the compiled program is there */
# define casemul_compiled 0x80 /* If the compiled program is there. */
typedef struct casio_casemul_header_s {
/* the flags */
/* The flags. */
casio_uint8_t casio_casemul_header_flags;
/* offset of the sources */
/* Offset of the sources. */
casio_uint32_t casio_casemul_header_source_offset;
/* compiled program offset */
/* Compiled program offset. */
casio_uint32_t casio_casemul_header_compiled_offset;
/* some alignment? */
/* Some alignment? */
casio_uint8_t casio_casemul_header__align[3];
} casio_casemul_header_t;
@ -84,34 +96,44 @@ typedef struct casio_casemul_header_s {
* The expected version is 1.00. */
typedef struct casio_casemul_source_header_s {
/* number of program records in the program block */
/* Number of program records in the program block. */
casio_uint8_t casio_casemul_source_header_programs;
/* number of picture records in the program block */
/* Number of picture records in the program block. */
casio_uint8_t casio_casemul_source_header_pictures;
/* number of matrix records in the program block */
/* Number of matrix records in the program block. */
casio_uint8_t casio_casemul_source_header_matrixes;
/* number of list records in the list block */
/* Number of list records in the list block. */
casio_uint8_t casio_casemul_source_header_lists;
/* program block offset */
/* Program block offset. */
casio_uint32_t casio_casemul_source_header_programs_offset;
/* picture block offset (length of the file before) */
/* Picture block offset (length of the file before). */
casio_uint32_t casio_casemul_source_header_pictures_offset;
/* matrix block offset */
/* Matrix block offset. */
casio_uint32_t casio_casemul_source_header_matrixes_offset;
/* list block offset */
/* List block offset. */
casio_uint32_t casio_casemul_source_header_list_offset;
/* main program ID */
/* Main program ID. */
casio_uint8_t casio_casemul_source_header_program_id;
/* alignment */
/* Alignment. */
casio_uint8_t casio_casemul_source_header__align[3];
} casio_casemul_source_header_t;
@ -123,12 +145,15 @@ typedef struct casio_casemul_source_header_s {
* The expected version is 1.00. */
typedef struct casio_casemul_compiled_header_s {
/* the number of instructions (size of the part) */
/* The number of instructions (size of the part). */
casio_uint32_t casio_casemul_compiled_header_size;
} casio_casemul_compiled_header_t;
/* ************************************************************************* */
/* Record */
/* ************************************************************************* */
/* ---
* Record.
* --- */
/* For each element, there is record, with a header and a subheader. The
* record header cannot easily be expressed as a structure, so here it is, in
* the form of a comment:
@ -145,29 +170,36 @@ typedef struct casio_casemul_compiled_header_s {
*
* Then expect an internal header, part of the subheader, that expresses the
* type of it (expected version for all of them is 1.00). */
/* ************************************************************************* */
/* Program */
/* ************************************************************************* */
/* ---
* Program.
* --- */
/* A program has type "PROG" (RPGO). Its subheader is the following: */
typedef struct casio_casemul_prog_header_s {
/* program length after Casemul encoding */
/* Program length after Casemul encoding. */
casio_uint32_t casio_casemul_prog_header_length;
} casio_casemul_prog_header_t;
/* Casemul makes use of tokens instead of FONTCHARACTERs or Unicode - this
* should be documented in the FONTCHARACTER reference. */
/* ************************************************************************* */
/* Picture */
/* ************************************************************************* */
/* ---
* Picture.
* --- */
/* A picture has type "PICT" (IPTC), and has the following subheader: */
typedef struct casio_casemul_pict_header_s {
/* size */
/* Size. */
casio_uint8_t casio_casemul_pict_header_width;
casio_uint8_t casio_casemul_pict_header_height;
/* ... aaaaand alignment. (you know, unchecked theory?) */
casio_uint8_t casio_casemul_pict_header__align[2];
} casio_casemul_pict_header_t;
@ -178,15 +210,18 @@ typedef struct casio_casemul_pict_header_s {
* Notice that DATAPICTURE_CX and DATAPICTURE_CY are actually macros,
* which means there are always 128x64 pixels (or at least that Casemul
* will only be able to open 128x64 pictures)... */
/* ************************************************************************* */
/* Matrix */
/* ************************************************************************* */
/* ---
* Matrix.
* --- */
/* A matrix has type "MTRX" (TMXR) and its its subheader has the following
* structure: */
typedef struct casio_casemul_mtrx_header_s {
/* number of lines and columns
/* Number of lines and columns,
* actually int-s in the original code... */
casio_uint32_t casio_casemul_mtrx_header_lines;
casio_uint32_t casio_casemul_mtrx_header_columns;
} casio_casemul_mtrx_header_t;
@ -194,14 +229,17 @@ typedef struct casio_casemul_mtrx_header_s {
/* Then it's simply a tab of `lines*columns` `double` numbers,
* ordered by lines (y). They are the real parts, as the numbers in those
* matrixes have got no imaginary parts. */
/* ************************************************************************* */
/* List */
/* ************************************************************************* */
/* ---
* List.
* --- */
/* A list has type "LIST" (ILTS) and has the following subheader structure: */
typedef struct casio_casemul_list_header_s {
/* number of lines
/* Number of lines,
* actually int-s in the original code... */
casio_uint32_t casio_casemul_list_header_lines;
} casio_casemul_list_header_t;

View File

@ -20,6 +20,7 @@
# define LIBCASIO_FORMAT_FXI_H
# include "../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* FXI is obfuscated with a symetrical obfuscation algorithm:
@ -88,5 +89,6 @@ typedef struct casio_fxi_entry_s {
} casio_fxi_entry_t;
CASIO_END_NAMESPACE
# pragma pack()
#endif

View File

@ -21,6 +21,7 @@
# include "../../cdefs.h"
# include "../../number.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* Lists, matrixes and vectors have exactly the same format.
@ -59,5 +60,6 @@ typedef struct casio_mcs_cellsheader_s {
* CASIOWIN 2.00. */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_MCS_CELLS_H */

View File

@ -20,6 +20,7 @@
# define LIBCASIO_FORMAT_MCS_PICTURE_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* Captures start with a simple header: */
@ -40,5 +41,6 @@ typedef struct casio_mcs_captureheader_s {
* and that's all. */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_MCS_PICTURE_H */

View File

@ -20,20 +20,24 @@
# define LIBCASIO_FORMAT_MCS_PROGRAM_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* Programs have a simple header: */
typedef struct casio_mcs_programheader_s {
/* the program password. not encrypted, anything */
/* The program password. not encrypted, anything. */
casio_uint8_t casio_mcs_programheader_password[8];
/* and some alignment. */
/* And some alignment. */
casio_uint8_t casio_mcs_programheader__align[2];
} casio_mcs_programheader_t;
/* Then comes their content, multi-byte FONTCHARACTER encoded. */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_MCS_PROGRAM_H */

View File

@ -26,6 +26,7 @@
* signification in the two).
*
* Known settings are:
*
* [0x13] Angle (0x00: degrees, 0x01: radians, 0x02: gradians);
* [0x14] SHIFT/Alpha status (0x00: both off, 0x01: shift only on,
* 0x04: alpha only on, 0x84: both on);

View File

@ -21,6 +21,7 @@
# include "../../cdefs.h"
# include "../../number.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* Spreadsheets are more complicated than that.
@ -28,10 +29,12 @@ CASIO_BEGIN_NAMESPACE
* For normal ones, there is a header: */
typedef struct casio_mcs_spreadsheet_header_s {
/* has subheader: 0x01 if yes */
/* Has subheader: 0x01 if yes. */
casio_uint8_t casio_mcs_spreadsheet_header_has_subheader;
/* column count (max: 26), on 24 bits and non-aligned */
/* Column count (max: 26), on 24 bits and non-aligned. */
casio_uint32_t casio_mcs_spreadsheet_header_column_count :24;
} casio_mcs_spreadsheet_header_t;
@ -41,13 +44,16 @@ typedef struct casio_mcs_spreadsheet_header_s {
* Here's the subheader: */
typedef struct casio_mcs_spreadsheet_subheader_s {
/* alignment or magic? {0, 0, 0, 0} */
/* Alignment or magic? {0, 0, 0, 0} */
casio_uint8_t casio_mcs_spreadsheet_subheader__align0[4];
/* number of column definitions */
/* Number of column definitions. */
casio_uint32_t casio_mcs_spreadsheet_subheader_defs_size;
/* alignment or magic II? {0, 0, 0, 0} */
/* Alignment or magic II? {0, 0, 0, 0} */
casio_uint8_t casio_mcs_spreadsheet_subheader__align1[4];
} casio_mcs_spreadsheet_subheader_t;
@ -63,5 +69,6 @@ typedef struct casio_mcs_spreadsheet_subheader_s {
* a column quicker. */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_MCS_SPREADSHEET_H */

View File

@ -27,9 +27,11 @@ CASIO_BEGIN_NAMESPACE
* 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 */
/* ************************************************************************* */
/* ---
* 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
@ -85,9 +87,11 @@ typedef struct casio_standard_header_s {
*
* 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 */
/* ************************************************************************* */
/* ---
* 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
@ -204,9 +208,11 @@ typedef struct casio_standard_classpad_subheader_s {
/* 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 */
/* ************************************************************************* */
/* ---
* Standard Picture Header.
* --- */
/* Picture formats (C2P, G3P) have a common picture standard subheader, which
* is the following: */
@ -243,9 +249,11 @@ typedef struct casio_standard_picheader_s {
} casio_standard_picheader_t;
/* Then we have the specific header -- see `libcasio/format/std/picture.h`. */
/* ************************************************************************* */
/* Flavors */
/* ************************************************************************* */
/* ---
* Flavors.
* --- */
/* Where do you want to go next? Pick your poison. */
CASIO_END_NAMESPACE

View File

@ -24,13 +24,16 @@ CASIO_BEGIN_NAMESPACE
/* Add-ins are compiled programs. They only have one standard part,
* These add-ins usually have the `g1a`, `g3a` or `c1a` extension. */
/* ************************************************************************* */
/* Legacy fx systems add-ins (G1A) */
/* ************************************************************************* */
/* ---
* Legacy fx systems add-ins (G1A).
* --- */
/* G1A subheader is the following: */
# define G1A_ICON_WIDTH 30
# define G1A_ICON_HEIGHT 17
typedef struct casio_addin_subheader_s {
/* the internal name, of format "@APPNAME".
* useful for add-ins calling themselves... I guess? */
@ -78,9 +81,11 @@ typedef struct casio_addin_subheader_s {
} casio_addin_subheader_t;
/* Then the G1A file will just contain the add-in code and stop. */
/* ************************************************************************* */
/* Classpad and Prizm add-ins (C1A, G3A) */
/* ************************************************************************* */
/* ---
* Classpad and Prizm add-ins (C1A, G3A).
* --- */
/* The two formats both have the Standard Subheader, then, for the C1A,
* the Classpad-specific subheader, and for the G3A, the Prizm-specific
* subheader.
@ -89,8 +94,10 @@ typedef struct casio_addin_subheader_s {
# define G3A_ICON_WIDTH 92
# define G3A_ICON_HEIGHT 64
typedef struct casio_prizm_addin_subheader_s {
/* selected and unselected icon image */
/* Selected and unselected icon image. */
casio_uint8_t casio_prizm_addin_subheader_selected_icon_image[0x3000];
casio_uint8_t casio_prizm_addin_subheader_unselected_icon_image[0x3000];
} casio_prizm_addin_subheader_t;
@ -99,14 +106,18 @@ typedef struct casio_prizm_addin_subheader_s {
# define C1A_ICON_WIDTH 46
# define C1A_ICON_HEIGHT 30
typedef struct casio_classpad_addin_subheader_s {
/* unknown bytes */
/* Unknown bytes. */
casio_uint8_t casio_classpad_addin_subheader__unknown0[0x2C];
/* this is an approximation (46x30 pixels, packed 1-bit) */
/* This is an approximation (46x30 pixels, packed 1-bit). */
casio_uint8_t casio_classpad_addin_subheader_icon[172];
/* unknown */
/* Unknown. */
casio_uint8_t casio_classpad_addin_subheader__unknown1[0xC54];
} casio_classpad_addin_subheader_t;

View File

@ -20,6 +20,7 @@
# define LIBCASIO_FORMAT_STD_EACT_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* E-Activities are the format CASIO uses for in-calc documents.
@ -124,5 +125,6 @@ typedef struct casio_eact_line_descriptor_s {
* Which means in each node, there can be a content to parse. */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_STD_EACT_H */

View File

@ -20,13 +20,16 @@
# define LIBCASIO_FORMAT_STD_FKEY_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* Function keys are the little boxes at the bottom with text in it, to tell
* you what you're going to access if you press F1-F6. */
/* ************************************************************************* */
/* G1N - Function-keys files for fx calculators */
/* ************************************************************************* */
/* ---
* G1N - Function-keys files for fx calculators.
* --- */
/* In G1Ns, function keys are 19x8 1-bit with fill bits images.
*
* TODO: it is unknown yet how to identify G1N files, as no non-community-made
@ -50,9 +53,11 @@ typedef struct casio_fkey_subheader_s {
/* Then there is a table of 16-bits offsets (iconXXX - icon0), then the icons.
* The first "icon" is in fact the name of the language. */
/* ************************************************************************* */
/* G3L-N - Function-keys files for CG calculators */
/* ************************************************************************* */
/* ---
* G3L-N - Function-keys files for CG calculators.
* --- */
/* G3N (also named G3L-N) have exactly the same structure than G3Ls (see
* `libcasio/format/std/lang.h`), but messages are 64x24 1-bit pictures. */
@ -65,5 +70,6 @@ typedef struct casio_fkey_subheader_s {
* integration in libcasio! */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_STD_FKEY_H */

View File

@ -20,11 +20,13 @@
# define LIBCASIO_FORMAT_STD_LANG_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* ************************************************************************* */
/* G1L - Language files for fx calculators */
/* ************************************************************************* */
/* ---
* G1L - Language files for fx calculators.
* --- */
/* It all starts with a header: */
typedef struct casio_lang_subheader_s {
@ -50,27 +52,34 @@ typedef struct casio_lang_subheader_s {
*
* The messages are null-terminated - once you get the offsets, you get
* them completely. */
/* ************************************************************************* */
/* G3L - Language files for Prizm */
/* ************************************************************************* */
/* ---
* G3L - Language files for the Prizm.
* --- */
/* G3L and G3N start with the StandardHeader and the Standard Subheader,
* then the Prizm-specific subheader. After this, both the G3L and G3N
* have this language header: */
typedef struct casio_prizm_lang_subheader_s {
/* sequence: '4C 59 37 35 35 00 00 00' (LY755 ) */
/* Sequence: '4C 59 37 35 35 00 00 00' (LY755 ) */
casio_uint8_t casio_prizm_lang_subheader_sequence[8];
/* unknown: 0x02 */
/* Unknown: 0x02 */
casio_uint8_t casio_prizm_lang_subheader__unknown;
/* unused byte. */
/* Unused byte. */
casio_uint8_t casio_prizm_lang_subheader__unused0;
/* number of messages ("possibly 0 base indexed") */
/* Number of messages ("possibly 0 base indexed") */
casio_uint32_t casio_prizm_lang_subheader_count;
/* unused bytes */
/* Unused bytes */
casio_uint8_t casio_prizm_lang_subheader__unused1[2];
} casio_prizm_lang_subheader_t;
@ -80,5 +89,6 @@ typedef struct casio_prizm_lang_subheader_s {
* And don't forget the footer (see `libcasio/format/std.h`) */
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_STD_LANG_H */

View File

@ -20,6 +20,7 @@
# define LIBCASIO_FORMAT_STD_MCS_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* MCS is the main filesystem on CASIO calculators. They contain settings,
@ -70,6 +71,7 @@ typedef struct casio_mcs_fileheader_s {
} casio_mcs_fileheader_t;
CASIO_END_NAMESPACE
# pragma pack()
/* Beneath the file header, the file have different structures according to

View File

@ -20,11 +20,13 @@
# define LIBCASIO_FORMAT_STD_PICTURE_H
# include "../../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* ************************************************************************* */
/* G3P: pictures for Prizm */
/* ************************************************************************* */
/* ---
* G3P: pictures for Prizm
* --- */
/* G3P are pictures for fx-CG. They start with a Standard Header, and
* a Standard Picture Header.
*
@ -106,9 +108,11 @@ typedef struct casio_prizm_picture_subheader_s {
* raw, uncompressed data (and is appended to it before deflating/obfuscating).
*
* TODO: footers */
/* ************************************************************************* */
/* C2P: Images for Classpads */
/* ************************************************************************* */
/* ---
* C2P: Images for Classpads.
* --- */
/* C2P are pictures for CASIO Classpad calculators (fx-CP*). They start with
* a Standard Header, followed by a Standard Picture Header.
*
@ -152,5 +156,6 @@ typedef struct casio_classpad_picture_footer_s {
} casio_classpad_picture_footer_s;
CASIO_END_NAMESPACE
# pragma pack()
#endif /* LIBCASIO_FORMAT_STD_PICTURE_H */

View File

@ -20,6 +20,7 @@
# define LIBCASIO_FORMAT_STORAGE_H
# include "../cdefs.h"
# pragma pack(1)
CASIO_BEGIN_NAMESPACE
/* Storage backup files (G1S) contain backups of the storage memory.
@ -31,9 +32,11 @@ CASIO_BEGIN_NAMESPACE
*
* These files are not managed by the calculator directly; however, they
* are managed by FA-124. */
/* ************************************************************************* */
/* Directory list */
/* ************************************************************************* */
/* ---
* Directory list.
* --- */
/* The SMEM (content of the G1S file once 0x270000 bytes were skipped) starts
* with a big entry list. An entry is 32-bytes long: it starts with a common
* part, then with a type-specific part (then unused bytes if the subheader
@ -81,9 +84,11 @@ typedef struct casio_storage_entry_s {
* then there is no parent.
*
* For now, only directories as parents for files have been encountered. */
/* ************************************************************************* */
/* Sectors */
/* ************************************************************************* */
/* ---
* Sectors.
* --- */
/* Sectors represent the physical sectors of the storage memory (space!).
* They are 64 KiB large.
*
@ -103,13 +108,15 @@ typedef struct casio_storage_sector_s {
* not be set as parent nodes :) */
casio_uint32_t casio_storage_sector_logical_sector_number;
} casio_storage_sector_t;
/* ************************************************************************* */
/* Directories */
/* ************************************************************************* */
/* ---
* Directories.
* --- */
/* After the sectors come the directories.
*
* Their spec# include "../cdefs.h"ial nibble is either 0x05 if active or 0x00 if deleted.
* Here is their subheader structure: */
* Their spec# include "../cdefs.h"ial nibble is either 0x05 if active or
* 0x00 if deleted. Here is their subheader structure: */
typedef struct casio_storage_directory_s {
/* the parent type and id */
@ -119,9 +126,11 @@ typedef struct casio_storage_directory_s {
/* the name (FONTCHARACTER-encoded) */
casio_uint16_t casio_storage_directory_name[12];
} casio_storage_directory_t;
/* ************************************************************************* */
/* Files */
/* ************************************************************************* */
/* ---
* Files.
* --- */
/* After the directories come the files (interrupted by fragments - see after).
*
* Their special nibble have the same meaning that for directories.
@ -135,9 +144,11 @@ typedef struct casio_storage_file_s {
/* the name (FONTCHARACTER-encoded) */
casio_uint16_t casio_storage_file_name[12];
} casio_storage_file_t;
/* ************************************************************************* */
/* File fragments */
/* ************************************************************************* */
/* ---
* File fragments.
* --- */
/* After each file entry comes the corresponding fragments entries.
* Fragments are in fact links to the sectors, with some more information.
*

View File

@ -23,7 +23,8 @@
# include <time.h>
CASIO_BEGIN_NAMESPACE
/* forward structure declarations (don't mind) */
/* Forward structure declarations (don't mind). */
struct casio_fs_s;
typedef struct casio_fs_s casio_fs_t;
struct casio_fsfuncs_s;
@ -34,9 +35,11 @@ struct casio_path_s;
typedef struct casio_path_s casio_path_t;
struct casio_stat_s;
typedef struct casio_stat_s casio_stat_t;
/* ************************************************************************* */
/* Filesystem file path */
/* ************************************************************************* */
/* ---
* Filesystem file path.
* --- */
/* We ought to make a file path abstraction, that take into account all of the
* existing file systems, with devices, namespaces, and their character
* encodings.
@ -70,9 +73,11 @@ struct casio_path_s {
const char *casio_path_device;
casio_pathnode_t *casio_path_nodes;
};
/* ************************************************************************* */
/* Filesystem file entry */
/* ************************************************************************* */
/* ---
* Filesystem file entry.
* --- */
/* This structure defines file metadata.
* Here are the flags:
* `CASIO_STAT_FLAG_PERM`: stat permissions are set;
@ -160,32 +165,34 @@ struct casio_stat_s {
* probably disappear afterwards, duplicate the node using
* `casio_duplicate_pathnode`! */
typedef void casio_fs_list_func_t OF((void *casio__cookie,
typedef void CASIO_EXPORT casio_fs_list_func_t OF((void *casio__cookie,
const casio_pathnode_t *casio__node, const casio_stat_t *casio__stat));
/* ************************************************************************* */
/* Filesystem description */
/* ************************************************************************* */
/* ---
* Filesystem description.
* --- */
/* The filesystem is a private structure that represents a file system.
*
* Once all of the operations are done, the user shall close the filesystem.
* This is the callback to free/close custom elements. */
typedef int casio_fs_close_t OF((void *casio__cookie));
typedef int CASIO_EXPORT casio_fs_close_t OF((void *casio__cookie));
/* From here, we will work with paths.
* Instead of having to convert the path every time, we will use native paths
* on the user side; they can be made how you want. */
typedef int casio_fs_makepath_t
typedef int CASIO_EXPORT casio_fs_makepath_t
OF((void *casio__cookie, void **casio__native_path,
casio_path_t *casio__path));
typedef void casio_fs_freepath_t
typedef void CASIO_EXPORT casio_fs_freepath_t
OF((void *casio__cookie, void *casio__native_path));
/* The `casio_fs_stat` callback is used to gather information about
* any element in your filesystem: files, directories, ... */
typedef int casio_fs_stat_t
typedef int CASIO_EXPORT casio_fs_stat_t
OF((void *casio__cookie, void *casio__native_path,
casio_stat_t *casio__stat));
@ -195,35 +202,35 @@ typedef int casio_fs_stat_t
* - `CASIO_STAT_TYPE_LNK`: void *casio__destination_path. */
# if defined(__STDC__) && __STDC__
typedef int casio_fs_make_t(void *casio__cookie,
typedef int CASIO_EXPORT casio_fs_make_t(void *casio__cookie,
void *casio__native_path, const casio_stat_t *casio__stat, ...);
# else
typedef int casio_fs_make_t();
typedef int CASIO_EXPORT casio_fs_make_t();
# endif
/* The `casio_fs_del` callback is used to delete an element of any type
* from your filesystem. */
typedef int casio_fs_del_t
typedef int CASIO_EXPORT casio_fs_del_t
OF((void *casio__cookie, void *casio__native_path));
/* The `casio_fs_move` callback is used to move an element of your filesystem
* to an other location. */
typedef int casio_fs_move_t
typedef int CASIO_EXPORT casio_fs_move_t
OF((void *casio__cookie, void *casio__native_orig,
void *casio__native_dest));
/* The `casio_fs_open` callback is used to make a stream out of an element
* of your filesystem. */
typedef int casio_fs_open_t
typedef int CASIO_EXPORT casio_fs_open_t
OF((void *casio__cookie, void *casio__path, casio_off_t size,
casio_openmode_t casio__mode, casio_stream_t **stream));
/* The `casio_fs_list` callback is used to list files in a directory. */
typedef int casio_fs_list_t
typedef int CASIO_EXPORT casio_fs_list_t
OF((void *casio__cookie, casio_path_t *casio__path,
casio_fs_list_func_t *casio__callback, void *casio__cbcookie));
@ -238,7 +245,7 @@ typedef int casio_fs_list_t
* mount point. This is a mess we need to clean up sometime, for now
* we're only considering this operation for CASIOWIN. */
typedef int casio_fs_optim_t
typedef int CASIO_EXPORT casio_fs_optim_t
OF((void *casio__cookie, const char *device));
/* And here is the structure with all of the functions.
@ -260,9 +267,11 @@ struct casio_fsfuncs_s {
casio_fs_optim_t *casio_fsfuncs_optim;
};
/* ************************************************************************* */
/* Filesystem public functions */
/* ************************************************************************* */
/* ---
* Filesystem public functions.
* --- */
CASIO_BEGIN_DECLS
/* Open a custom filesystem, and close any filesystem. */

View File

@ -80,20 +80,23 @@ typedef struct casio_link_info_s {
/* The user shall confirm or not a link action. */
typedef int casio_link_confirm_t OF((void *casio__cookie));
typedef int CASIO_EXPORT casio_link_confirm_t
OF((void *casio__cookie));
/* This callback is for displaying the progress of an operation (usually
* file/data transfer). It receives the packet ID and the total number of
* packets. For initialization of the display, this callback is called
* with a packet ID superior to the number of packets. */
typedef void casio_link_progress_t OF((void *casio__cookie,
unsigned int casio__id, unsigned int casio__total));
typedef void CASIO_EXPORT casio_link_progress_t
OF((void *casio__cookie, unsigned int casio__id,
unsigned int casio__total));
/* List files. */
typedef void casio_link_list_t OF((void *casio__cookie,
const char *casio__path, const casio_stat_t *casio__stat));
typedef void CASIO_EXPORT casio_link_list_t
OF((void *casio__cookie, const char *casio__path,
const casio_stat_t *casio__stat));
/* ---
* Other structures.
@ -162,20 +165,24 @@ CASIO_EXTERN void CASIO_EXPORT casio_unlock_link
CASIO_EXTERN const casio_link_info_t* CASIO_EXPORT casio_get_link_info
OF((casio_link_t *casio__handle));
/* ************************************************************************* */
/* Run servers. */
/* ************************************************************************* */
/* ---
* Run servers.
* --- */
/* Run a Protocol 7.00 server. */
typedef int casio_seven_server_func_t OF((void *casio__cookie,
casio_link_t *casio__handle));
typedef int CASIO_EXPORT casio_seven_server_func_t
OF((void *casio__cookie, casio_link_t *casio__handle));
CASIO_EXTERN int CASIO_EXPORT casio_seven_serve
OF((casio_link_t *casio__handle,
casio_seven_server_func_t **casio__callbacks, void *casio__cookie));
/* ************************************************************************* */
/* General-purpose link operations */
/* ************************************************************************* */
/* ---
* General-purpose link operations.
* --- */
/* Set the link settings. */
CASIO_EXTERN int CASIO_EXPORT casio_setlink

View File

@ -23,6 +23,7 @@ CASIO_BEGIN_NAMESPACE
CASIO_BEGIN_DECLS
/* Get and set the log level at runtime. */
CASIO_EXTERN void CASIO_EXPORT casio_setlog
OF((const char *casio__level));
CASIO_EXTERN const char* CASIO_EXPORT casio_getlog

View File

@ -22,14 +22,17 @@
# include "mcsfile.h"
CASIO_BEGIN_NAMESPACE
/* forward structure declarations (don't mind) */
/* Forward structure declarations (don't mind). */
struct casio_mcs_s;
typedef struct casio_mcs_s casio_mcs_t;
struct casio_mcsfuncs_s;
typedef struct casio_mcsfuncs_s casio_mcsfuncs_t;
/* ************************************************************************* */
/* Main Filesystem description */
/* ************************************************************************* */
/* ---
* Main Memory filesystem description.
* --- */
/* The Main Memory, also called MCS (for Main Control Structure),
* is a filesystem that represents all the RAM filesystems CASIO has had
* over the years in its calculators.
@ -41,24 +44,24 @@ typedef struct casio_mcsfuncs_s casio_mcsfuncs_t;
*
* Here are the callbacks you should set: */
typedef int casio_mcs_get_t
typedef int CASIO_EXPORT casio_mcs_get_t
OF((void *casio__cookie, casio_mcsfile_t **casio__mcsfile,
casio_mcshead_t *casio__mcshead));
typedef int casio_mcs_put_t
typedef int CASIO_EXPORT casio_mcs_put_t
OF((void *casio__cookie, casio_mcsfile_t *casio__mcsfile));
typedef int casio_mcs_delete_t
typedef int CASIO_EXPORT casio_mcs_delete_t
OF((void *casio__cookie, casio_mcshead_t *casio__mcshead));
typedef void casio_mcslist_t
typedef void CASIO_EXPORT casio_mcslist_t
OF((void *casio__cookie, const casio_mcshead_t *casio__mcshead));
typedef int casio_mcs_list_t
typedef int CASIO_EXPORT casio_mcs_list_t
OF((void *casio__cookie, casio_mcslist_t *casio__mcslist,
void *casio__mcslist_cookie));
typedef int casio_mcs_close_t
typedef int CASIO_EXPORT casio_mcs_close_t
OF((void *casio__cookie));
struct casio_mcsfuncs_s {
@ -68,9 +71,11 @@ struct casio_mcsfuncs_s {
casio_mcs_list_t *casio_mcsfuncs_list;
casio_mcs_close_t *casio_mcsfuncs_close;
};
/* ************************************************************************* */
/* Main Filesystem public functions */
/* ************************************************************************* */
/* ---
* Main Memory filesystem public functions.
* --- */
CASIO_BEGIN_DECLS
/* Open and close. */

View File

@ -37,9 +37,11 @@ CASIO_BEGIN_NAMESPACE
*
* As there are few formats, it should be possible to manage them all
* in libcasio. */
/* ************************************************************************* */
/* Main memory file types */
/* ************************************************************************* */
/* ---
* Main Memory file types.
* --- */
/* Here are all the file types that are managed by libcasio. */
typedef unsigned long casio_mcsfile_type_t;
@ -105,7 +107,8 @@ typedef unsigned long casio_mcstype_t;
# define casio_mcstype_end 0x00000400
/* Macros to check if the type uses the ID, and to interact with it */
/* Macros to check if the type uses the ID, and to interact with it. */
# define casio_mcshead_uses_id(CASIO__H) (((CASIO__H)->casio_mcshead_type & (\
casio_mcstype_list | casio_mcstype_mat | casio_mcstype_vct | \
casio_mcstype_pict | casio_mcstype_capt | casio_mcstype_string) || \
@ -113,9 +116,11 @@ typedef unsigned long casio_mcstype_t;
(CASIO__H)->casio_mcshead_count == 1)))
# define casio_get_id_major(CASIO__I) ((CASIO__I) >> 6)
# define casio_get_id_minor(CASIO__I) ((CASIO__I) & 0x3F)
/* ************************************************************************* */
/* Main memory flags and platforms */
/* ************************************************************************* */
/* ---
* Main Memory flags and platforms.
* --- */
/* Main memory files in libcasio have various options.
* Here are the core flags: */
@ -141,13 +146,16 @@ typedef unsigned int casio_mcsinfo_t;
# define casio_mcsfor_cas50 0x04000000 /* legacy CAS50 header */
# define casio_mcsfor_cas100 0x08000000 /* legacy CAS100 header */
/* Aliases */
/* Aliases. */
# define casio_mcsfor_cas casio_mcsfor_cas40
# define casio_mcsfor_caspro casio_mcsfor_cas50
# define casio_mcsfor_graph100 casio_mcsfor_cas100
/* ************************************************************************* */
/* MCS cell */
/* ************************************************************************* */
/* ---
* MCS Cell.
* --- */
/* Numbers in various MCS file formats (lists, matrixes, variables,
* spreadsheets) have a real part (BCD encoded), an imaginary part
* (BCD encoded) and flags. Here is the structure representing this.
@ -163,9 +171,11 @@ typedef struct casio_mcscell_s {
casio_bcd_t casio_mcscell_real;
casio_bcd_t casio_mcscell_imgn;
} casio_mcscell_t;
/* ************************************************************************* */
/* Main memory file head */
/* ************************************************************************* */
/* ---
* Main Memory file head.
* --- */
/* Filenames and directory names are not the only things which characterize
* MCS files; that's why a separate structure representing the meta information
* about MCS files are preferable. This head structure is also used to
@ -208,9 +218,11 @@ typedef struct casio_mcshead_s {
char casio_mcshead_cas_app[4];
char casio_mcshead_datatype[3];
} casio_mcshead_t;
/* ************************************************************************* */
/* Main memory file */
/* ************************************************************************* */
/* ---
* Main Memory file.
* --- */
/* Here is the file data. Its content depends on what's in the head. */
typedef struct casio_mcsfile_s {
@ -239,10 +251,13 @@ typedef struct casio_mcsfile_s {
(F)->casio_mcsfile_head.casio_mcshead_password[0]
# define casio_remove_password(F) \
(F)->casio_mcsfile_head.casio_mcshead_password[0] = 0
/* ************************************************************************* */
/* Utilities */
/* ************************************************************************* */
/* ---
* Utilities.
* --- */
CASIO_BEGIN_DECLS
/* Make a main memory file, prepare it, and free it. */
CASIO_EXTERN int CASIO_EXPORT casio_make_mcsfile

View File

@ -39,9 +39,10 @@ CASIO_BEGIN_NAMESPACE
# define CASIO_BCD_GOODBUFSIZE \
(2 + CASIO_BCD_MANTISSA_SIZE + 4 + 2 + 1)
/* ************************************************************************* */
/* Main type */
/* ************************************************************************* */
/* ---
* Main type.
* --- */
/* libcasio type definition.
* This is the "unzipped" BCD format. There are several, this is the one
* libcasio will always convert to.
@ -73,9 +74,10 @@ typedef struct casio_bcd_s {
char casio_bcd_mant[CASIO_BCD_MANTISSA_SIZE];
} casio_bcd_t;
/* ************************************************************************* */
/* Raw formats */
/* ************************************************************************* */
/* ---
* Raw formats.
* --- */
/* CAS BCD -- the old BCD format.
*
* First two nibbles are the integer part, the fourteen that follow are
@ -113,9 +115,10 @@ typedef struct casio_mcsbcd_s {
unsigned char casio_mcsbcd__align[3];
} casio_mcsbcd_t;
/* ************************************************************************* */
/* Conversion utilities */
/* ************************************************************************* */
/* ---
* Conversion utilities.
* --- */
CASIO_BEGIN_DECLS
/* From and to MCS BCD. */

View File

@ -66,9 +66,11 @@ typedef casio_uint32_t casio_pixel_t;
* formats, as it might change! */
typedef unsigned int casio_pictureformat_t;
/* ************************************************************************* */
/* Monochrome pictures with fill bits */
/* ************************************************************************* */
/* ---
* Monochrome pictures with fill bits.
* --- */
/* In this format, each bit represents a pixel (so one byte contains eight
* pixels). If the width is not divisible by eight, then the last bits of the
* last byte of the line are unused (fill bits), and the next line starts at
@ -83,9 +85,11 @@ typedef unsigned int casio_pictureformat_t;
/* To calculate the size, it's simple: just calculate the number of bytes
* a line occupies, then multiply it by the number of lines. */
/* ************************************************************************* */
/* Packed monochrome pictures */
/* ************************************************************************* */
/* ---
* Packed monochrome pictures.
* --- */
/* Packed monochrome pictures is basically the same than the previous format,
* except there are no fill bits: if a picture width is 6 pixels, then the
* second line will start at the seventh bit of the first byte (where it would
@ -99,9 +103,11 @@ typedef unsigned int casio_pictureformat_t;
/* To calculate the size, find out the number of occupied bits, divide by
* eight to get the bytes, and make sure to keep an extra byte if there are
* left bits. */
/* ************************************************************************* */
/* Old monochrome format */
/* ************************************************************************* */
/* ---
* Old monochrome format.
* --- */
/* The old monochrome format used by CASIO is basically a normal monochrome
* format (the width is usually 96 or 128, so no need for fill bits), except
* that it starts with the last byte (where the bits are in left to right
@ -111,9 +117,11 @@ typedef unsigned int casio_pictureformat_t;
/* The size is the same as for normal 1-bit monochrome pictures, only the
* byte order changes. */
/* ************************************************************************* */
/* Dual monochrome format */
/* ************************************************************************* */
/* ---
* Dual monochrome format.
* --- */
/* This is the format used for the Prizm's projector mode. It is composed of
* two monochrome pictures (with sizes divisible by eight).
* It is basically gray pictures, with white, light gray, dark gray and
@ -122,9 +130,11 @@ typedef unsigned int casio_pictureformat_t;
# define casio_pictureformat_2bit_dual 0x0200
/* To calculate the size, well, we just have two monochrome screens. */
/* ************************************************************************* */
/* 4-bit RGB_ format */
/* ************************************************************************* */
/* ---
* 4-bit RGB_ format.
* --- */
/* This is a 4 bit per pixel format. There is no need for fill nibbles.
* Each nibble (group of 4 bits) is made of the following:
* - one bit for red (OR by 0xFF0000);
@ -136,9 +146,11 @@ typedef unsigned int casio_pictureformat_t;
# define casio_pictureformat_4bit_rgb 0x0400
/* Calculating the size is trivial: just divide the number of pixels by two. */
/* ************************************************************************* */
/* 4-bit code format */
/* ************************************************************************* */
/* ---
* 4-bit code format.
* --- */
/* In this encoding, each nibble for a pixel represents one of these colors: */
# define casio_color_black 0x0 /* 0x000000 */
@ -155,9 +167,11 @@ typedef unsigned int casio_pictureformat_t;
# define casio_pictureformat_4bit_code 0x0410
/* The size is calculated the same way as previously. */
/* ************************************************************************* */
/* Quad-monochrome VRAM formats */
/* ************************************************************************* */
/* ---
* Quad-monochrome VRAM formats.
* --- */
/* This format is used by old CASIO models. It is made of four monochrome
* pictures (no need for fill bits), where the palettes are:
* - for the `color` variant: [orange, green, blue, white (bg)]
@ -167,9 +181,11 @@ typedef unsigned int casio_pictureformat_t;
# define casio_pictureformat_4bit_mono 0x0421
/* To get the size, just multiply the size of a VRAM by four. */
/* ************************************************************************* */
/* Casemul format */
/* ************************************************************************* */
/* ---
* Casemul format.
* --- */
/* This format is used by Casemul.
* It is basically arbitrary color codes, where, for example, 1 is orange.
* You can check the full color codes in `src/picture.c`. */
@ -177,9 +193,11 @@ typedef unsigned int casio_pictureformat_t;
# define casio_pictureformat_casemul 0x0800
/* Each pixel takes one byte. */
/* ************************************************************************* */
/* 16-bit R5G6B5 format */
/* ************************************************************************* */
/* ---
* 16-bit R5G6B5 format.
* --- */
/* This is the format of the Prizm's VRAM. Each pixel is two bytes long,
* the first five bits represent the high five (clap!) bits of the red part,
* the next six bits represent the high six bits of the green part,
@ -189,9 +207,11 @@ typedef unsigned int casio_pictureformat_t;
# define casio_pictureformat_16bit 0x1000
/* Two bytes per pixel. */
/* ************************************************************************* */
/* Utilities */
/* ************************************************************************* */
/* ---
* Utilities.
* --- */
/* Here are the functions to decode/encode pictures using this format: */
CASIO_BEGIN_DECLS

View File

@ -28,9 +28,11 @@
/* In these protocols, there are two types of packets: one-byte packets,
* and multi-byte packets (headers, headers data, data).
* Multi-byte packets are managed elsewhere. */
/* ************************************************************************* */
/* Checks */
/* ************************************************************************* */
/* ---
* Checks.
* --- */
/* At the beginning of the communication, the active side sends one of two
* possible bytes: 0x15 if the communication is supposed to be interactive,
* 0x16 if not. */
@ -41,9 +43,11 @@
/* Then the passive side is supposed to send an initial packet confirmation: */
# define casio_legacy_start_ack 0x13
/* ************************************************************************* */
/* Main communication */
/* ************************************************************************* */
/* ---
* Main communication.
* --- */
/* The active side starts by sending a header (starting with 0x3A, ':').
* The passive side then answers with either an ACK (0x06), or
* an overwrite error (0x21) if the file already exists.

View File

@ -23,9 +23,10 @@
# include "typz.h"
CASIO_BEGIN_NAMESPACE
/* ************************************************************************* */
/* Packets */
/* ************************************************************************* */
/* ---
* Packets.
* --- */
/* Protocol 7.00 (the latest proprietary protocol from CASIO) is a protocol
* using several-bytes packets. Every packet, with one exception we'll detail
* later, contains a type, a subtype, an optional payload, and a checksum.
@ -86,9 +87,11 @@ typedef unsigned int casio_seven_term_t;
* for some types, subheaders. libcasio translates this into a VRAM and a
* picture format, which you can see in the Protocol 7.00 packet
* representation. */
/* ************************************************************************* */
/* Screenstreaming */
/* ************************************************************************* */
/* ---
* Screenstreaming.
* --- */
/* Screenstreaming packet flow is totally different from the normal packet
* flow: it's just the calculator sending its screen repeateadly, not
* expecting any answer from the 'passive' side. It is only available when
@ -100,9 +103,11 @@ typedef unsigned int casio_seven_term_t;
* - "TYP01" is the basic monochrome capture (1-bit, 128x64);
* - "TYPZ1"/"TYPZ2" is the extended capture (see
* `libcasio/protocol/typz.h`). */
/* ************************************************************************* */
/* Command payload */
/* ************************************************************************* */
/* ---
* Command payload.
* --- */
/* The command has a payload which contain, even in the cases where they are
* not useful, the overwrite status (OW), the MCS raw data type (DT),
* the file size (FS), and the six arguments (of variable length,
@ -142,9 +147,11 @@ typedef unsigned int casio_seven_ow_t;
* 6 | ??? (unused everywhere) |
*
* Whether arguments are used or not depend on the command. */
/* ************************************************************************* */
/* Protocol 7.00 limits */
/* ************************************************************************* */
/* ---
* Protocol 7.00 limits.
* --- */
/* The Protocol 7.00 packet representation includes all the data
* you could have in a packet. First, here are the buffer sizes: */
@ -165,10 +172,13 @@ typedef unsigned int casio_seven_ow_t;
* although some functions such as `casio_getscreen` do decode it to a 32-bit
* pixel matrix (easier for the user, and extensible).
* Check `libcasio/picture.h` for picture format descriptions and utilities. */
/* ************************************************************************* */
/* Protocol 7.00 packet receiving and sending utilities */
/* ************************************************************************* */
/* ---
* Protocol 7.00 packet receiving and sending utilities.
* --- */
CASIO_BEGIN_DECLS
/* This is the main function to receive a packet.
* It manages checksum errors, and timeouts; the only thing you should care
* about is the returned error.
@ -273,11 +283,15 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmd_data
CASIO_END_DECLS
CASIO_END_NAMESPACE
# include <libcasio/protocol/seven/commands.h>
/* ************************************************************************* */
/* Protocol 7.00 environment */
/* ************************************************************************* */
/* ---
* Protocol 7.00 environment.
* --- */
CASIO_BEGIN_NAMESPACE
/* A Protocol 7.00 environment is the type of calculator there is on the
* other side. Environment identification is required for a more precise
* error guessing. */
@ -297,9 +311,11 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_command_is_supported
OF((const casio_seven_env_t *casio__env, unsigned int casio__code));
CASIO_END_DECLS
/* ************************************************************************* */
/* Protocol 7.00 packet representation */
/* ************************************************************************* */
/* ---
* Protocol 7.00 packet representation.
* --- */
/* This representation contains all the possible fields, and only some of them
* are used depending on the packet type/code. */
@ -341,9 +357,11 @@ typedef struct casio_seven_packet_s {
} casio_seven_packet_t;
/* To extract it from the handle, use the extractors in `libcasio/link.h`. */
/* ************************************************************************* */
/* Packet flows */
/* ************************************************************************* */
/* ---
* Packet flows.
* --- */
/* Once the communication is initialized (`casio_init_link` with the
* `CASIO_LINKFLAG_ACTIVE | CASIO_LINKFLAG_CHECK` flags takes care of that),
* Protocol 7.00 is basically a set of packet flows.
@ -367,10 +385,13 @@ typedef struct casio_seven_packet_s {
* If you have finished doing what you wanted to do and the communication is
* still active, send an END packet, to which the other calculator should
* respond with an ACK. */
/* ************************************************************************* */
/* Protocol 7.00 packet flow utilities */
/* ************************************************************************* */
/* ---
* Protocol 7.00 packet flow utilities.
* --- */
CASIO_BEGIN_DECLS
/* Start and end the communication.
* Is used by the link opening and closing functions;
* you shouldn't use them unless you know what you're doing
@ -426,9 +447,11 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_open_data_stream
OF((casio_stream_t **casio__stream,
casio_link_t *casio__link, casio_off_t casio__size,
casio_link_progress_t *casio__disp, void *casio__dcookie));
/* ************************************************************************* */
/* Protocol 7.00 high-level abstractions */
/* ************************************************************************* */
/* ---
* Protocol 7.00 high-level abstractions.
* --- */
/* Make the MCS interface. */
CASIO_EXTERN int CASIO_EXPORT casio_open_seven_mcs

View File

@ -24,75 +24,94 @@ CASIO_BEGIN_NAMESPACE
CASIO_BEGIN_DECLS
/* Utility for MCS commands */
CASIO_EXTERN int CASIO_EXPORT casio_seven_send_typical_mcs_command
OF((casio_link_t *casio__handle,
int casio__code, casio_mcshead_t *casio__head,
casio_mcsfile_t *casio__mcsfile, int casio__ow));
/* ************************************************************************* */
/* Basic commands */
/* ************************************************************************* */
/* Get the platform information */
/* ---
* Basic commands.
* --- */
/* Get the platform information. */
# define casio_seven_cmdsys_getinfo 0x01
# define casio_seven_send_cmdsys_getinfo(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x01)
/* Set the link settings */
/* Set the link settings. */
# define casio_seven_cmdsys_setlink 0x02
CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmdsys_setlink
OF((casio_link_t *casio__handle,
int casio__baudrate, int casio__parity, int casio__stopbits));
/* ************************************************************************* */
/* Backup commands */
/* ************************************************************************* */
/* ---
* Backup commands.
* --- */
/* Backup the RAM */
# define casio_seven_cmdbak_reqram 0x2F
# define casio_seven_send_cmdbak_reqram(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x2F)
/* Send the RAM */
# define casio_seven_cmdbak_putram 0x30
# define casio_seven_send_cmdbak_putram(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x30)
/* Backup the ROM */
# define casio_seven_cmdbak_reqrom 0x4F
# define casio_seven_send_cmdbak_reqrom(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x4F)
/* Send the ROM */
# define casio_seven_cmdbak_putrom 0x50
# define casio_seven_send_cmdbak_putrom(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x50)
/* Backup the CASIOWIN entry */
# define casio_seven_cmdbak_reqcwe 0x52
# define casio_seven_send_cmdbak_reqcwe(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x52)
/* Send the CASIOWIN entry */
# define casio_seven_cmdbak_putcwe 0x53
# define casio_seven_send_cmdbak_putcwe(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x53)
/* Backup the bootcode */
# define casio_seven_cmdbak_reqboot 0x54
# define casio_seven_send_cmdbak_reqboot(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x54)
/* Send the bootcode */
# define casio_seven_cmdbak_putboot 0x55
# define casio_seven_send_cmdbak_putboot(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x55)
/* ************************************************************************* */
/* Main memory commands */
/* ************************************************************************* */
/* ---
* Main memory commands.
* --- */
/* Request a file */
# define casio_seven_cmdmcs_reqfile 0x24
# define casio_seven_send_cmdmcs_reqfile(CASIO__HANDLE, CASIO__HEAD) \
casio_seven_send_typical_mcs_command(CASIO__HANDLE, 0x24, \
CASIO__HEAD, 0, 0)
/* Send a file */
# define casio_seven_cmdmcs_sendfile 0x25
# define casio_seven_send_cmdmcs_sendfile(CASIO__HANDLE, CASIO__OW, \
CASIO__FILE) \
@ -100,42 +119,52 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmdsys_setlink
(CASIO__FILE)->casio_mcsfile_head, CASIO__OW)
/* Delete a file */
# define casio_seven_cmdmcs_delfile 0x26
# define casio_seven_send_cmdmcs_delfile(CASIO__HANDLE, CASIO__HEAD) \
casio_seven_send_typical_mcs_command(CASIO__HANDLE, 0x26, \
(CASIO__HEAD), NULL, 0)
/* Request all file information */
# define casio_seven_cmdmcs_reqallinfo 0x2D
# define casio_seven_send_cmdmcs_reqallinfo(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x2D)
/* Send one file's information */
# define casio_seven_cmdmcs_fileinfo 0x2E
/* Send a setup entry */
# define casio_seven_cmdmcs_putsetup 0x32
/* Request all setup entries. */
# define casio_seven_cmdmcs_reqallsetup 0x33
# define casio_seven_send_cmdmcs_reqallsetup(CASIO__HANDLE) \
casio_seven_send_cmd(CASIO__HANDLE, 0x33)
/* ************************************************************************* */
/* Storage commands */
/* ************************************************************************* */
/* ---
* Storage commands.
* --- */
/* Make a directory */
# define casio_seven_cmdfls_mkdir 0x40
# define casio_seven_send_cmdfls_mkdir(CASIO__HANDLE, CASIO__DIR, CASIO__DEV) \
casio_seven_send_cmd_data(CASIO__HANDLE, 0x40, 0, 0, 0, \
CASIO__DIR, NULL, NULL, NULL, CASIO__DEV, NULL)
/* Delete a directory */
# define casio_seven_cmdfls_rmdir 0x41
# define casio_seven_send_cmdfls_rmdir(CASIO__HANDLE, CASIO__DIR, CASIO__DEV) \
casio_seven_send_cmd_data(CASIO__HANDLE, 0x41, 0, 0, 0, \
CASIO__DIR, NULL, NULL, NULL, CASIO__DEV, NULL)
/* Rename (move) a directory */
# define casio_seven_cmdfls_mvdir 0x42
# define casio_seven_send_cmdfls_mvdir(CASIO__HANDLE, CASIO__DIR, \
CASIO__NEWDIR, CASIO__DEV) \
@ -143,12 +172,14 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmdsys_setlink
CASIO__DIR, CASIO__NEWDIR, NULL, NULL, CASIO__DEV, NULL)
/* Change working directory */
# define casio_seven_cmdfls_cwd 0x43
# define casio_seven_send_cmdfls_cwd(CASIO__HANDLE, CASIO__DIR, CASIO__DEV) \
casio_seven_send_cmd_data(CASIO__HANDLE, 0x43, 0, 0, 0, \
CASIO__DIR, NULL, NULL, NULL, CASIO__DEV, NULL)
/* Request a file */
# define casio_seven_cmdfls_reqfile 0x44
# define casio_seven_send_cmdfls_reqfile(CASIO__HANDLE, CASIO__DIR, \
CASIO__FILE, CASIO__DEV) \
@ -156,6 +187,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmdsys_setlink
CASIO__DIR, CASIO__FILE, NULL, NULL, CASIO__DEV, NULL)
/* Send a file */
# define casio_seven_cmdfls_sendfile 0x45
# define casio_seven_send_cmdfls_sendfile(CASIO__HANDLE, CASIO__OW, \
CASIO__SIZE, CASIO__DIR, CASIO__FILE, CASIO__DEV) \
@ -163,6 +195,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmdsys_setlink
CASIO__DIR, CASIO__FILE, NULL, NULL, CASIO__DEV, NULL)
/* Delete a file */
# define casio_seven_cmdfls_delfile 0x46
# define casio_seven_send_cmdfls_delfile(CASIO__HANDLE, CASIO__DIR, \
CASIO__FILE, CASIO__DEV) \
@ -170,6 +203,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmdsys_setlink
CASIO__DIR, CASIO__FILE, NULL, NULL, CASIO__DEV, NULL)
/* Rename a file */
# define casio_seven_cmdfls_renamefile 0x47
# define casio_seven_send_cmdfls_renamefile(CASIO__HANDLE, CASIO__DIR, \
CASIO__NEWDIR, CASIO__DEV) \
@ -177,6 +211,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmdsys_setlink
CASIO__DIR, CASIO__NEWDIR, NULL, NULL, CASIO__DEV, NULL)
/* Copy a file */
# define casio_seven_cmdfls_copyfile 0x48
# define casio_seven_send_cmdfls_copyfile(CASIO__HANDLE, CASIO__DIR, \
CASIO__FILE, CASIO__NEWDIR, CASIO__NEWFILE, CASIO__DEV) \
@ -185,35 +220,43 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmdsys_setlink
CASIO__DEV, NULL)
/* Reset a storage device */
# define casio_seven_cmdfls_reset 0x4A
# define casio_seven_send_cmdfls_reset(CASIO__HANDLE, CASIO__DEV) \
casio_seven_send_cmd_data(CASIO__HANDLE, 0x4A, 0, 0, 0, \
NULL, NULL, NULL, NULL, CASIO__DEV, NULL)
/* Request the capacity */
# define casio_seven_cmdfls_reqcapacity 0x4B
# define casio_seven_send_cmdfls_reqcapacity(CASIO__HANDLE, CASIO__DEV) \
casio_seven_send_cmd_data(CASIO__HANDLE, 0x4B, 0, 0, 0, \
NULL, NULL, NULL, NULL, CASIO__DEV, NULL)
/* Request all file information */
# define casio_seven_cmdfls_reqallinfo 0x4D
# define casio_seven_send_cmdfls_reqallinfo(CASIO__HANDLE, CASIO__DEV) \
casio_seven_send_cmd_data(CASIO__HANDLE, 0x4D, 0, 0, 0, \
NULL, NULL, NULL, NULL, CASIO__DEV, NULL)
/* Send one file's information */
# define casio_seven_cmdfls_fileinfo 0x4E
/* Optimize a storage device */
# define casio_seven_cmdfls_opt 0x51
# define casio_seven_send_cmdfls_opt(CASIO__HANDLE, CASIO__DEV) \
casio_seven_send_cmd_data(CASIO__HANDLE, 0x51, 0, 0, 0, \
NULL, NULL, NULL, NULL, CASIO__DEV, NULL)
/* ************************************************************************* */
/* OS Update commands */
/* ************************************************************************* */
/* ---
* OS Update commands.
* --- */
/* Upload and run */
# define casio_seven_cmdosu_upandrun 0x56
CASIO_EXTERN int CASIO_EXPORT casio_seven_send_cmdosu_upandrun
OF((casio_link_t *casio__handle,

View File

@ -19,30 +19,39 @@
#ifndef LIBCASIO_PROTOCOL_TYPZ_H
# define LIBCASIO_PROTOCOL_TYPZ_H
# include "../cdefs.h"
CASIO_BEGIN_NAMESPACE
/* In both Protocol 7.00 and extended SCSI protocols, recent CASIO
* calculators (Prizm) use a TYPZ subheader to give details about the
* capture they're sending. It's name is this because the five-letter ID
* is "TYPZ1" or "TYPZ2". The subheader is the following: */
* is "TYPZ1" or "TYPZ2". The two subheaders vary in the size of the
* packet size field: for TYPZ1, it occupies 6 characters, and for TYPZ2, it
* occupies 8 characters.
*
* Encoding algorithms are the following:
* - RC2: 16-bit mode;
* - RC3: 3-bit mode (1 nibble per pixel, red-green-blue-trash);
* - RM2: 2-bit mode?
*
* Once the SIZE field (of 6 or 8 characters depending on the type) is
* made of the following: */
typedef struct casio_typz_s {
/* ASCII-hex size */
unsigned char casio_typz_size[6];
/* Dimensions. */
/* dimensions */
unsigned char casio_typz_height[4];
unsigned char casio_typz_width[4];
/* one: we are number one but it is in ascii (always "1") */
/* One: we are number one but it is in ascii (always "1") */
unsigned char casio_typz_one;
/* encoding algorithm:
* - RC2: 16-bit mode;
* - RC3: 3-bit mode (1 nib./pxl, red-green-blue-trash)
* - RM2: 2-bit mode? */
/* Encoding algorithm. */
unsigned char casio_typz_enc[3];
} casio_typz_t;
CASIO_END_NAMESPACE
#endif /* LIBCASIO_PROTOCOL_TYPZ_H */

View File

@ -21,9 +21,6 @@
# include "cdefs.h"
CASIO_BEGIN_NAMESPACE
/* ************************************************************************* */
/* Description */
/* ************************************************************************* */
/* The real setup from the calculator is either a group of 100/200 byte
* register, or a string-byte map (e.g. "Axes" -> 0x01).
* This structure reduces this big bulky thing to a single usable structure.
@ -102,9 +99,11 @@ typedef struct casio_setup_s {
unsigned int casio_setup_mflags;
unsigned char casio_setup_vals[casio_setup_nvals];
} casio_setup_t;
/* ************************************************************************* */
/* Methods */
/* ************************************************************************* */
/* ---
* Utilities.
* --- */
CASIO_BEGIN_DECLS
/* Initialize the structure. */

View File

@ -111,19 +111,23 @@ typedef int casio_stream_scsi_t
/* Here is the callbacks structure: */
struct casio_streamfuncs_s {
/* main callbacks */
/* Main callbacks. */
casio_stream_close_t *casio_streamfuncs_close;
casio_stream_settm_t *casio_streamfuncs_settm;
/* read & write callbacks */
/* Read & Write callbacks. */
casio_stream_read_t *casio_streamfuncs_read;
casio_stream_write_t *casio_streamfuncs_write;
casio_stream_seek_t *casio_streamfuncs_seek;
/* serial callbacks */
/* Serial callbacks. */
casio_stream_setattrs_t *casio_streamfuncs_setattrs;
/* SCSI callbacks */
/* SCSI callbacks. */
casio_stream_scsi_t *casio_streamfuncs_scsi;
};
@ -252,41 +256,45 @@ struct casio_timeouts_s {
* to implement an SCSI interface into libcasio streams.
*
* This is libcasio's SCSI request structure, inspired from Linux's
* `sg_io_hdr_t` structure, except this structure is cross-platform.
* Here is the different values for the data direction: */
* `sg_io_hdr_t` structure, except this structure tries to be cross-platform
* and is just there to fulfill the library's needs.
*
* Here is the different values for the data direction:
*
* `NONE`: no content.
* `TO_DEV`: outgoing data.
* `FROM_DEV`: incoming data. */
# define CASIO_SCSI_DXFER_NONE -1 /* no content */
# define CASIO_SCSI_DXFER_TO_DEV -2 /* outgoing */
# define CASIO_SCSI_DXFER_FROM_DEV -3 /* incoming */
# define CASIO_SCSI_DIREC_NONE (-1)
# define CASIO_SCSI_DIREC_TO_DEV (-2)
# define CASIO_SCSI_DIREC_FROM_DEV (-3)
/* And here is the request structure: */
/* And here is the request structure:
*
* `cmd` is the raw command buffer (of 6, 10, 12 or 16 bytes).
* `cmd_len` is the command length (6, 10, 12 or 16).
* `direction` is the data transfer direction.
* `data` is the data to transfer (send or receive buffer).
* `data_len` is the data length.
* `status` is the status byte returned by the device. */
struct casio_scsi_s {
/* command description */
int casio_scsi_type;
int casio_scsi_direction;
unsigned int casio_scsi_byte_transfer_length;
unsigned long casio_scsi_logical_block;
unsigned long casio_scsi_allocation_length;
unsigned char casio_scsi_cbp[4];
unsigned char casio_scsi_misc;
/* raw data */
void *casio_scsi_cmd;
unsigned int casio_scsi_cmd_len;
unsigned int casio_scsi_data_len;
unsigned int casio_scsi_sense_len;
unsigned char casio_scsi_cmd[16];
unsigned char *casio_scsi_data;
unsigned char *casio_scsi_sense;
/* TODO: output thingies? */
int casio_scsi_direction;
void *casio_scsi_data;
int casio_scsi_data_len;
int casio_scsi_status;
};
/* It will be sent to your `scsi_request` callback. */
/* ************************************************************************* */
/* Public stream functions */
/* ************************************************************************* */
/* It will be sent to the `scsi` callback of the stream. */
/* ---
* Public stream functions.
* --- */
CASIO_BEGIN_DECLS
/* Default stream serial settings utilities. */
CASIO_EXTERN int CASIO_EXPORT casio_make_attrs
@ -294,8 +302,8 @@ CASIO_EXTERN int CASIO_EXPORT casio_make_attrs
/* List serial devices (platform agnostic). */
typedef void casio_list_com_t OF((void *casio__cookie,
const char *casio__str));
typedef void CASIO_EXPORT casio_list_com_t
OF((void *casio__cookie, const char *casio__str));
CASIO_EXTERN int CASIO_EXPORT casio_comlist
OF((casio_list_com_t *casio__callback, void *casio__cookie));
@ -392,6 +400,11 @@ CASIO_EXTERN casio_off_t CASIO_EXPORT casio_tell
CASIO_EXTERN int CASIO_EXPORT casio_getsize
OF((casio_stream_t *casio__stream, casio_off_t *casio__size));
/* Make a SCSI request. */
CASIO_EXTERN int CASIO_EXPORT casio_scsi_request
OF((casio_stream_t *casio__stream, casio_scsi_t *casio__request));
/* Make a stream out of memory. */
CASIO_EXTERN int CASIO_EXPORT casio_open_memory
@ -411,24 +424,26 @@ CASIO_EXTERN int CASIO_EXPORT casio_empty_limited
CASIO_EXTERN int CASIO_EXPORT casio_open_csum32
OF((casio_stream_t **casio__stream, casio_stream_t *casio__original,
casio_uint32_t *casio__csum));
/* ************************************************************************* */
/* USB or serial stream opening management */
/* ************************************************************************* */
/* ---
* USB and serial stream utilities.
* --- */
/* For platforms whose the utilities aren't built-in, here is a way to add
* your defaults, that will be used with the default functions!
*
* Communication port listing. */
typedef int casio_comlist_t OF((casio_list_com_t *casio__callback,
void *casio__cookie));
typedef int CASIO_EXPORT casio_comlist_t
OF((casio_list_com_t *casio__callback, void *casio__cookie));
CASIO_EXTERN int CASIO_EXPORT casio_add_default_comlist
OF((casio_comlist_t *casio__function));
/* Serial communication stream opening. */
typedef int casio_opencomstream_t OF((casio_stream_t **casio__stream,
const char *casio__path));
typedef int casio_opencomstream_t
OF((casio_stream_t **casio__stream, const char *casio__path));
CASIO_EXTERN int CASIO_EXPORT casio_open_com_stream
OF((casio_stream_t **casio__stream,
@ -438,7 +453,8 @@ CASIO_EXTERN int CASIO_EXPORT casio_add_default_com_stream
/* USB stream opening. */
typedef int casio_openusbstream_t OF((casio_stream_t **casio__stream));
typedef int CASIO_EXPORT casio_openusbstream_t
OF((casio_stream_t **casio__stream));
CASIO_EXTERN int CASIO_EXPORT casio_open_usb_stream
OF((casio_stream_t **casio__stream));
@ -447,5 +463,6 @@ CASIO_EXTERN int CASIO_EXPORT casio_add_default_usb_stream
CASIO_END_DECLS
CASIO_END_NAMESPACE
# include "builtin.h"
#endif /* LIBCASIO_STREAM_H */

View File

@ -19,6 +19,7 @@
#ifndef LIBCASIO_VERSION_H
# define LIBCASIO_VERSION_H
# include "cdefs.h"
CASIO_BEGIN_NAMESPACE
/* CASIO's versions look like 'MM.mm.ABCD', where 'MM' is the major, 'mm' is
@ -66,6 +67,7 @@ typedef struct casio_version_s {
} casio_version_t;
CASIO_BEGIN_DECLS
/* And here are the utilities to check that a version has the
* right format (for user interface, such as command-line argument checking),
* and to decode/encode a version. */

View File

@ -31,13 +31,15 @@ void CASIO_EXPORT casio_bcd_fromdouble(casio_bcd_t *bcd, double dbl)
{
int neg = 0, exp = 1, i;
/* check if is negative */
/* Check if is negative. */
if (dbl < 0) {
neg = 1;
dbl = -dbl;
}
/* check the exponent, normalize the number */
/* Check the exponent, normalize the number. */
while (dbl >= 10) {
exp++;
dbl /= 10;
@ -47,14 +49,16 @@ void CASIO_EXPORT casio_bcd_fromdouble(casio_bcd_t *bcd, double dbl)
dbl *= 10;
}
/* get the mantissa */
/* Get the mantissa. */
for (i = 0; i < 15; i++) {
double work = floor(dbl);
bcd->casio_bcd_mant[i] = (int)work;
dbl = (dbl - work) * 10;
}
/* set the flags */
/* Set the flags */
bcd->casio_bcd_flags = casio_make_bcdflags(0, neg, 15);
bcd->casio_bcd_exp = exp;
}
@ -67,9 +71,28 @@ void CASIO_EXPORT casio_bcd_fromdouble(casio_bcd_t *bcd, double dbl)
* @return the double.
*/
double CASIO_EXPORT casio_bcd_todouble(const casio_bcd_t *bcd)
double CASIO_EXPORT casio_bcd_todouble(casio_bcd_t const *bcd)
{
/* TODO */
(void)bcd;
return (0);
double val = 0.0;
double power = 1.0;
int i;
/* Use the mantissa. */
for (i = 0; i < casio_bcd_precision(bcd); i++) {
val += bcd->casio_bcd_mant[i] * power;
power /= 10.0;
}
/* Use the exponent. */
power = pow(10, (double)bcd->casio_bcd_exp);
val *= power;
/* Use the flags. */
if (casio_bcd_is_negative(bcd))
val = -val;
return (val);
}

View File

@ -20,14 +20,23 @@
# define LOCAL_LINK_H 1
# include "../internals.h"
/* Internals macros. */
/* Internal macros. */
# define response (handle->casio_link_response)
# define command_is_supported(CASIO__N) \
casio_seven_command_is_supported(&handle->casio_link_env, CASIO__N)
/* ************************************************************************* */
/* Link structure */
/* ************************************************************************* */
/* Internal stream for making Protocol 7.00 streams over SCSI. */
CASIO_EXTERN int CASIO_EXPORT casio_open_seven_scsi
OF((casio_stream_t **casio__stream, casio_stream_t *casio__original));
/* ---
* Link structure.
* --- */
/* Link handle internal flags. */
# define casio_linkflag_sendalt 0x0001 /* use alternative buffer */
# define casio_linkflag_alloc 0x0002 /* was allocated */
# define casio_linkflag_active 0x0004 /* active status */
@ -72,6 +81,7 @@ struct casio_link_s {
};
/* Decode the data field of specific packets. */
CASIO_EXTERN int CASIO_EXPORT casio_seven_decode_data
OF((casio_link_t *casio__handle,
const unsigned char *casio__raw, unsigned int casio__raw_size));
@ -83,16 +93,19 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_decode_ack
const unsigned char *casio__raw, unsigned int casio__raw_size));
/* Special send functions. */
CASIO_EXTERN int CASIO_EXPORT casio_seven_send_again
OF((casio_link_t *casio__handle));
/* Special packet functions. */
CASIO_EXTERN int CASIO_EXPORT casio_seven_send_err_resend
OF((casio_link_t *casio__handle));
CASIO_EXTERN int CASIO_EXPORT casio_seven_send_timeout_check
OF((casio_link_t *casio__handle));
/* Encode and decode raw data. */
CASIO_EXTERN unsigned int CASIO_EXPORT casio_seven_decoderaw
OF((void *casio__dest, const void *casio__encoded,
unsigned int casio__size));

View File

@ -40,7 +40,8 @@ int CASIO_EXPORT casio_open_link(casio_link_t **h, unsigned long flags,
int err = 0;
casio_link_t *handle;
/* allocate handle */
/* Allocate the handle. */
msg((ll_info, "Allocating and building the link handle!"));
*h = NULL;
if (!(*h = casio_alloc(1, sizeof(casio_link_t)))) {
@ -48,12 +49,15 @@ int CASIO_EXPORT casio_open_link(casio_link_t **h, unsigned long flags,
goto fail;
}
/* initialize handle */
handle = *h; memset(handle, 0, sizeof(casio_link_t)); /* important! */
/* Initialize the handle. */
handle = *h;
memset(handle, 0, sizeof(casio_link_t)); /* important! */
casio_init_lock(&handle->casio_link_lock);
handle->casio_link_stream = stream;
/* initialize flags */
/* Initialize the flags. */
handle->casio_link_flags = 0;
if (flags & CASIO_LINKFLAG_ACTIVE)
handle->casio_link_flags |= casio_linkflag_active;
@ -73,22 +77,26 @@ int CASIO_EXPORT casio_open_link(casio_link_t **h, unsigned long flags,
msg((ll_info, "[Options] Terminate: %s",
flags & CASIO_LINKFLAG_TERM ? "yes" : "no"));
/* set communication thingies */
/* Set communication properties. */
msg((ll_info, "Initializing stream settings."));
if (!settings)
casio_init_attrs(handle->casio_link_stream);
else
casio_set_attrs(handle->casio_link_stream, settings);
/* if active, start */
err = casio_seven_start(handle);
if (err) goto fail;
/* If active, start. */
err = casio_seven_start(handle);
if (err)
goto fail;
/* initialization went alright */
return (0);
fail:
if (*h) casio_close_link(*h);
if (*h)
casio_close_link(*h);
*h = NULL;
return (err);
}
@ -101,17 +109,22 @@ fail:
void CASIO_EXPORT casio_close_link(casio_link_t *handle)
{
/* check if handle is already freed */
if (!handle) return ;
/* Check if handle is already freed. */
if (!handle)
return ;
msg((ll_info, "Let's end that mess."));
/* end communication -- FIXME: check error? */
/* End communication -- FIXME: check error? */
casio_seven_end(handle);
/* close stream */
/* Close stream. */
casio_close(handle->casio_link_stream);
/* free handle */
/* Free the handle. */
msg((ll_info, "freeing the handle!"));
casio_free(handle);
}

View File

@ -44,8 +44,10 @@ int CASIO_EXPORT casio_open_com(casio_link_t **handle, unsigned long flags,
}
err = casio_open_com_stream(&stream, path);
if (err == casio_error_op) return (casio_error_nocalc);
if (!err) break;
if (err == casio_error_op)
return (casio_error_nocalc);
if (!err)
break;
if (err != casio_error_nocalc)
return (err);
@ -56,6 +58,8 @@ int CASIO_EXPORT casio_open_com(casio_link_t **handle, unsigned long flags,
}
err = casio_open_link(handle, flags, stream, attrs);
if (err) return (err);
if (err)
return (err);
return (0);
}

View File

@ -29,7 +29,10 @@
int CASIO_EXPORT casio_open_usb(casio_link_t **handle, unsigned long flags)
{
int err, failed = 0, tries = 3; casio_stream_t *stream;
int err, failed = 0, tries = 3;
casio_stream_t *stream, *ns;
/* Open the base USB stream. */
*handle = NULL;
msg((ll_info, "Looking for USB-connected calculators."));
@ -40,17 +43,39 @@ int CASIO_EXPORT casio_open_usb(casio_link_t **handle, unsigned long flags)
}
err = casio_open_usb_stream(&stream);
if (err == casio_error_op) return (casio_error_nocalc);
if (!err) break;
if (err == casio_error_op)
return (casio_error_nocalc);
if (!err)
break;
if (err != casio_error_nocalc)
return (err);
msg((ll_error, "No device found!"));
if (!tries--) return (casio_error_nocalc);
if (!tries--)
return (casio_error_nocalc);
failed = 1;
}
/* Open the SCSI device stream if required. */
switch ((err = casio_open_seven_scsi(&ns, stream))) {
case 0:
stream = ns;
break;
case casio_error_op:
/* Use the good ol' basic stream. */
break;
default:
return (err);
}
/* Open the link based on the stream. */
err = casio_open_link(handle, flags, stream, NULL);
if (err) return (err);
if (err)
return (err);
return (0);
}

View File

@ -176,13 +176,15 @@ CASIO_LOCAL unsigned int command_masks[] = {
* - Lephenixnoir, Hackcell (some but less models). */
CASIO_LOCAL env_corresp_t known_environments[] = {
/* bootcodes */
/* Bootcodes. */
{"Gy362000", {"fx-7400GII/fx-9860GII bootcode", MASK_ALL}},
{"Gy363000", {"fx-9750GII-2/fx-9860GII(-2) bootcode", MASK_ALL}},
{"Gy490000", {"fx-7400GII-2 bootcode", MASK_ALL}},
{"Ly755000", {"fx-CG20 bootcode", MASK_ALL | MASK_MCS}},
/* fx devices */
/* fx devices. */
{"Gy490006", {"fx-7400GII (Graph 25)",
MASK_ALL | MASK_RESET | MASK_MCS}},
{"Gy49000F", {"Graph 25+E (modified fx-7400GII-2)",
@ -205,7 +207,8 @@ CASIO_LOCAL env_corresp_t known_environments[] = {
MASK_ALL | MASK_RESET | MASK_MCS | MASK_FLS
| MASK_OSUPDATE_1}},
/* terminating entry */
/* Terminating entry. */
{NULL, {"Default environment", MASK_ALL | MASK_MCS | MASK_FLS}}
};
/* ************************************************************************* */

View File

@ -244,10 +244,21 @@ CASIO_LOCAL int casio_seven_decode(casio_link_t *handle, int scralign)
image_size = 1024;
} else if (!memcmp(&buffer[1], "TYPZ1", 5)
|| !memcmp(&buffer[1], "TYPZ2", 5)) {
int typz_size_length; /* size field length */
casio_typz_t *s = (void*)&buffer[6];
msg((ll_info, "Prizm VRAM!"));
if (buffer[5] == '1')
typz_size_length = 6;
else /* '2' */
typz_size_length = 8;
COMPLETE_PACKET(typz_size_length)
COMPLETE_PACKET(sizeof(casio_typz_t))
image_size = casio_getascii(&buffer[6], typz_size_length);
s = (void*)&buffer[6 + typz_size_length];
response.casio_seven_packet_width =
casio_getascii(s->casio_typz_width, 4);
response.casio_seven_packet_height =
@ -267,7 +278,6 @@ CASIO_LOCAL int casio_seven_decode(casio_link_t *handle, int scralign)
elsemsg((ll_error, "Unknown encoding: %.3s", s->casio_typz_enc));
/* FIXME: check size according to format? */
image_size = casio_getascii(s->casio_typz_size, 6);
msg((ll_info, "Image size: %uB", image_size));
check_sum = 1;
} else {

325
lib/link/seven/scsi.c Normal file
View File

@ -0,0 +1,325 @@
/* ****************************************************************************
* link/seven/scsi.c -- use SCSI to exchange data.
* Copyright (C) 2016-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/>.
*
* These functions are the one used behind the others to send a packet.
* ************************************************************************* */
#include "data.h"
/* The fx-CG* calculators (fx-CG10/20, known as the Prizm, and the fx-CG50,
* known as the Graph 90+E in France) uses some vendor-specific commands
* to exchange bytes over an SCSI connexion. This stream makes that
* accessible through a simple stream.
*
* To gather more information, here's the page dealing with that on Cemetech:
* https://www.cemetech.net/prizm/USB_Communication
*
* Multi-byte integers are expressed in big endian.
*
* To receive data, we must probe first if there is data available.
* In order to do that, we use the 0xC0 command which returns the following
* data:
*
* D0 00 00 00 00 00 00 SS SS 00 AA AA 00 00 00 00
*
* Where `SS SS` represents the amount of available data and `AA AA`
* is the activity status of the Prizm (`10 00` if busy).
*
* TODO: The initial `D0 00` probably links to the `CAL00D0` we receive
* in Protocol 7.00 or not?
*
* Then, if data is available, we want to receive it, so we send the
* following command:
*
* C1 00 00 00 00 00 SS SS
*
* Where `SS SS` is the amount of bytes we want to receive. The Prizm will
* answer with the raw data.
*
* To send data, we first have to probe (each time!) to check if the
* calculator is busy or not (by checking the activity field). Then, if it
* is not busy, we send the following command:
*
* C2 00 00 00 00 00 SS SS
*
* Where `SS SS` is the quantity of data we are about to send next. After
* this command is sent, we send our raw data. */
/* ---
* Cookie definition.
* --- */
/* The cookie contains the following data:
* - the original stream to use for SCSI requests;
* - the buffer (with size). */
#define COOKIE_BUFFER_SIZE MAX_PACKET_SIZE
#define reset_cookie(COOKIE) \
(COOKIE)->off = 0; \
(COOKIE)->left = 0; \
(COOKIE)->ptr = (casio_uint8_t *)&(COOKIE)[1]
typedef struct {
casio_stream_t *stream;
size_t size, off, left;
casio_uint8_t *ptr;
} seven_scsi_cookie_t;
/* ---
* Read and write from the stream.
* --- */
CASIO_LOCAL int seven_scsi_read(seven_scsi_cookie_t *cookie,
unsigned char *buffer, size_t size)
{
casio_scsi_t scsi; int err;
/* Empty what's already in the buffer. */
if (cookie->left) {
if (cookie->left >= size) {
memcpy(buffer, cookie->ptr, size);
cookie->ptr += size;
cookie->left -= size;
return (0);
}
memcpy(buffer, cookie->ptr, cookie->left);
buffer += cookie->left;
size -= cookie->left;
reset_cookie(cookie);
}
do {
casio_uint8_t *to;
size_t avail;
/* casio_uint16_t activity; */
/* Polling loop. */
while (1) {
casio_uint8_t poll_command[16] = {0xC0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
casio_uint8_t poll_data[16];
/* Send the polling command, extract the data. */
scsi.casio_scsi_cmd = poll_command;
scsi.casio_scsi_cmd_len = 16;
scsi.casio_scsi_direction = CASIO_SCSI_DIREC_FROM_DEV;
scsi.casio_scsi_data = poll_data;
scsi.casio_scsi_data_len = 16;
if ((err = casio_scsi_request(cookie->stream, &scsi)))
return (err);
avail = (poll_data[7] << 8) | poll_data[8];
/* activity = (poll_data[10] << 8) | poll_data[11]; */
/* Check if there are some bytes to get. */
if (!avail) {
/* FIXME: delay and check the timeout!!! */
continue;
}
break;
}
/* Decide which buffer to use and what size to read.
* We want to get the most bytes and directly into the buffer
* if possible.
* We could also check that `avail < 0x10000` because we need to
* express it later, but it is imposed by the source format. */
if (avail > size && size <= cookie->size) {
to = cookie->ptr;
if (avail > cookie->size)
avail = cookie->size;
} else {
to = buffer;
if (avail > size)
avail = size;
}
/* Actually get the data. */
{
casio_uint8_t recv_command[16] = {0xC1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
recv_command[6] = (avail >> 8) & 0xFF;
recv_command[7] = avail & 0xFF;
scsi.casio_scsi_cmd = recv_command;
scsi.casio_scsi_cmd_len = 16;
scsi.casio_scsi_direction = CASIO_SCSI_DIREC_FROM_DEV;
scsi.casio_scsi_data = cookie->ptr;
scsi.casio_scsi_data_len = avail;
if ((err = casio_scsi_request(cookie->stream, &scsi)))
return (err);
}
if (to == buffer) {
buffer += avail;
size -= avail;
} else {
cookie->left = avail;
memcpy(buffer, cookie->ptr, size);
cookie->ptr += size;
cookie->left -= size;
size = 0;
}
} while (size);
return (0);
}
CASIO_LOCAL int seven_scsi_write(seven_scsi_cookie_t *cookie,
unsigned char const *buffer, size_t size)
{
casio_scsi_t scsi;
int err;
do {
casio_uint16_t activity;
/* Polling loop. */
while (1) {
casio_uint8_t poll_command[16] = {0xC0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
casio_uint8_t poll_data[16];
/* Poll to check the activity. */
scsi.casio_scsi_cmd = poll_command;
scsi.casio_scsi_cmd_len = 16;
scsi.casio_scsi_direction = CASIO_SCSI_DIREC_FROM_DEV;
scsi.casio_scsi_data = poll_data;
scsi.casio_scsi_data_len = 16;
if ((err = casio_scsi_request(cookie->stream, &scsi)))
return (err);
activity = (poll_data[10] << 8) | poll_data[11];
if (activity == 0x100) {
/* The calculator is busy.
* FIXME: delay and check the timeout!! */
continue;
}
break;
}
/* Actually send some of the data. */
{
casio_uint16_t to_send = (size > 0xFFFF) ? 0xFFFF : size;
casio_uint8_t send_command[16] = {0xC2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
send_command[6] = (to_send >> 8) & 0xFF;
send_command[7] = to_send & 0xFF;
scsi.casio_scsi_cmd = send_command;
scsi.casio_scsi_cmd_len = 16;
scsi.casio_scsi_direction = CASIO_SCSI_DIREC_TO_DEV;
scsi.casio_scsi_data = (casio_uint8_t *)buffer;
scsi.casio_scsi_data_len = to_send;
if ((err = casio_scsi_request(cookie->stream, &scsi)))
return (err);
buffer += to_send;
size -= to_send;
}
} while (size);
return (0);
}
/* ---
* SCSI requests.
* --- */
CASIO_LOCAL int seven_scsi_request(seven_scsi_cookie_t *cookie,
casio_scsi_t *request)
{
/* Actually, just transmit the request to the source stream. */
return (casio_scsi_request(cookie->stream, request));
}
/* ---
* Manage the stream.
* --- */
CASIO_LOCAL int seven_scsi_close(seven_scsi_cookie_t *cookie)
{
casio_close(cookie->stream);
free(cookie);
return (0);
}
CASIO_LOCAL casio_streamfuncs_t seven_scsi_funcs = {
(casio_stream_close_t *)seven_scsi_close,
NULL,
(casio_stream_read_t *)seven_scsi_read,
(casio_stream_write_t *)seven_scsi_write,
NULL,
NULL,
(casio_stream_scsi_t *)seven_scsi_request
};
int CASIO_EXPORT casio_open_seven_scsi(casio_stream_t **streamp,
casio_stream_t *original)
{
seven_scsi_cookie_t *cookie = NULL;
/* Check if the original stream supports SCSI. */
if (~casio_get_openmode(original) & CASIO_OPENMODE_SCSI) {
/* We shall not close the original stream because the caller
* might want to use it if this stream hasn't been opened. */
return (casio_error_op);
}
/* Allocate and prepare the cookie. */
cookie = casio_alloc(1, sizeof(seven_scsi_cookie_t) + COOKIE_BUFFER_SIZE);
if (!cookie) {
casio_close(original);
return (casio_error_alloc);
}
cookie->stream = original;
cookie->size = COOKIE_BUFFER_SIZE;
reset_cookie(cookie);
/* Create the stream. */
return (casio_open_stream(streamp,
CASIO_OPENMODE_READ | CASIO_OPENMODE_WRITE | CASIO_OPENMODE_SCSI,
cookie, &seven_scsi_funcs, 0));
}

View File

@ -64,19 +64,28 @@ int CASIO_EXPORT casio_free_screen(casio_screen_t *screen)
}
/* ---
* Gather the screen.
* Gather the screen on a legacy fx device, or using legacy fx-CG formats.
* This also gathers a screen from the Prizm with protocol 7.00 compatibility.
* --- */
/**
* casio_get_screen:
* Get the screen.
/* Legacy screenstreaming uses tweaks in Protocol 7.00 (managed in the
* libcasio Protocol 7.00 link core code) to transmit a continuous feed
* of images, not expecting the other party to answer (so we're not answering).
*
* @arg handle the link handle.
* @arg screen the screen to allocate/reallocate/reuse.
* @return if it worked.
* In fact, not continuous: the calculator only sends a frame when it feels
* like it, usually when the screen changes. Also, as the calculator doesn't
* wait for us to send screens (it starts sending screens as soon as it is
* on), it might be in the middle of sending a screen when we're joining in.
* Fortunately, there is a "screen alignment" function in the packet receiving
* function that we can use, that looks for the packet beginning. It may fail
* sometimes, and get a weird screen, but it does its best. */
/**
* casio_get_seven_screen:
* Get the screen through protocol 7.00.
*/
int CASIO_EXPORT casio_get_screen(casio_link_t *handle,
CASIO_LOCAL int casio_get_seven_screen(casio_link_t *handle,
casio_screen_t **screenp)
{
int err = 0;
@ -84,8 +93,6 @@ int CASIO_EXPORT casio_get_screen(casio_link_t *handle,
/* Make checks. */
chk_handle(handle);
chk_seven(handle); /* TODO: SCSI? */
chk_passive(handle);
/* Prepare the screen. */
@ -111,7 +118,7 @@ int CASIO_EXPORT casio_get_screen(casio_link_t *handle,
if (response.casio_seven_packet_type != casio_seven_type_ohp)
return (casio_error_unknown);
/* Convert the screen buffer. */
/* Convert the screen buffer and return. */
screen->casio_screen_width = response.casio_seven_packet_width;
screen->casio_screen_height = response.casio_seven_packet_height;
@ -123,3 +130,28 @@ int CASIO_EXPORT casio_get_screen(casio_link_t *handle,
return (0);
}
/* ---
* Public function.
* --- */
/**
* casio_get_screen:
* Get the screen.
*
* @arg handle the link handle.
* @arg screen the screen to allocate/reallocate/reuse.
* @return if it worked.
*/
int CASIO_EXPORT casio_get_screen(casio_link_t *handle,
casio_screen_t **screenp)
{
int err = 0;
casio_screen_t *screen;
chk_handle(handle);
chk_seven(handle); /* TODO: SCSI? */
return (casio_get_seven_screen(handle, screenp));
}

View File

@ -18,15 +18,19 @@
* ************************************************************************* */
#include "../../internals.h"
/* cookie structure */
/* ---
* Cookie structure.
* --- */
struct thecookie {
casio_stream_t *_stream;
casio_uint32_t *_checksum;
};
/* ************************************************************************* */
/* Callbacks */
/* ************************************************************************* */
/* ---
* Callbacks.
* --- */
/**
* csum32_read:
* Read from this stream.
@ -72,9 +76,10 @@ CASIO_LOCAL const casio_streamfuncs_t csum32_callbacks =
casio_stream_callbacks_for_virtual(csum32_close,
csum32_read, NULL, NULL);
/* ************************************************************************* */
/* Main functions */
/* ************************************************************************* */
/* ---
* Main functions.
* --- */
/**
* casio_open_csum32:
* Open a 32-bit checksum stream.
@ -91,7 +96,9 @@ int CASIO_EXPORT casio_open_csum32(casio_stream_t **stream,
struct thecookie *cookie = NULL;
casio_openmode_t openmode;
/* FIXME: check original stream */
if (!casio_isreadable(original))
return (casio_error_op);
/* Allocate the cookie. */
cookie = casio_alloc(1, sizeof(struct thecookie));

View File

@ -22,7 +22,17 @@
# ifndef LIBCASIO_DISABLED_LIBUSB
# include <libusb.h>
# define BUFSIZE 2048
/* These `ENDPOINT_IN` and `ENDPOINT_OUT` are taken from the definitions
* made by Nessotrin in UsbConnector. I can't really explain them, and
* knowing the type of person he is, I'm pretty sure he got these through
* test-driven development. */
# define ENDPOINT_IN (LIBUSB_ENDPOINT_IN | LIBUSB_TRANSFER_TYPE_BULK)
# define ENDPOINT_OUT (LIBUSB_ENDPOINT_OUT | LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
/* Cookie definition used in the callbacks. */
# define BUFSIZE 2048
typedef struct {
libusb_context *_context;
@ -55,5 +65,10 @@ CASIO_EXTERN int CASIO_EXPORT casio_libusb_write
OF((cookie_libusb_t *casio__cookie,
const unsigned char *casio__data, size_t casio__size));
/* SCSI callbacks. */
CASIO_EXTERN int CASIO_EXPORT casio_libusb_scsi_request
OF((cookie_libusb_t *casio__cookie, casio_scsi_t *casio__request));
# endif
#endif /* LOCAL_STREAM_BUILTIN_LIBUSB_H */

View File

@ -22,11 +22,12 @@
/* Stream callbacks. */
CASIO_LOCAL const casio_streamfuncs_t casio_libusb_callbacks = {
(casio_stream_close_t*)&casio_libusb_close,
(casio_stream_settm_t*)&casio_libusb_settm,
(casio_stream_read_t*)&casio_libusb_read,
(casio_stream_write_t*)&casio_libusb_write,
NULL, NULL, NULL
(casio_stream_close_t *)&casio_libusb_close,
(casio_stream_settm_t *)&casio_libusb_settm,
(casio_stream_read_t *)&casio_libusb_read,
(casio_stream_write_t *)&casio_libusb_write,
NULL, NULL,
(casio_stream_scsi_t *)&casio_libusb_scsi_request
};
/**

View File

@ -29,8 +29,6 @@
* @return the error code (0 if ok).
*/
# define ENDPOINT_IN (LIBUSB_ENDPOINT_IN | LIBUSB_TRANSFER_TYPE_BULK)
int CASIO_EXPORT casio_libusb_read(cookie_libusb_t *cookie,
unsigned char *dest, size_t size)
{
@ -59,28 +57,29 @@ int CASIO_EXPORT casio_libusb_read(cookie_libusb_t *cookie,
libusberr = libusb_bulk_transfer(cookie->_handle, ENDPOINT_IN,
cookie->_buffer, BUFSIZE, &recv, cookie->tmread);
switch (libusberr) {
case 0:
break;
case 0:
break;
case LIBUSB_ERROR_PIPE:
case LIBUSB_ERROR_NO_DEVICE:
case LIBUSB_ERROR_IO:
msg((ll_error, "The calculator is not here anymore :("));
return (casio_error_nocalc);
case LIBUSB_ERROR_PIPE:
case LIBUSB_ERROR_NO_DEVICE:
case LIBUSB_ERROR_IO:
msg((ll_error, "The calculator is not here anymore :("));
return (casio_error_nocalc);
case LIBUSB_ERROR_TIMEOUT:
return (casio_error_timeout);
case LIBUSB_ERROR_TIMEOUT:
return (casio_error_timeout);
default:
msg((ll_fatal, "libusb error was %d: %s", libusberr,
libusb_strerror(libusberr)));
return (casio_error_unknown);
default:
msg((ll_fatal, "libusb error was %d: %s", libusberr,
libusb_strerror(libusberr)));
return (casio_error_unknown);
}
/* Get the current size to copy. */
tocopy = (size_t)recv;
if (tocopy > size) tocopy = size;
if (tocopy > size)
tocopy = size;
/* Copy to destination. */

View File

@ -0,0 +1,67 @@
/* ****************************************************************************
* stream/builtin/libusb/scsi.c -- make an scsi request on a libusb stream.
* Copyright (C) 2016-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/>.
* ************************************************************************* */
#include "libusb.h"
#ifndef LIBCASIO_DISABLED_LIBUSB
/* SCSI over USB in libusb uses the Bulk-Only protocol defined here:
* http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf
*
* CBW (command block wrappers) for USB-attached SCSI Mass Storage,
* with integer fields using little-endian:
*
* - Signature (4B): identify the packet as a CBW.
* [0x55, 0x53, 0x42, 0x43] (USBC)
* - Tag (4B): answerer will echo this field to us in the associated CSW.
* Used by BrandonW: [0x41, 0x42, 0x43, 0x44] (ABCD)
* - Data Transfer Length (4B):
* - Flags (1B):
* - Bit 7 (128): direction, 0 for host to device, 1 for device to host.
* - Other bits: reserved or obsolete, set to zero (0).
* - LUN (1B): LUN (from 0 to 15).
* - Command Block Length (1B): (6, 10, 12 or 16).
* - (Command Descriptor Block content)
*
* CSW (command status wrappers) for USB-attached SCSI Mass Storage,
* with integer fields using little-endian:
*
* - Signature (4B): identify the packet as a CSW.
* [0x55, 0x53, 0x42, 0x53] (USBS)
* - Tag (4B): echo the field from the CBW.
* Used by BrandonW: [0x41, 0x42, 0x43, 0x44] (ABCD)
* - Data Residue (4B):
* - Status (1B): success or failure.
* - 0: command passed (good).
* - 1: command failed (bad).
* - 2: phase error. */
/**
* casio_libusb_scsi_request:
* Make an SCSI request on a libusb connected device, using CBW.
*/
int CASIO_EXPORT casio_libusb_scsi_request(cookie_libusb_t *cookie,
casio_scsi_t *request)
{
/* TODO */
return (casio_error_op);
}
#endif

View File

@ -29,8 +29,6 @@
* @return the error code (0 if ok).
*/
# define ENDPOINT_OUT (LIBUSB_ENDPOINT_OUT | LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
int CASIO_EXPORT casio_libusb_write(cookie_libusb_t *cookie,
const unsigned char *data, size_t size)
{

View File

@ -49,7 +49,8 @@ int CASIO_EXPORT casio_add_default_usb_stream(casio_openusbstream_t *function)
struct corresp *c; int num;
for (c = openusbs, num = NUM; c->_valid && num; c++, num--);
if (!num) return (casio_error_op);
if (!num)
return (casio_error_op);
c->_valid = 1;
c->_openusb = function;
@ -73,7 +74,8 @@ int CASIO_EXPORT casio_open_usb_stream(casio_stream_t **stream)
for (; c->_valid; c++) {
err = (*c->_openusb)(stream);
if (!err) return (0);
if (!err)
return (0);
if (err != casio_error_nocalc)
return (err);
}

47
lib/stream/scsi.c Normal file
View File

@ -0,0 +1,47 @@
/* ****************************************************************************
* stream/scsi.c -- make a SCSI request.
* Copyright (C) 2018 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/>.
* ************************************************************************* */
#include "stream.h"
/**
* casio_scsi_request:
* Make a SCSI request.
*
* @arg stream the stream to use.
* @arg request the request to execute.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_scsi_request(casio_stream_t *stream,
casio_scsi_t *request)
{
int err;
casio_stream_scsi_t *s;
s = getcb(stream, scsi);
if (!s)
return (casio_error_op);
err = (*s)(stream->casio_stream_cookie, request);
failure(err, err)
err = 0;
fail:
stream->casio_stream_lasterr = err;
return (err);
}

View File

@ -35,10 +35,45 @@ int CASIO_EXPORT casio_seek(casio_stream_t *stream, casio_off_t offset,
failure(whence != CASIO_SEEK_SET && whence != CASIO_SEEK_CUR
&& whence != CASIO_SEEK_END, casio_error_op)
/* Check if the job isn't already done. */
if ((whence == CASIO_SEEK_CUR && !offset)
|| (whence == CASIO_SEEK_SET && offset == stream->casio_stream_offset))
return (0);
/* Try to seek using the dedicated function. */
s = getcb(stream, seek);
if (!s) return (casio_error_op);
err = (*s)(stream->casio_stream_cookie, &offset, whence);
failure(err, err)
if (s) {
/* The callback exists, let's use it! */
err = (*s)(stream->casio_stream_cookie, &offset, whence);
failure(err, err)
} else if (whence == CASIO_SEEK_CUR && offset > 0
&& stream->casio_stream_mode & CASIO_OPENMODE_READ) {
/* Fallback mehod for skipping bytes: read until N bytes have
* been skipped. */
{
unsigned char buf[128];
size_t to_skip = (size_t)offset;
do {
size_t rd = min(to_skip, 128);
/* Read that much from the stream. */
if ((err = casio_read(stream, buf, rd)))
goto fail;
to_skip -= rd;
} while (to_skip);
}
} else {
err = casio_error_op;
goto fail;
}
stream->casio_stream_offset = offset;
err = 0;

View File

@ -29,27 +29,8 @@
int CASIO_EXPORT casio_skip(casio_stream_t *stream, size_t size)
{
unsigned char buf[128];
/* Use what has been implemented in the `casio_seek()` function to
* skip N bytes. */
/* initial checks */
if (!stream->casio_stream_mode & CASIO_OPENMODE_READ)
return (casio_error_noread);
if (!size) return (0);
/* main loop */
msg((ll_info, "Skipping %" CASIO_PRIuSIZE " bytes.", size));
while (size) {
/* get the size of the data to read */
size_t rd = min(size, 128);
/* read */
int err = casio_read(stream, buf, rd);
if (err) return (err);
/* less size */
size -= rd;
}
/* no error! */
return (0);
return (casio_seek(stream, (casio_off_t)size, CASIO_SEEK_CUR));
}