diff --git a/AUTHORS.md b/AUTHORS.md index af95d20..c4d98ee 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -6,7 +6,8 @@ from **Casiopeia**, **Cemetech** (Prizm-related), the **Universal Casio Forum** and the **Casetta** project website (where some information about legacy thingies have been regrouped). -Thanks to: +Thanks to: + - Simon Lothar (mainly on Casiopeia) for its reverse engineering and documentation (**fxReverse project documentation** with Andreas Bertheussen, and `fx_calculators_SuperH_based.chm`); @@ -19,5 +20,7 @@ Thanks to: - Tom Wheeley for making CaS a free software; - Him and Tom Lynn for documenting the legacy protocol (9700); - Zezombye (from Planète Casio) for its research on some MCS file formats; -- David Quaranta for having made and shared Flash100's source code; +- David Quaranta for making and sharing Flash100's source code; +- Walter 'dscoshpe' Hanau for providing some AFX communications dump and + reverse engineering; - Other people at **Planète Casio** for their support! diff --git a/include/libg1m.h b/include/libg1m.h index 9db9c66..fa88e3a 100644 --- a/include/libg1m.h +++ b/include/libg1m.h @@ -141,6 +141,10 @@ extern int g1m_decode_casfiles_part(g1m_mcshead_t *head, g1m_mcshead_t *heads, g1m_buffer_t *buffer); extern int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer); extern int g1m_correct_casfile_head(g1m_mcshead_t *head); + +/* announce, encode a CAS head */ +extern int g1m_encode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer); +extern int g1m_encode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer); /* ************************************************************************** */ /* MCS archive management */ /* ************************************************************************** */ diff --git a/include/libg1m/format/cas.h b/include/libg1m/format/cas.h index c158f8f..d5cc16e 100644 --- a/include/libg1m/format/cas.h +++ b/include/libg1m/format/cas.h @@ -86,10 +86,12 @@ struct cas40 { * was always 0x31 ('1' in ASCII), which are 40 bytes long. From there and other * pieces of documentation, here are the extension types I could find: */ -# define casdyn_ext_9850 0x00 /* 50 bytes long */ -# define casdyn_ext_end 0xFF /* yet an alias to `casdyn_ext_9850`, - * used by the END packet. */ -# define casdyn_ext_g100 0x31 /* 40 bytes long */ +# define casdyn_ext_9850 0x00 /* 50 bytes long */ +# define casdyn_ext_end 0xFF /* yet an alias to `casdyn_ext_9850`, + * used by the END packet. */ +# define casdyn_ext_g100 0x31 /* 40 bytes long */ +# define casdyn_ext_g100b 0x32 /* yet an alias to `casdyn_ext_g100`, + * used for some commands */ /* Here are the common fields to all packets: */ @@ -132,20 +134,25 @@ struct _cas50 { * Anyway, here is the CAS100 header after the CASDYN header is read: */ struct _cas100 { - /* drive? "INF", "FR0" */ + /* drive? + * - "INF" <1>: system + * - "FR0" <0>: segment + * - "MSG" <1>: language + * - "MR0" <4>: ? + * - "S00" <0>: ? */ uint8_t drive[3]; /* driver number, in ASCII (0x30 + ) */ uint8_t id; - /* ExportDrive: 0x400, size? */ + /* group size (size of each fragment group part to be sent): 1024 */ uint32_t _size; /* ExportDrive: 0x80, type? */ uint32_t _type; - /* ExportDrive: 0x20000, other size? */ - uint32_t _othersize; + /* drive size: 0x20000 bytes */ + uint32_t drive_size; /* 0xFFs */ uint8_t _unknown[18]; @@ -163,17 +170,20 @@ struct _cas100_info { uint8_t board[5]; uint8_t _delim0; /* 0xFF */ - /* serial settings? "038400N1.00" - * excepted the ".00", this would mean 38400 bauds, no parity, 1 stop bit */ + /* serial settings? "038400N" + * this would mean 38400 bauds, no parity (2 stop bits?) */ uint8_t settings[11]; + /* ROM version? "1.00" or "1.01" */ + uint8_t version[4]; + /* values? */ - uint32_t _val1; /* 0xF00 */ + uint32_t _val1; /* 0xF00 or 0x1000 */ uint32_t _val2; /* 0x400 */ uint32_t _val3; /* 0x100 */ /* hex value with prefix... what? */ - uint8_t hex[4]; /* "0x07", litteraly */ + uint8_t hex[4]; /* "0x07", litterally, or 0x07 followed by three 0xFFs */ uint8_t _delim1; /* 0xFF */ /* checksum */ diff --git a/include/libg1m/format/mcs/setup.h b/include/libg1m/format/mcs/setup.h index 63c786c..69dcb81 100644 --- a/include/libg1m/format/mcs/setup.h +++ b/include/libg1m/format/mcs/setup.h @@ -41,6 +41,7 @@ * [0x20] Stat Wind (0x00: Auto, 0x01: Manual); * [0x21] Graph Func; * [0x22] Dual Screen (0x03: OFF); + * [0x23] Simul Graph; * [0x24] Dynamic Type (0x00: Cont, 0x01: Stop); * [0x25] SigmaDisplay; * [0x26] Slope; @@ -54,11 +55,12 @@ * [0x2D] Resid List (0x00: None, 0x01-0x1A: List[1-26]); * [0x2E] List File (0x01-0x06: File[1-6]); * [0x2F] Variable (0x00: Range, 0x01-0x26: List[1-26]); + * [0x30] Recur Type (unknown values, default: 0x01?); * [0x31] Recur Dual (Dual Screen) (0x00: T+G, 0x01: OFF); * [0x4E] Auto Calc; * [0x4F] Show Sell (Show cell) (0x00: Formula, 0x01: Value); * [0x50] Move (0x00: Lower, 0x01: Right); - * [0x51] Sub Name (0x00: ON, 0x01: OFF); + * [0x51] Sub Name; * [0x53] Input Mode (0x00: Math, 0x01: Linear); * [0x54] Locus; * [0x55] Y=Draw Speed (0x00: Norm, 0x01: High); diff --git a/include/libg1m/mcs.h b/include/libg1m/mcs.h index 70dbd97..1a07f14 100644 --- a/include/libg1m/mcs.h +++ b/include/libg1m/mcs.h @@ -26,7 +26,7 @@ # define g1m_ans 29 /* ************************************************************************** */ -/* Main Memory Types */ +/* Main Memory types and platforms */ /* ************************************************************************** */ /* MCS file type */ # define PRIuMCSTYPE "lu" @@ -80,17 +80,76 @@ typedef unsigned int g1m_mcsinfo_t; # define g1m_get_id_major(I) ((I) >> 6) # define g1m_get_id_minor(I) ((I) & 0x3F) /* ************************************************************************** */ -/* Helpers */ +/* List, Matrix, Vector, Spreadsheet Cell */ /* ************************************************************************** */ -/* MCS cell flags */ +/* Flags */ # define g1m_mcscellflag_used 0x0001 -/* List, Matrix, Vector and Spreadsheet cell. */ +/* Main structure */ typedef struct g1m_mcs_cell_s { g1m_bcd_t real, imgn; unsigned int flags; } g1m_mcscell_t; /* ************************************************************************** */ +/* Setup */ +/* ************************************************************************** */ +/* Input flags */ +# define g1m_setupiflag_shift 0x0001 /* SHIFT is pressed */ +# define g1m_setupiflag_alpha 0x0002 /* ALPHA is pressed */ +# define g1m_setupiflag_insert 0x0004 /* Insert/overwrite mode */ +# define g1m_setupiflag_math 0x0008 /* Math input mode instead of linear */ + +/* Window flags */ +# define g1m_setupwflag_grid 0x0001 /* Grid */ +# define g1m_setupwflag_axes 0x0002 /* Axes */ +# define g1m_setupwflag_plot 0x0004 /* Draw Plot Type instead of Con */ +# define g1m_setupwflag_coord 0x0010 /* Coord */ +# define g1m_setupwflag_sigma 0x0020 /* Sigma Display */ +# define g1m_setupwflag_stat 0x0040 /* Stat Window */ +# define g1m_setupwflag_graph 0x0080 /* Graph Function */ +# define g1m_setupwflag_simul 0x0100 /* Simul Graph */ +# define g1m_setupwflag_slope 0x0200 /* Slope */ + +/* Miscallenous flags */ +# define g1m_setupmflag_deriv 0x0001 /* Derivative */ +# define g1m_setupmflag_label 0x0002 /* label */ +# define g1m_setupmflag_date360 0x0004 /* 360 Date Mode, instead of 365 */ +# define g1m_setupmflag_complex 0x0008 /* Complex answer instead of real */ +# define g1m_setupmflag_simp 0x0010 /* Auto Simplify (not Manual) */ +# define g1m_setupmflag_dynamic 0x0020 /* Continue Dynamic Type (not Stop) */ +# define g1m_setupmflag_payment 0x0040 /* Begin Payment (not End) */ +# define g1m_setupmflag_autocalc 0x0080 /* Auto Calc */ +# define g1m_setupmflag_cformula 0x0100 /* Show Cell Formula (not Value) */ + +# define g1m_setupmflag_dpfix 0x1000 /* Display Fix instead of Sci */ +# define g1m_setupmflag_dpnorm 0x2000 /* Display Norm */ +# define g1m_setupmflag_dpemode 0x4000 /* Toggle /E-mode */ + +/* More complex values */ +# define g1m_setupval_number 0 /* 0 being comp, 2,8,10,16 being the base */ +# define g1m_setupval_function 1 /* -> 0x18 */ +# define g1m_setupval_listfile 2 /* List File 1-6, 0 being none */ +# define g1m_setupval_bg 3 /* Background picture ID, 0 being none */ +# define g1m_setupval_dispid 4 /* Display ID, see dpfix/dpnorm/dpemode */ +# define g1m_setupval_residlist 5 /* Resid List */ + +/* Function types */ +# define g1m_functype_yequ 0x00 /* Y= */ +# define g1m_functype_requ 0x01 /* r= */ +# define g1m_functype_param 0x02 /* Param */ +# define g1m_functype_xequc 0x03 /* X=c */ +# define g1m_functype_ygt 0x04 /* Y> */ +# define g1m_functype_ylt 0x05 /* Y< */ +# define g1m_functype_yge 0x06 /* Y>= */ +# define g1m_functype_yle 0x07 /* Y<= */ + +/* Main structure */ +# define g1m_setupvals 6 +typedef struct g1m_setup_s { + unsigned int iflags, wflags, mflags; + unsigned char vals[g1m_setupvals]; +} g1m_setup_t; +/* ************************************************************************** */ /* Main structures */ /* ************************************************************************** */ /* mcs file special flags */ @@ -144,6 +203,9 @@ typedef struct g1m_mcsfile_s { /* for pictures and captures */ uint32_t **pic; /* 0x0RGB */ uint32_t ***pics; + + /* for settings */ + g1m_setup_t setup; } g1m_mcsfile_t; #endif /* LIBG1M_MCS_H */ diff --git a/src/decode/mcs/setup.c b/src/decode/mcs/setup.c index 4530595..9960a2d 100644 --- a/src/decode/mcs/setup.c +++ b/src/decode/mcs/setup.c @@ -31,34 +31,29 @@ int g1m_decode_mcs_setup(g1m_mcsfile_t **handle, g1m_buffer_t *buffer, g1m_mcshead_t *head) { + /* read content */ + uint8_t content[head->size]; + READ(content, head->size) + /* make final head and file */ int err = g1m_make_mcsfile(handle, head); if (err) return (err); - unsigned char *content = (void*)(*handle)->content; - READ(content, head->size) + g1m_setup_t *sp = &(*handle)->setup; - /* log angle setting */ - switch (content[0x13]) { - case 0x00: log_info("[Angle] Degrees mode"); break; - case 0x01: log_info("[Angle] Radians mode"); break; - case 0x02: log_info("[Angle] Gradians mode"); break; - } + /* get input flags */ + switch (content[0x14]) { + case 0x84: sp->iflags |= g1m_setupiflag_alpha; + case 0x01: sp->iflags |= g1m_setupiflag_shift; break; + case 0x04: sp->iflags |= g1m_setupiflag_alpha; break; } + if (content[0x15] == 0x02) sp->iflags |= g1m_setupiflag_insert; + if (!content[0x53]) sp->iflags |= g1m_setupiflag_math; - /* log number mode */ - switch (content[0x17]) { - case 0x00: log_info("[Number] Comp"); break; - case 0x01: log_info("[Number] Binary"); break; - case 0x07: log_info("[Number] Octal"); break; - case 0x09: log_info("[Number] Decimal"); break; - case 0x0F: log_info("[Number] Hexadecimal"); break; - } - - /* axes setting */ - log_info("[Axes] %s", content[0x1D] ? "on" : "off"); - - /* list file */ - log_info("[ListFile] #%hhu", content[0x2E]); + /* get window flags */ + if (content[0x1C]) sp->wflags |= g1m_setupwflag_grid; + if (content[0x1D]) sp->wflags |= g1m_setupwflag_axes; + if (content[0x19]) sp->wflags |= g1m_setupwflag_plot; + /* TODO: decode more options! */ /* no error! */ return (0); } diff --git a/src/encode/cas.c.draft b/src/encode/cas.c.draft new file mode 100644 index 0000000..31eed69 --- /dev/null +++ b/src/encode/cas.c.draft @@ -0,0 +1,75 @@ +/* ***************************************************************************** + * encode/cas.c -- encode CAS elements and file. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libg1m. + * libg1m is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3.0 of the License, + * or (at your option) any later version. + * + * libg1m is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libg1m; if not, see . + * ************************************************************************** */ +#include + +/* ************************************************************************** */ +/* Correspondances */ +/* ************************************************************************** */ +/* Types */ +typedef int (*announce_t)(g1m_mcsfile_t*, size_t*); +typedef int (*encode_t)(g1m_mcsfile_t*, g1m_buffer_t*); +struct corresp { + /* 'identification' */ + g1m_mcstype_t types; + + /* functions */ + announce_t announce; + encode_t encode; +}; + +/* All correspondances */ +static const struct corresp encodings[] = { + /* sentinel */ + {0, NULL, NULL} +}; +/* ************************************************************************** */ +/* Header/data encoding functions */ +/* ************************************************************************** */ +/** + * g1m_announce_casfile_head: + * Figure out the CAS file head. + * + * @arg head the head. + * @arg sz the size to contribute to. + */ + +int g1m_announce_casfile_head(g1m_mcshead_t *head, size_t *sz) +{ + +} + +/** + * g1m_encode_casfile_head: + * Encode a CAS file head. + */ + +int g1m_encode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer) +{ + /* TODO */ +} + +/** + * g1m_encode_casfile_part: + * Encode a CAS file data part. + */ + +int g1m_encode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer) +{ + /* TODO */ +} diff --git a/src/encode/main.c b/src/encode/main.c index 27b958c..388653b 100644 --- a/src/encode/main.c +++ b/src/encode/main.c @@ -43,7 +43,6 @@ static const struct corresp encodings[] = { /* sentinel */ {0, 0, NULL, NULL} }; - /* ************************************************************************** */ /* Main function */ /* ************************************************************************** */ diff --git a/src/manage/mcsfile.c b/src/manage/mcsfile.c index 96e3fd4..7d49617 100644 --- a/src/manage/mcsfile.c +++ b/src/manage/mcsfile.c @@ -102,6 +102,7 @@ int g1m_make_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *rawhead) /* allocate nothing */ case g1m_mcstype_end: + case g1m_mcstype_setup: case g1m_mcstype_string: /* TEMPORARY XXX */ break; @@ -185,6 +186,7 @@ void g1m_free_mcsfile(g1m_mcsfile_t *handle) /* free nothing */ case g1m_mcstype_end: + case g1m_mcstype_setup: case g1m_mcstype_string: /* TEMPORARY XXX */ break; diff --git a/src/type/cas/app.c b/src/type/cas/app.c index 6b36f4c..d46d140 100644 --- a/src/type/cas/app.c +++ b/src/type/cas/app.c @@ -67,10 +67,22 @@ static struct ext_corresp apps[] = { /* Graph 100 (Algebra FX) headers */ {casdyn_ext_g100, g1m_mcsinfo_cas100, (struct app_corresp[]){ - {"ADN"}, /* ? */ + {"MDL"}, /* Model, initialize */ + {"END"}, /* Terminate */ + {"REQ"}, /* Receive */ + {"ADN"}, /* Send */ + + {"FMV"}, /* ? */ + {"FCL"}, /* ? */ {"MCS"}, /* ? */ - {"MDL"}, /* model info? */ - {"END"}, /* end, again? */ + + ETERM + }}, + + /* Graph 100 (Algebra FX) alternate headers */ + {casdyn_ext_g100b, g1m_mcsinfo_cas100, (struct app_corresp[]){ + {"ADN"}, /* Send (bis) */ + {"REQ"}, /* Request (bis) */ ETERM }}, diff --git a/src/type/setup.c.draft b/src/type/setup.c.draft new file mode 100644 index 0000000..02ef2ad --- /dev/null +++ b/src/type/setup.c.draft @@ -0,0 +1,69 @@ +/* ***************************************************************************** + * type/setup.c -- get the setup entry id/string using an id/string. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libg1m. + * libg1m is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3.0 of the License, + * or (at your option) any later version. + * + * libg1m is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libg1m; if not, see . + * ************************************************************************** */ +#include + +struct corresp { + char *name; + int offset; +}; + +static struct corresp correspondances[] = { + {"Angle", 0x13}, + {"Mode", 0x14}, + {"Func Type", 0x18}, + {"Draw Type", 0x19}, + {"Derivative", 0x1A}, + {"Coord", 0x1B}, + {"Grid", 0x1C}, + {"Axes", 0x1D}, + {"Label", 0x1E}, + + {"Stat Wind", 0x20}, + {"Graph Func", 0x21}, + {"Dual Screen", 0x22}, + {"Simul Graph", 0x23}, + {"Dynamic Type", 0x24}, + {"SigmaDisplay", 0x25}, + {"Slope", 0x26}, + {"Payment", 0x27}, + {"Date Mode", 0x28}, + {"Answer Type", 0x29}, + {"Complex Mode", 0x2A}, + {"Display", 0x2B}, + {"Background", 0x2C}, + {"Resid List", 0x2D}, + {"List File", 0x2E}, + {"Variable", 0x2F}, + {"Recur Dual", 0x31}, + {"Auto Calc", 0x4E}, + {"Show Sell", 0x4F}, + + {"Move", 0x50}, + {"Sub Name", 0x51}, + {"Input Mode", 0x53}, + {"Locus", 0x54}, + {"Y=Draw Speed", 0x55}, + {"Sketch Line", 0x56}, + {"Frac Result", 0x57}, + {"Recur Type", 0x30}, + {"Inequa Type", 0x5D}, + {"Periods YR", 0x5E}, + {"Q1Q3 Type", 0x5C}, + {"Simplify", 0x5F}, +};