cake
/
libg1m
Archived
1
0
Fork 0

Added Main ID distinguishment

This commit is contained in:
Thomas Touhey 2016-11-24 17:55:51 +01:00
parent 2baded1666
commit b98ca3b0ee
5 changed files with 121 additions and 45 deletions

11
TODO.md Normal file
View File

@ -0,0 +1,11 @@
# TODO in libg1m
## Find out what these formats are/how to parse them
- G1L (languages for fx calculators?);
- G1N (???);
- G3L (languages for cg calculators);
- G3M (like G1M?);
## Correct the parsing of these formats
- G1M (BCD, other subtypes);
- G1A/G3A (addins for fx and cg calculators);
- G3P (pictures).

View File

@ -20,32 +20,7 @@
* In fact, there is no name for the general format, only names for the
* "subformats" based on this one.
*
* Here's a complete list of the declinations and corresponding IDs: */
enum g1m_type {
/* fx-CG add-in */
g1m_typ_addin_cg = 0x2c,
/* mcs (main memory) save */
g1m_typ_mcs = 0x31,
/* e-activity (document) */
g1m_typ_eact = 0x49,
/* g1r equivalent */
g1m_typ_g2r = 0x62,
/* g3m (fx-CG program) */
g1m_typ_g3m = 0x75,
/* g3p (fx-CG picture) */
g1m_typ_g3p = 0x7d,
/* add-in (compiled program) */
g1m_typ_addin = 0xf3,
};
/* It all starts with a header, called Standard Header by Simon Lothar.
* It all starts with a header, called Standard Header by Simon Lothar.
* This Standard Header contains the total filesize, the G1M type (add-in,
* MCS, e-acts), some data that will be useful for the MCS type, and some
* magic and control bytes.
@ -57,7 +32,7 @@ enum g1m_type {
* it can simply be obtained bitwise-AND-ing with 0xff. */
struct standard_header {
/* the file identifier, should be "USBPower". */
/* the file identifier - see below */
uint8_t main_id[8];
/* our filetype! */
@ -90,6 +65,52 @@ struct standard_header {
uint16_t number;
};
/* At the beginning, we thought "USBPower" was some magic sequence we would
* systematically find in the "main_id" field. But a counter example came:
* the G3L, where the main ID was "Ly755 ".
*
* So here are the known main IDs: */
enum g1m_main_id {
/* "USBPower": the most common one */
g1m_mid_usbpower,
/* "Ly755 ": fx-CG specific types */
g1m_mid_ly755,
};
/* Here are USBPower types: */
enum g1m_usbpower_type {
/* fx-CG add-in */
g1m_usbpower_type_addin_cg = 0x2c,
/* mcs (main memory) save */
g1m_usbpower_type_mcs = 0x31,
/* e-activity (document) */
g1m_usbpower_type_eact = 0x49,
/* g1r equivalent */
g1m_usbpower_type_g2r = 0x62,
/* g3m (fx-CG program) */
g1m_usbpower_type_g3m = 0x75,
/* g3p (fx-CG picture) */
g1m_usbpower_type_g3p = 0x7d,
/* add-in (compiled program) */
g1m_usbpower_type_addin = 0xf3,
};
/* And here are Ly755 types: */
enum g1m_ly755_type {
/* language file */
g1m_ly755_type_lang = 0x2c
};
# pragma pack()
/* After the Standard Header is read and the G1M type is read, we have parts,

View File

@ -55,7 +55,7 @@
/* Functions prototypes */
void g1m_log_mem(const char *prefix, void *m, size_t n);
const char *g1m_get_type_string(int code);
const char *g1m_get_type_string(int main_id, int type);
const char *g1m_get_mcs_ftype_string(int code);
const char *g1m_get_eact_ltype_string(int code);

View File

@ -135,17 +135,25 @@ void g1m_log_mem(const char *prefx, void *m, size_t n)
* @return the string.
*/
const char *g1m_get_type_string(int code)
const char *g1m_get_type_string(int main_id, int type)
{
switch (code) {
case g1m_typ_addin_cg: return ("fx-CG addin");
case g1m_typ_mcs: return ("mcs");
case g1m_typ_eact: return ("e-activity");
case g1m_typ_g2r: return ("mcs (g2r)");
case g1m_typ_g3p: return ("g3p");
case g1m_typ_addin: return ("addin");
default: return ("unknown");
switch (main_id) {
case g1m_mid_usbpower:
switch (type) {
case g1m_usbpower_type_addin_cg: return ("fx-CG addin");
case g1m_usbpower_type_mcs: return ("mcs");
case g1m_usbpower_type_eact: return ("e-activity");
case g1m_usbpower_type_g2r: return ("mcs (g2r)");
case g1m_usbpower_type_g3p: return ("g3p");
case g1m_usbpower_type_addin: return ("addin");
}
break;
case g1m_mid_ly755:
switch (type) {
case g1m_ly755_type_lang: return ("fx-CG language file");
}
}
return ("unknown");
}
/**

View File

@ -9,6 +9,23 @@
/* ************************************************************************** */
#include <libg1m/internals.h>
/**
* get_main_id:
* Get numerical main ID based on the main ID string.
*
* @arg s the 8-bytes buffer containing the ID.
* @return the main ID or -1 if the main ID is unknown.
*/
static int get_main_id(unsigned char *s)
{
if (!memcmp(s, "USBPower", 8))
return (g1m_mid_usbpower);
if (!memcmp(s, "Ly755 ", 8))
return (g1m_mid_ly755);
return (-1);
}
/**
* g1m_parse:
* Parse a G1M file.
@ -50,37 +67,56 @@ int g1m_parse(g1m_t *handle, FILE *stream)
return (g1m_error_magic);
}
/* get the main ID */
int main_id = get_main_id(hd.main_id);
if (main_id < 0) {
log_fatal("Main ID is unknown: '%.8s'", hd.main_id);
return (g1m_error_magic);
}
/* log some data */
log_info("Standard Header Main ID is '%.8s'", hd.main_id);
log_info("Standard Header Type is '%s' (0x%02x)",
g1m_get_type_string(hd.type), hd.type);
g1m_get_type_string(main_id, hd.type), hd.type);
log_info("Standard Header filesize is %uo", hd.filesize);
log_info("Standard Header num is %d.", hd.number);
/* subparse. */
handle->is_cg = 0;
switch (hd.type) {
case g1m_typ_addin:
switch (main_id) {
case g1m_mid_usbpower:
switch (hd.type) {
case g1m_usbpower_type_addin:
handle->type = g1m_type_addin;
return (g1m_parse_addin(handle, stream));
case g1m_typ_addin_cg:
case g1m_usbpower_type_addin_cg:
handle->type = g1m_type_addin;
handle->is_cg = 1;
return (g1m_parse_addin_cg(handle, stream, &hd));
case g1m_typ_g2r:
case g1m_typ_mcs:
case g1m_usbpower_type_g2r:
case g1m_usbpower_type_mcs:
handle->type = g1m_type_mcs;
return (g1m_parse_mcs(handle, stream, hd.number));
case g1m_typ_eact:
case g1m_usbpower_type_eact:
handle->type = g1m_type_eact;
return (g1m_parse_eact(handle, stream));
case g1m_typ_g3p:
case g1m_usbpower_type_g3p:
handle->type = g1m_type_pict;
handle->is_cg = 1;
return (g1m_parse_g3p(handle, stream, &hd));
default:
log_info("Type not managed (yet?): 0x%02x", hd.type);
}
break;
case g1m_mid_ly755:
switch (hd.type) {
case g1m_ly755_type_lang:
log_info("Lang type isn't managed yet.");
break;
default:
log_info("Type not managed (yet?): 0x%02x", hd.type);
}
break;
}
/* no error */