cake
/
libg1m
Archived
1
0
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
libg1m/include/libg1m/format/storage.h

153 lines
6.0 KiB
C
Raw Normal View History

/* ************************************************************************** */
/* _____ _ */
2016-12-28 20:55:07 +01:00
/* libg1m/format/storage.h |_ _|__ _ _| |__ ___ _ _ */
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2016/12/25 13:39:13 |___/ */
/* */
/* ************************************************************************** */
2016-12-28 20:55:07 +01:00
#ifndef LIBG1M_FORMAT_STORAGE_H
# define LIBG1M_FORMAT_STORAGE_H
2016-12-29 02:07:32 +01:00
/* Storage backup files (G1S) contain backups of the storage memory.
* It corresponds exactly to the on-calc storage memory structure.
*
* According to Simon Lothar, the files contain zeroes up to 0x00270000
2016-12-29 02:07:32 +01:00
* (including the StandardHeader; this is the location of the SMEM in real
* fx-9860 calculators), then it has the same structure than the one
* used by the calculator.
*
2016-12-29 02:07:32 +01:00
* It looks like these files are not managed by the calculator (not directly);
* however, they are managed by FA-124. */
/* ************************************************************************** */
/* 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
* is less than 28-bytes long). Here is its structure: */
struct storage_entry {
/* the type number - see below */
uint16_t type;
/* the unique number of the entry */
uint16_t uuid;
/* the raw subheader */
uint8_t raw_subheader[28];
};
/* The `type` is composed of three nibbles of identification (`type & 0xFFF`)
* and a (high) nibble of special properties, keep that in mind.
* Here are the known types: */
enum storage_entry_type {
storage_entrytype_sector = 0x200,
storage_entrytype_directory = 0x110,
storage_entrytype_file = 0x120,
storage_entrytype_fragment = 0x130,
};
/* The list has 0x800 entries, and occupies the two first sectors (or maybe
* just one, but it looks like data storage starts at sector 3). Entries with
* a type being 0xFFFF should not be read. */
2016-12-29 02:07:32 +01:00
/* ************************************************************************** */
/* Sectors */
/* ************************************************************************** */
/* Sectors represent the physical sectors of the storage memory (space!).
* Simon Lothar says that there are 27 entries for them (or 25 "not on the
* AU" in the other documentation, whatever that means). If the logical number
* is 0xFFFFFFFF, the sector is unused. First sector contains gibberish in the
* logical number field, as it's occupied by the directory.
2016-12-29 02:07:32 +01:00
*
* Their special nibble is either 0x04 or 0x00, I don't know why yet.
* Here is their subheader structure: */
struct storage_sector {
/* the sector start address - 0xFF */
uint32_t startaddr;
/* the sector ID - because for some reason, fragments won't use the uuid */
uint32_t logical_sector_number;
};
/* ************************************************************************** */
/* Directories */
/* ************************************************************************** */
/* After the sectors come the directories.
*
* Their special nibble is either 0x05 if active or 0x00 if deleted.
* Here is their subheader structure: */
struct storage_directory {
/* the directory reference - looks unusable */
uint32_t directory_reference;
/* the name (FONTCHARACTER-encoded) */
FONTCHARACTER name[12];
};
/* ************************************************************************** */
/* Files */
/* ************************************************************************** */
/* After the directories come the files (interrupted by fragments - see after).
*
* Their special nibble have the same meaning that for directories.
* Here is their subheader structure: */
struct storage_file {
/* the directory reference
* - is `storage_entrytype_directory` if the file is in a subdirectory.
* - is 0xFFFF otherwise. */
uint16_t directory_reference;
/* the directory number - should be read only if is in a subdirectory. */
uint16_t directory_number;
/* the name (FONTCHARACTER-encoded) */
FONTCHARACTER name[12];
};
/* ************************************************************************** */
/* File fragments */
/* ************************************************************************** */
/* After each file entry comes the corresponding fragments entries.
* Fragments are in fact links to the sectors, with some more info.
*
* Their special nibble have the same meaning that for files... but are not
* always accurate, so only check on files.
* Here is their subheader structure: */
struct storage_fragment {
/* the file ID */
uint32_t file_uuid;
/* the file type (probably detected when the file is transferred):
* - 0x01 for an unknown type;
* - 0x02 for an add-in (G1A);
* - 0x06 for an MCS archive (G1M);
* - 0x2E for an MCS archive with setup (G1R).
*
* why is it here and not in the file entry data? you've got a point. */
uint16_t file_type;
/* the fragment count */
uint16_t fragment_count;
/* the fragment number */
uint16_t fragment_id;
/* the sector id that the fragment is linked to */
uint16_t fragment_sector_id;
/* offset of the used bytes in sector */
uint16_t used_bytes_offset;
/* number of used bytes in sector */
uint16_t used_bytes;
};
2016-12-28 20:55:07 +01:00
#endif /* LIBG1M_FORMAT_STORAGE_H */