HP Prime/File Format
This page aims at providing information about the file types of the HP Prime and their storage format (on both the computer side and the calculator side, if they're different).
Known file types
This list was extracted from the folder used by the computer version of the HP Prime software (dated August 15th, 2013), namely %appdata%/HP_Prime on Windows, and through the files generated by the HP (Prime) Connectivity Kit, located in %home%\Documents\HP Connectivity Kit\Calculators\MyCalc.
So far, it is believed that the text is in UTF-16 little endian. For other data, it appears to be sized in multiples of 4 (bytes grouped by 4).
Everything below is in hexadecimal.
App Data
"*.hpapp", "*.hpappnote", "*.hpapprgm": data for applications, built-in or others. For built-in applications, *.hpappnote files are 2+ bytes long, and *.hpappprgm files are 22+ bytes long.
User BASIC programs
"*.hpprgm"
There are two known types of files using the .hpprgm extension, one includes the script name in the metadata. Both versions use UTF16 (little endian byte order) for the name and the main data.
The current structures can handle files larger than 64K, but only in theory since some stuff will fail with these larger files, for example the size of the file is truncated to the modulus of 64K in the calculator and the connectivity kit will warn us about that the file it is too large.
Unnamed .hpprgm files
This version of the file does not includes any name, just the length of the data, and the data itself.
Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Example | 0C | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 08 | 00 | 00 | 00 | … |
Description | Type | Name flag | Size | Data | |||||||||||||||||
Additional | Unnamed | 64K current fw limit |
Named .hpprgm files
Here, the name is appended to the header without any size descriptors (the name ends with two consecutive zero-valued bytes and after that, the data begins).
Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | … | … | … |
Example | 0C | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 01 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 31 | … | 00 | 00 | … |
Description | Type | Name flag | Name start | Name | Name end | Data | |||||||||||||||
Additional | Named | Name end with 0×00, 0×00 |
Parsing .hpprgm files
We can read both files simply by using the byte at position 8 to discern which type is the file to be read [1].
Little C# code snippet [2] as example of this:
if (b.Length >= 19)
{
for (var i = 1; i <= 7; i++)
if (b[i] != 0x00)
goto case null;
switch (b[8])
{
case 0x00:
var size = b[16] + b[17]*0xff + b[18]*0xff*0xff;
Data = new byte[size];
const int offset = 20;
for (int i = offset; i < offset + size && i < b.Length; i++)
Data[i - offset] = b[i];
break;
case 0x01:
if (b[16] == 0x31)
{
for(var i=18;i<b.Length;i++)
if (b[i - 1] == b[i] && b[i] == 0x00)
{
if (!ignoreInternal)
Name = Encoding.Unicode.GetString(b.SubArray(18, i-18));
i += 8;
Data = b.SubArray(i, b.Length - i);
break;
}
}
break;
}
}
There is a bit of metadata at the beginning, labeled as type: The metadata at the beginning is about "information about exported variables/programs (so the system knows how to recognize them, and number of arguments for example, a compiled bytecode area, and the source."[3]) "On poweroff, the source is saved to flash if it has been modified. The bytecode is discarded."[4]
Settings
"calc.settings", "cas.settings, "settings": binary information about settings.
Structure
calc.settings contains a number of UTF-16 little-endian strings, among which some names for built-in apps, and the user input in the home screen (under a semi-internal form: strings such as "EVALLIST" and "NEG" can be seen).
Lists
"*.hplist": list files:
Some facts gathered over time: (Some unknown bytes are about "flags indicating status, location in memory, or similar"[5])
Structure
- The first group appears to contain a common "header" : [01/02] 00 16 00. The first byte apparently is 01 for a calculator-generated list or 02 for a connectivity-kit generated one.
- The second group contains the number of elements in the list (only the 1st byte of the group ?), which we'll call n.
- The next group(s) (n different instances of this kind of group) contains some kind of timestamp as its bytes changes over time for a same, given, list.
- The next 4 group(s) (n different instances of this kind of 4-groups) contain the element's actual data (elements in reverse order of the list) :
- The first (and second ?) subgroup contains some info about the number, like '01' on the 4th byte if positive (or zero), or 'FF' if negative
- The first 3 bytes of this subgroup are, as far as we know, not about the element itself.
- The 2nd subgroup's indicates the exponent (length of the number, minus 1). If positive, it's directly given (in hex) on the first byte (the 3 remaining right bytes being 0), and if negative, it's given by substracting from 0x100 the absolute value of the exponent (e.g. 'FD' for -3). The 3 remaining right bytes are FF.
- The 2 last subgroups contain the number, from right to left, little endian.
Examples
- {} (default/empty): a 8-byte file: 01 00 16 00 00 00 00 00
- {0} is stored as a 28-byte file: 01 00 16 00 01 00 00 00 18 2D 23 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00
- {1} is stored as a 28-byte file: 01 00 16 00 01 00 00 00 38 2D 23 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01
- {2} is stored as a 28-byte file: 01 00 16 00 01 00 00 00 58 2D 23 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 02
- {1337} is stored as a 28-byte file: 01 00 16 00 01 00 00 00 40 75 8D 01 02 00 10 01 03 00 00 00 00 00 00 00 00 70 33 01
- {9001} is stored as a 28-byte file: 01 00 16 00 01 00 00 00 80 75 8D 01 01 00 10 01 03 00 00 00 00 00 00 00 00 10 00 09
- {-9001} is stored as a 28-byte file: 01 00 16 00 01 00 00 00 A0 75 8D 01 01 00 10 FF 03 00 00 00 00 00 00 00 00 10 00 09
- {-1} is stored as a 28-byte file: 01 00 16 00 01 00 00 00 08 2D 23 01 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 01
- {1.23456789012E19} [...] 28-byte: 01 00 16 01 01 00 00 00 D8 5B AD 01 01 00 10 01 13 00 00 00 00 20 01 89 67 45 23 01
- {0.00123} is stored as a 28-byte file: 02 00 16 01 01 00 00 00 E8 60 AD 01 01 00 10 01 FD FF FF FF 00 00 00 00 00 00 23 01
- {1,2} is stored as a 48-byte file: 01 00 16 00 02 00 00 00 18 2D 23 01 38 2D 23 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01
- {-9001,1337,2} is [...] 68-byte file: 01 00 16 00 03 00 00 00 80 75 8D 01 50 75 8D 01 38 2D 23 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 02 02 00 10 01 03 00 00 00 00 00 00 00 00 70 33 01 01 00 10 FF 03 00 00 00 00 00 00 00 00 10 00 09
Matrices
"*.hpmat"
Structure
The "header" appears to be : 01 00 14 01
- [ [ 0 ] ] (default) is a 24-byte file: 01 00 14 01 02 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00
- [ [ 1 ] ] is stored as a 24-byte file: 01 00 14 01 02 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 01
Notes
"*.hpnote": note (text) files
Structure
The file seems to contain the text of the note as UTF-16 little endian, followed by a null byte (U+0000), followed by some formatting information starting by "CSWD110".
Test modes
"testmodes.hptestmodes": current settings for the exam mode ?
References
- ↑ Erwin Ried, Nov. 29 2013 - http://ried.cl/en/franqueando-los-secretos-del-hardware-mediante-ingenieria-inversa/
- ↑ Erwin Ried, Nov. 29 2013 - https://github.com/eried/PrimeComm/blob/master/PrimeComm/PrimeProgramFile.cs
- ↑ Tim Wessman, Aug. 20 2013 - http://www.omnimaga.org/index.php?topic=16826.msg304202#msg304202
- ↑ Tim Wessman, Aug. 20 2013 - http://www.omnimaga.org/index.php?topic=16826.msg304202#msg304202
- ↑ Tim Wessman, Aug. 20 2013 - http://www.omnimaga.org/index.php?topic=16826.msg304191#msg304191