This English readme may not be up to date with the Chinese version.
An open source HP39GII firmware project
This firmware project is created by a group of calculator enthusiasts, using libraries such as FreeRTOS kernel, TinyUSB, FatFs, dhara, giac, etc. Like-minded friends are more than welcome to try out and improve the code of this project. We'd love to hear your voices!
Refer to the Install Guide for installing procedures.
Developer Guide | ||
---|---|---|
Current Development Status | Experimental Fautures | |
Comiling and Installing | ||
Prerequisites | Compiling ExistOS | Flash firmware |
Code contribution | ||
Documents (To do) | Third-party App developing | Code submision standard |
Uninstalling and Flashing Back | Contributors | License |
- Boot
- Serial debugging
- LCD driver supporting 256 shades of grey
- STMP3770 interrupt controller
- Keyboard driver (GPIO polling)
- Timer driver
- Setting CPU frequency
- Real-time clock
- USB mass storage device mode
- USB serial console
- USB keyboard & mouse emulation
- USB functions dynamic configuration
- Flash driver
- FATFS implementation
- Multitasking
- Virtual memory
- Loading applications
- Miminal MicroPython implementation
- Graphical user interface
- Basic power management
- Complete power management
- Firmware updating independent of stock tools
- Charging Ni-Mh batteries in the compartment via USB power
- Running hp39g firmware with Saturn emulator
- Running hp48g firmware with Saturn emulator
Current development status is as described above. User interface etc. are still under discussion. You may open an issue to give your opinion.
Requires:
- Firmware: Download from here.
- Download
OSLoader.sb
andExistOS.sys
.
- Download
- ExistOS Updater: Download from here.
- Only supports Windows 10 / 11.
Then follow the instructions to flash the firmware.
Requires:
- Firmware: Download from here.
- Download
OSLoader.sb
andExistOS.sys
.
- Download
- sb_loader: Used to send OSLoader to the RAM of your calculator if you haven't installed it before.
- EDB (ExistOS Debug Brige): Used to flash firmwares.
Put the mentioned files to a directory.
If you haven't installed ExistOS on your calculator, please go through this to-do list first:
- Remove all batteries from your calculator.
- Hold
ON/C
key and connect your calculator to computer via USB cable. - Run command
sbloader OSLoader.sb
- Normally your calculator will boot into the OSLoader, and then a message will show up on the screen. There is no need to unplug the USB cable now. Just continue to do the following steps.
If ExistOS has already been installed on your device:
- Connect your calculator to computer via USB cable.
- Run command
edb -r -f OSLoader.sb 1408 b
to flash the OSLoader.
- Your calculator will reboot automatically.
- Run command
edb -r -f ExistOS.sys 1984
to flash the System.
- Your calculatr will reboot automatically.
- Enjoy ExistOS!
- If you are in trouble with the installation or anything else, open an issue or join our Discord server to seek for help.
Clone the git repo first:
git clone https://github.com/ExistOS-Team/ExistOS-For-HP39GII.git # https
git clone git@github.com:ExistOS-Team/ExistOS-For-HP39GII.git # ssh
Then enter the directory:
cd ExistOS-For-HP39GII
Switch to the root directory of this project first.
Note:
gcc-arm-none-eabi
v10.3 is tested OK. Download binary executable files from here.- Using other versions of GCC may cause OSLoader to not run.
System | Install |
---|---|
Windows | Download from here and install gcc-arm-none-eabi |
Do not forget to add directory to the PATH environment variable | |
Debian & Ubuntu | apt-get install gcc-arm-none-eabi |
Arch Linux | pacman -Syu arm-none-eabi-gcc |
Other | Lookup if there are binary packages provided. Or you can build from source code |
The link above is the new version. You can download the old version (V10.3) from here |
Add udev
rule:
System | Install |
---|---|
Windows | N/A |
Linux | sudo cp 99-hp39gii.rules /etc/udev/rules.d/ |
Then restart udev to load the new rule: |
|
sudo service udev restart |
|
If commands above didn't work: | |
sudo udevadm control --reload-rules |
|
sudo udevadm trigger |
|
Other distros using udev |
Copy 99-hp39gii.rules in the project to the directory containing udev rules, then restart udev |
Install compiler:
System | Install |
---|---|
Windows | Download binary executable of Ninja, extract it to a directory and add it your PATH |
Debian & Ubuntu | apt-get install cmake make |
Arch Linux | pacman -Syu cmake make |
Install dependencies:
System | Install |
---|---|
Windows | N/A |
Debian | apt-get install libcrypto++-dev libusb-1.0.0-dev |
Ubuntu | apt-get install libcrypto++6 libcrypto++-dev libusb-1.0.0-dev |
Arch Linux | pacman -Syu libusb crypto++ |
Others | Install libusb 1.0, libcrypto++ |
Check installtion with pkg-config |
Tips: pkg-config
will search for libraries according to /usr/lib/pkgconfig/*.pc
. If you would like to manually add libraries, please modify CMakeLists.txt
to correct paths.
Build sbtool
:
System | Install |
---|---|
Windows | Pre-compiled executable in tools/ |
Linux | cd tools/sbtools/ && make |
cp sb_loader ../ |
|
cp elftosb ../ |
|
cd ../../ |
|
cd Libs/src/micropython-master/ports/eoslib/ && make |
|
cd ../../../../../ |
Build EDB
:
System | Install |
---|---|
Windows | Pre-compiled executable in tools/ |
Linux | cd tools/ |
git clone https://github.com/ExistOS-Team/edb-unix.git |
|
cd edb-unix/ |
|
mkdir build |
|
cmake -B build/ |
|
cmake --build build/ |
|
cp build/edb ../ |
|
cd ../../ |
Build sys_signer:
System | Install |
---|---|
Windows | Pre-compiled executable in tools/ |
Linux | cd tools/sys_signer/ |
mkdir build |
|
cmake -B build/ |
|
cmake --build build/ |
|
cp build/sys_signer ../ |
|
cd ../../ |
Create a new directory to store binary files and caches:
mkdir build
cd build
Preparing to compile:
System | Install | Note |
---|---|---|
Windows | cmake .. -G Ninja |
Specifies Ninja as complier |
Linux | cmake .. |
Compiling:
System | Install |
---|---|
Windows | ninja |
Linux | make |
Note: Please install drivers for HP39GII on your own.
You can skip this step if the OSLoader has been installed on your device (unless it's bricked.)
OSLoader boots ExistOS and provides low-level APIs and virtual memory service. Run commands below to load the OSLoader temporarily.
Before flashing, power off your calculator completely by removing the batteries, and then plug in USB cable while holding down the ON/C
key. Then your calculator will enter the flashing mode.
An HID device named "USB Input Device" with the ID of 066F:3770 will show up in the Device Manager under Windows.
System | Install |
---|---|
Windows | ninja sb_flash |
Linux | make sb_flash |
System | Install |
---|---|
Windows | ninja edb_flash_loader |
Linux | make edb_flash_loader |
This will flash OSLoader to the calculator.
Your calculator will reboot automatically.
System | Install |
---|---|
Windows | ninja edb_flash_sys |
Linux | make edb_flash_sys |
This will install ExistOS on your calculator.
Your calculator will reboot automatically.
Experience ExistOS first with ExistOS Emulator for Windows.
Download from here.
After system finishes booting, drag & drop files onto the emulator window to transfer them.
Replace ExistOS.sys directly.
During the first boot after the installation you will see the following dialog, prompting you to format the data section of the flash as FAT16. Press ENTER
to confirm the operation, which usually takes around 30 seconds.
This screen indicates a successful formatting attempt. Select OK to enter the main menu.
This system only comes with a KhiCAS application for now. Press ←
→
↑
↓
to navigate and ENTER
to confirm.
The Files tab is the file explorer that is capable of viewing jpg pictures, playing mjpeg encoded avi videos and executing .exp ExistOS applications. No other file managing functions are implemented now.
The Status tab shows system status and related settings.
ON
+ F5
: Enter the maintenance menu
ON
+ [+]
/ [-]
: Adjust the contrast
Holding down the F2
key while booting (or immediately after pressing the ON/C
key) will bring up the following interface:
An 80 MB USB drive, the data section of the onboard flash, will show up on your computer. The System
directory stores the assets, for example, fonts and pictures (Unused right now). The xcas
directory stores KhiCAS user scripts, sessions (history) and other datas.
Press ↓
to select the KhiCAS app under the Application tab in the main menu, and press ENTER
to launch it. A dialog will show up on the first launch, which is for you to choose between Xcas mode F1
and Python mode F6
.
After the configurations, the current status is shown on the status bar below. The first item is the current time, the second is the mode (Xcas or Python), the third is the filename of the current session.
Use time(hh, mm)
to set the time.
Calculations can be performed after initialization.
Long press the ON/C
key to clear the history.
Press SHIFT
+ ON/C
to save the session and quit KhiCAS.
General expressions can be entered in KhiCAS to perform calculations. Calculation of large integers is supported. However for floating point calculation, only single-percision floating point numbers calculation is supported.
For an expression entered in linear mode, select View (F3
) to edit it in the natural textbook editor.
Press F1
and F2
to bring up could-be commonly-used commands menu.
The cmds
menu (F4
) lists all available commands in KhiCAS as nested entries, including algebraic, complex, polynominal, probability, plotting, etc., where you can search commands needed. After selecting the command, press Input
to copy them to the main menu, ex1
ex2
to copy built-in examples or help
to show built-in help.
Use plot
command to plot functions. In the plot interface: Press ↑
↓
←
→
to move the canvas, +``-
to zoom, *
to auto-zoom and fill the screen, /
to auto-zoom and keep the scale of the axes equal.
plot(expression, x)
plot(expression, x=[start...end], xstep=step)
plotpolar
command plots in polar coordinate system.
plotfield
command draws vector fields.
Two input syntax modes are present in KhiCAS, namely Xcas and Python. With the ability to execute scripts, new functions can be defined via programming. Here we use Python syntax to implement the following bifurcation diagram.
Press File
(F6) in the main menu and select the 6th item to open the script editor.
In the editor, the top left corner shows current time, syntax mode, filename and current line/total lines. F1
~F3
stores shortcut commands such as symbolic conditionals, loop bodies, function definitions, etc.
The script we are using is as follows. First we define two global vectors r
and p
, where the result of function f
iteration will be stored. Then we can plot by calling KhiCAS command point(r,p)
externally.
r = []
p = []
def f():
for u in range(0, 40):
x = 0.132456
for n in range(1,50):
x1 = (u/10)*x*(1-x)
x = x1
if n > 25:
r.append(u/100)
p.append(x)
return
After editing, the script can be checked and compiled using the Check syntax option in the File menu, and the result will be output to the console.
The following figure shows the result of compiling a script with a symbolic error, with a specific indication of the line number. (Compiling Python scripts in Xcas mode also causes error.)
The result of a successful compilation is shown below.
The function name in the script is called to execute the function written above, and the point
command is then called to draw the scattered data to the canvas.
Final output:
ExistOS supports controlling the DC-DC and linear regulators inside the SoC to step-down 5V USB voltage, feeding 1.4V to the battery compartment. Make sure you're using rechargable batteries when using this feature to avoid possible danger.
Usage: Plug in USB cable and switch to the Status
tab. Scroll to the bottom and tick Enable Charge
to start charging. The core temperature shown above may rise up to 50℃, since the voltage regulators are integrated in the same chip along with the CPU.
The following system status graph was drawn charging one AAAA battery rated 400mAh 1.2V for 6 hours.
The following system status graph was drawn discharging one AAAA battery rated 400mAh 1.2V for 2 hours.
This application runs the firmware of HP39/48 calculators by running a Saturn emulator. Right now it only supports loading the HP 39g firmware, leaving quitting the emulator and saving user data unfinished. Optimizations are also not applied yet, so expect a slow speed.
Usage: Put rom.g39
(1MB) to the root directory of the calculator's internal storage, then start Emu48
from the main menu.
Reboot: ON + F6
Shut down: ON + F3
You need to erase the whole flash before flashing back to the HP Firmware, otherwise you'll get stuck at the formatting progress when using the official update tool.
How to erase the whole flash:
After flashing OSLoader or while ExistOS is running, press ON
+F5
to enter the maintenance menu, and then press F2
to erase the flash. This operation cannot be undone. When the screen shows "Flash Cleared", connect the calculator to a computer and launch the official update tool under 7 / XP to flash your calculator back to the HP firmware.
ExistOS APP Demo Repo:
https://github.com/ExistOS-Team/ExistOS-App-demo
If you want to contribute to this project, please follow the standards below
-
Variable
- Variables are named using lower camel case. For example,
windowHeight
- Function parameter naming is the same as variable.
- Don't name using a single letter except for temporary or loop variable.
- It is prefered to add some meaningful prefix. For example,
p
means pointer. - Don't define variable and pointer at the same time on one line, such as
char *p, q;
- Variables are named using lower camel case. For example,
-
Function
- Functions are named using underline. For example,
get_window_width
。 - Function names should follow the Verb - object relationship.
- It is prefered to add some meaningful prefix. For example,
is
means the type of return value is bool. - Short function can be defined as inline, function parameters and return values should be pointer instead of variable.
- Avoid using recursion, consider refactoring to cycling.
- Functions are named using underline. For example,
-
Constant, macro and hardware-related
- Constants and macros are named using underline to divide upper-case letters. For example,
MAX_WIDTH
。
- Constants and macros are named using underline to divide upper-case letters. For example,
-
Custom type
- Custom type names are named using underline (tentative).
- Must use typedef to define a custom type before using struct to define non-single-instance object.
-
Operator and other symbol
- Unary operators should appress the variable, such as
c++
,*p
. - Binary operators shold have spaces on both sides, such as
i == 1
,a += 3
, except for->
- Ternary are the same as binary, such as
isLeft ? 1 : 0
. - commas should be followed by a space.
- Parentheses should be added appropriately where it is not easy to understand.
- Unary operators should appress the variable, such as
-
Pseudo-class
If object-oriented is necessary, you can consider using
typedef struct
as pseudo-class.-
Pseudo classes should be named by the upper camel case (Pascal) name.
-
For properties inside the class, its name is the same as the general variable.
-
Pseudo-class methods are not saved in pseudo-classes, but are global functions. Methods should be named using underline.
-
Normal method should be named as
ClassName_method_name
, the first parameter should always be a pointer to the instance and be namedthis
(even unnecessary). -
Static method should be named as
ClassName_static_method_name
。 -
General method named
ClassName_initializer
should be called right after an instance is defined.
-
-
-
Coding
7.1
if (a == 1) { // There should be spaces between keywords and brackets, and spaces between brackets and curly brackets // code here }else{ // Use Java style // code here } if (b == 1) return; // When there is only one sentence of code in the block, you can leave a blank space without curly braces
7.2
while (true) ; // When using empty loops, you should wrap the semicolon and indent it
7.3
(a) The loop variable of a general for loop is defined in the for loop:
for (int i = 0; i < l; i++) { // code here }
(b) In cases where circular variables are used externally, an initial value should also be given here:
int i; for (i = 0; i < l; i++) { // code here } return i;
(c) Do not leave any of the three of for loops empty:
for ( ; ; )
, otherwise use the while loop.7.4 Don't use assignment where a sentence needs to be judged, such as
if (a = 1), (a = 1) ? a : 0
.7.5 The goto statement should be avoided as much as possible.
7.6 Switch should be used more than else if.In a switch statement, it is best to have a break/return statement in each case, except when multiple cases share exactly the same piece of code.Care should be taken when using switch traversal and it is best to comment on it.
For VSCode users, clang-format
extension is available to format the code conveniently.
Special thanks to: