diff --git a/Makefile.vars b/Makefile.vars index dd70f12..8f85fc1 100755 --- a/Makefile.vars +++ b/Makefile.vars @@ -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. diff --git a/include/libcasio/builtin.h b/include/libcasio/builtin.h index bb71dd4..11c6b3d 100644 --- a/include/libcasio/builtin.h +++ b/include/libcasio/builtin.h @@ -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: */ diff --git a/include/libcasio/cdefs.h b/include/libcasio/cdefs.h index 8452aa1..e3f7cf0 100644 --- a/include/libcasio/cdefs.h +++ b/include/libcasio/cdefs.h @@ -38,12 +38,15 @@ # include /* 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)) diff --git a/include/libcasio/cdefs/integers.h b/include/libcasio/cdefs/integers.h index 638c6b3..9197922 100644 --- a/include/libcasio/cdefs/integers.h +++ b/include/libcasio/cdefs/integers.h @@ -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" diff --git a/include/libcasio/error.h b/include/libcasio/error.h index 0d693ce..09f498b 100644 --- a/include/libcasio/error.h +++ b/include/libcasio/error.h @@ -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 diff --git a/include/libcasio/file.h b/include/libcasio/file.h index 4d0d259..b242af1 100644 --- a/include/libcasio/file.h +++ b/include/libcasio/file.h @@ -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 diff --git a/include/libcasio/fontchar.h b/include/libcasio/fontchar.h index 2c7fb9f..5170244 100644 --- a/include/libcasio/fontchar.h +++ b/include/libcasio/fontchar.h @@ -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 diff --git a/include/libcasio/format.h b/include/libcasio/format.h index 5049626..1102adc 100644 --- a/include/libcasio/format.h +++ b/include/libcasio/format.h @@ -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 diff --git a/include/libcasio/format/cas.h b/include/libcasio/format/cas.h index f4574ae..2ead5d9 100644 --- a/include/libcasio/format/cas.h +++ b/include/libcasio/format/cas.h @@ -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 + ) + /* Driver number, in ASCII (0x30 + ) * "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 */ diff --git a/include/libcasio/format/cas/gmem.h b/include/libcasio/format/cas/gmem.h index fc99253..21f0deb 100644 --- a/include/libcasio/format/cas/gmem.h +++ b/include/libcasio/format/cas/gmem.h @@ -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 */ diff --git a/include/libcasio/format/cas/picture.h b/include/libcasio/format/cas/picture.h index 6801cf2..e9a99f6 100644 --- a/include/libcasio/format/cas/picture.h +++ b/include/libcasio/format/cas/picture.h @@ -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 */ diff --git a/include/libcasio/format/cas/program.h b/include/libcasio/format/cas/program.h index 27b341a..b5c3c0a 100644 --- a/include/libcasio/format/cas/program.h +++ b/include/libcasio/format/cas/program.h @@ -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 */ diff --git a/include/libcasio/format/casemul.h b/include/libcasio/format/casemul.h index fefc2d0..800943e 100644 --- a/include/libcasio/format/casemul.h +++ b/include/libcasio/format/casemul.h @@ -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; diff --git a/include/libcasio/format/fxi.h.draft b/include/libcasio/format/fxi.h.draft index 438a94f..19ce393 100644 --- a/include/libcasio/format/fxi.h.draft +++ b/include/libcasio/format/fxi.h.draft @@ -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 diff --git a/include/libcasio/format/mcs/cells.h b/include/libcasio/format/mcs/cells.h index aab59e9..f8be14c 100644 --- a/include/libcasio/format/mcs/cells.h +++ b/include/libcasio/format/mcs/cells.h @@ -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 */ diff --git a/include/libcasio/format/mcs/picture.h b/include/libcasio/format/mcs/picture.h index ad57a57..638aa71 100644 --- a/include/libcasio/format/mcs/picture.h +++ b/include/libcasio/format/mcs/picture.h @@ -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 */ diff --git a/include/libcasio/format/mcs/program.h b/include/libcasio/format/mcs/program.h index b1d62c4..9df89fc 100644 --- a/include/libcasio/format/mcs/program.h +++ b/include/libcasio/format/mcs/program.h @@ -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 */ diff --git a/include/libcasio/format/mcs/setup.h b/include/libcasio/format/mcs/setup.h index 53c22c6..e75454f 100644 --- a/include/libcasio/format/mcs/setup.h +++ b/include/libcasio/format/mcs/setup.h @@ -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); diff --git a/include/libcasio/format/mcs/spreadsheet.h b/include/libcasio/format/mcs/spreadsheet.h index ad907c1..bac1021 100644 --- a/include/libcasio/format/mcs/spreadsheet.h +++ b/include/libcasio/format/mcs/spreadsheet.h @@ -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 */ diff --git a/include/libcasio/format/std.h b/include/libcasio/format/std.h index afd75ff..2fa4518 100644 --- a/include/libcasio/format/std.h +++ b/include/libcasio/format/std.h @@ -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 diff --git a/include/libcasio/format/std/addin.h b/include/libcasio/format/std/addin.h index 93c1856..895e2b9 100644 --- a/include/libcasio/format/std/addin.h +++ b/include/libcasio/format/std/addin.h @@ -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; diff --git a/include/libcasio/format/std/eact.h b/include/libcasio/format/std/eact.h index 9cf854a..217ed1d 100644 --- a/include/libcasio/format/std/eact.h +++ b/include/libcasio/format/std/eact.h @@ -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 */ diff --git a/include/libcasio/format/std/fkey.h b/include/libcasio/format/std/fkey.h index 5fde382..ecf4ed7 100644 --- a/include/libcasio/format/std/fkey.h +++ b/include/libcasio/format/std/fkey.h @@ -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 */ diff --git a/include/libcasio/format/std/lang.h b/include/libcasio/format/std/lang.h index 88a7176..d99e95e 100644 --- a/include/libcasio/format/std/lang.h +++ b/include/libcasio/format/std/lang.h @@ -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 */ diff --git a/include/libcasio/format/std/mcs.h b/include/libcasio/format/std/mcs.h index da8f834..8813f7f 100644 --- a/include/libcasio/format/std/mcs.h +++ b/include/libcasio/format/std/mcs.h @@ -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 diff --git a/include/libcasio/format/std/picture.h b/include/libcasio/format/std/picture.h index 109c043..2de025b 100644 --- a/include/libcasio/format/std/picture.h +++ b/include/libcasio/format/std/picture.h @@ -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 */ diff --git a/include/libcasio/format/storage.h b/include/libcasio/format/storage.h index 689a588..91493ce 100644 --- a/include/libcasio/format/storage.h +++ b/include/libcasio/format/storage.h @@ -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. * diff --git a/include/libcasio/fs.h b/include/libcasio/fs.h index 0f8b0eb..084722d 100644 --- a/include/libcasio/fs.h +++ b/include/libcasio/fs.h @@ -23,7 +23,8 @@ # include 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. */ diff --git a/include/libcasio/link.h b/include/libcasio/link.h index 2a74865..002c347 100644 --- a/include/libcasio/link.h +++ b/include/libcasio/link.h @@ -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 diff --git a/include/libcasio/log.h b/include/libcasio/log.h index beb18f7..c07ec18 100644 --- a/include/libcasio/log.h +++ b/include/libcasio/log.h @@ -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 diff --git a/include/libcasio/mcs.h b/include/libcasio/mcs.h index b665617..10dfd63 100644 --- a/include/libcasio/mcs.h +++ b/include/libcasio/mcs.h @@ -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. */ diff --git a/include/libcasio/mcsfile.h b/include/libcasio/mcsfile.h index b992878..425dbbc 100644 --- a/include/libcasio/mcsfile.h +++ b/include/libcasio/mcsfile.h @@ -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 diff --git a/include/libcasio/number.h b/include/libcasio/number.h index 324c939..73d3c47 100644 --- a/include/libcasio/number.h +++ b/include/libcasio/number.h @@ -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. */ diff --git a/include/libcasio/picture.h b/include/libcasio/picture.h index a229e81..8093ed3 100644 --- a/include/libcasio/picture.h +++ b/include/libcasio/picture.h @@ -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 diff --git a/include/libcasio/protocol/legacy.h b/include/libcasio/protocol/legacy.h index c1d2e8a..02a91a7 100644 --- a/include/libcasio/protocol/legacy.h +++ b/include/libcasio/protocol/legacy.h @@ -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. diff --git a/include/libcasio/protocol/seven.h b/include/libcasio/protocol/seven.h index 34597d2..0d61124 100644 --- a/include/libcasio/protocol/seven.h +++ b/include/libcasio/protocol/seven.h @@ -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 -/* ************************************************************************* */ -/* 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 diff --git a/include/libcasio/protocol/seven/commands.h b/include/libcasio/protocol/seven/commands.h index df02dd4..e6d3a7a 100644 --- a/include/libcasio/protocol/seven/commands.h +++ b/include/libcasio/protocol/seven/commands.h @@ -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, diff --git a/include/libcasio/protocol/typz.h b/include/libcasio/protocol/typz.h index cfeb547..834e84b 100644 --- a/include/libcasio/protocol/typz.h +++ b/include/libcasio/protocol/typz.h @@ -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 */ diff --git a/include/libcasio/setup.h b/include/libcasio/setup.h index 6e3244d..44d9bcc 100644 --- a/include/libcasio/setup.h +++ b/include/libcasio/setup.h @@ -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. */ diff --git a/include/libcasio/stream.h b/include/libcasio/stream.h index 3d4353b..4abaebb 100644 --- a/include/libcasio/stream.h +++ b/include/libcasio/stream.h @@ -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 */ diff --git a/include/libcasio/version.h b/include/libcasio/version.h index 1f21829..3700ba3 100644 --- a/include/libcasio/version.h +++ b/include/libcasio/version.h @@ -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. */ diff --git a/lib/bcd/double.c b/lib/bcd/double.c index e399825..5199d93 100644 --- a/lib/bcd/double.c +++ b/lib/bcd/double.c @@ -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); } diff --git a/lib/link/link.h b/lib/link/link.h index e22eaf0..7773415 100644 --- a/lib/link/link.h +++ b/lib/link/link.h @@ -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)); diff --git a/lib/link/open.c b/lib/link/open.c index 5b7f152..d95bdbe 100644 --- a/lib/link/open.c +++ b/lib/link/open.c @@ -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); } diff --git a/lib/link/open/com.c b/lib/link/open/com.c index 39c44cf..5522f55 100644 --- a/lib/link/open/com.c +++ b/lib/link/open/com.c @@ -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); } diff --git a/lib/link/open/usb.c b/lib/link/open/usb.c index ceba50d..9b0a935 100644 --- a/lib/link/open/usb.c +++ b/lib/link/open/usb.c @@ -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); } diff --git a/lib/link/seven/devices.c b/lib/link/seven/devices.c index 76ef59f..a046a67 100644 --- a/lib/link/seven/devices.c +++ b/lib/link/seven/devices.c @@ -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}} }; /* ************************************************************************* */ diff --git a/lib/link/seven/receive.c b/lib/link/seven/receive.c index 28bc6ee..109bf19 100644 --- a/lib/link/seven/receive.c +++ b/lib/link/seven/receive.c @@ -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 { diff --git a/lib/link/seven/scsi.c b/lib/link/seven/scsi.c new file mode 100644 index 0000000..1951590 --- /dev/null +++ b/lib/link/seven/scsi.c @@ -0,0 +1,325 @@ +/* **************************************************************************** + * link/seven/scsi.c -- use SCSI to exchange data. + * Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey + * + * 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 . + * + * 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)); +} diff --git a/lib/link/usage/getscreen.c b/lib/link/usage/getscreen.c index 7673f91..e08c7ca 100644 --- a/lib/link/usage/getscreen.c +++ b/lib/link/usage/getscreen.c @@ -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)); +} diff --git a/lib/stream/builtin/csum32.c b/lib/stream/builtin/csum32.c index 529214f..a071582 100644 --- a/lib/stream/builtin/csum32.c +++ b/lib/stream/builtin/csum32.c @@ -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)); diff --git a/lib/stream/builtin/libusb/libusb.h b/lib/stream/builtin/libusb/libusb.h index fdc75ea..b3cad60 100644 --- a/lib/stream/builtin/libusb/libusb.h +++ b/lib/stream/builtin/libusb/libusb.h @@ -22,7 +22,17 @@ # ifndef LIBCASIO_DISABLED_LIBUSB # include -# 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 */ diff --git a/lib/stream/builtin/libusb/open.c b/lib/stream/builtin/libusb/open.c index c9b05d4..3eeead1 100644 --- a/lib/stream/builtin/libusb/open.c +++ b/lib/stream/builtin/libusb/open.c @@ -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 }; /** diff --git a/lib/stream/builtin/libusb/read.c b/lib/stream/builtin/libusb/read.c index 1441f77..34d727f 100644 --- a/lib/stream/builtin/libusb/read.c +++ b/lib/stream/builtin/libusb/read.c @@ -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. */ diff --git a/lib/stream/builtin/libusb/scsi.c b/lib/stream/builtin/libusb/scsi.c new file mode 100644 index 0000000..295c6a4 --- /dev/null +++ b/lib/stream/builtin/libusb/scsi.c @@ -0,0 +1,67 @@ +/* **************************************************************************** + * stream/builtin/libusb/scsi.c -- make an scsi request on a libusb stream. + * Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey + * + * 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 . + * ************************************************************************* */ +#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 diff --git a/lib/stream/builtin/libusb/write.c b/lib/stream/builtin/libusb/write.c index 42a4e18..8f36f37 100644 --- a/lib/stream/builtin/libusb/write.c +++ b/lib/stream/builtin/libusb/write.c @@ -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) { diff --git a/lib/stream/open/usb.c b/lib/stream/open/usb.c index 377c96c..f9089dc 100644 --- a/lib/stream/open/usb.c +++ b/lib/stream/open/usb.c @@ -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); } diff --git a/lib/stream/scsi.c b/lib/stream/scsi.c new file mode 100644 index 0000000..270d8da --- /dev/null +++ b/lib/stream/scsi.c @@ -0,0 +1,47 @@ +/* **************************************************************************** + * stream/scsi.c -- make a SCSI request. + * Copyright (C) 2018 Thomas "Cakeisalie5" Touhey + * + * 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 . + * ************************************************************************* */ +#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); +} diff --git a/lib/stream/seek.c b/lib/stream/seek.c index 0191b99..376221c 100644 --- a/lib/stream/seek.c +++ b/lib/stream/seek.c @@ -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; diff --git a/lib/stream/skip.c b/lib/stream/skip.c index 46d0a79..7c785e5 100644 --- a/lib/stream/skip.c +++ b/lib/stream/skip.c @@ -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)); }