db48x/help/db48x.md
Christophe de Dinechin 97b5917069 fractions: Option to render mixed fractions
Add `MixedFractions` option to render `3/2` as `1 1/2`.
The opposite setting is `ImproperFractions`.

In addition, fractions can be rendered as small digits,
e.g. `¹²/₄₃`. This is controlled by the `SmallFractions` and
`BigFractions` settings.

The menus were updated accordingly.

Fixes #554

Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
2023-11-12 22:07:12 +01:00

140 KiB
Raw Blame History

Overview

DB48X on DM42

The DB48X project intends to rebuild and improve the user experience of the legendary HP48 family of calculators, notably their "Reverse Polish Lisp" (RPL) language with its rich set of data types and built-in functions.

This project is presently targeting the SwissMicro DM42 calculator and leveraging its built-in software platform, known as DMCP. This is presumably the calculator you are currently running this software on.

Table of contents

State of the project

This is currently SEMI-STABLE software, meaning that the implemented features appear to work somewhat reliably, but that some features are still being added with each new release. This is NOT PRODUCTION READY and should not be used for any mission-critical computation.

At this point in time, you should only installing this if you are interested in contributing to the project, whether it is in the form of code, feedback or documentation changes. Please refer to the web site of the project on GitHub or GitLab for details and updates. The best way to report an issue, request an improvement or submit a proposed change is on the project's GitHub page.

The implementation status section categorizes all the RPL commands in the HP50G and in DB48X into "implemented", "not implemented" and "DB48X only" lists.

Design overview

The objective is to re-create an RPL-like experience, but to optimize it for the existing DM42 physical hardware. Ideally, DB48X should be fully usable without a keyboard overlay. though one is being worked on.

Compared to the original HP48, the DM42 has a much larger screen, but no annunciators (it is a fully bitmap screen). It has a keyboard with dedicated soft-menu (function) keys, but only one shift key (whereas the HP48 has two), lacks a dedicated alpha key, does not provides left or right arrow keys (only up and down), and has no space key (SPC on the HP48).

Keyboard interaction

The keyboard differences force us to revisit the user interaction with the calculator compared to the HP48:

  • When running DB48X on the DM42, the single yellow shift key cycles between three states, Shift (shown in the documentation as 🟨), Right Shift (shown in the documentation as 🟦), and no shift. This double-shift shortcut appears necessary because RPL calculators like the HP48 have a rather full keyboard even with two shift keys.

  • A first press on the shift key is shown as 🟨 in the documentation, and activates functions shown in yellow in the keyboard overlay. A second press is shown as 🟦 in the documentation, and activates functions shown in blue in the keyboard overlay. On the screen, the shift state is indicated in the header area. When a soft menu is visible on the screen, the selected row of functions is highlighed.

In the rest of this document, the shift key is referred to as 🟨, and pressing it twice is referred to as 🟦, irrespective of the appearance of the physical shift key on your particular hardware.

Left Shift

Other aspects of the keyboard interaction are fine-tuned for RPL usage:

  • Since RPL uses alphabetic entry (also called Alpha mode) a lot more frequently than on RPN models like the HP41 or HP42, making it quickly accessible seems important, so there are three distinct ways to activate it.

  • The and keys move the cursor left and right while editing instead of up and down. These cursor movements are much more useful for a text-based program editing as found in RPL. In the rest of this document, they are described as ◀︎ and ▶︎ respectively.

  • Using 🟨 ◀︎ and 🟨 ▶︎ moves the cursor up and down. When not editing, ◀︎ and ▶︎ behave like and on the HP48, i.e. ◀︎ enters the interactive stack (not yet implemented) and ▶︎ edits the object on the first level of the stack.

  • Long-pressing arrow keys, the (also known as Backspace) or text entry keys in Alpha mode activates auto-repeat.

  • Long-pressing keys that would directly trigger a function (e.g. SIN), including function keys associated with a soft-menu, will show up the built-in help for the corresponding function.

Alpha mode

Entering alphabetic characters is done using Alpha mode. These alphabetic characters are labeled on the right of each key on the DM42's keyboard.

When Alpha mode is active, an ABC indicator shows up in the annunciator area at the top of the screen. For lowercase entry, the indicator changes to abc.

There are three ways to enter Alpha mode:

  • The first method is to use 🟨 ENTER as indicated by the ALPHA yellow label on the DM42 ENTER key. This cycles between Alpha ABC, Lowercase abc and Normal entry modes.

  • The second method is to hold 🟨 for more than half a second. This cycles between Alpha ABC and Normal entry modes, and cannot be used to type lowercase characters.

  • The third method is to hold one of the arrow keys ◀︎ or ▶︎ while typing on the keyboard. This is called transient alpha mode because Alpha mode ends as soon as the arrow key is released. Using ◀︎ enters uppercase characters, while ▶︎ uses lowercase characters.

There is no equivalent of the HP48's "single-Alpha" mode. Alpha mode is either transient (when you hold one of the arrow keys) or sticky (with 🟨 ENTER or by holding 🟨).

Alpha mode is cancelled when pressing ENTER or EXIT.

Since the DM42's alphabetic keys overlap with the numeric keys (unlike the HP48), as well as with operations such as × and ÷, using 🟨 in Alpha mode brings back numbers. This means 🟨 cannot be used for lowercase, but as indicated above, there are two other methods to enter lowercase characters.

Using 🟨 or 🟦 in combination with keys other than the numeric keypad gives a variety of special characters.

Key mapping

The layout of keys on DB48X was carefully chosen to offer a good compromise between immediate applicability for calculations and giving access to numerous advanced functions through menus.

DB48X keyboard overlays for DM-42 and DM-32 SwissMicros calculators are already available.

DB48X keyboard layout

In the rest of this document, keys bindings will usually be described using the alphabetic key, to make it easier to locate on the keyboard, followed by the standard label on the DB48X layout. For example, the assignment for the sin function will be described as J (SIN). The shifted functions of the same key will be described as 🟨 J (SIN⁻¹) or 🟦 J (HYP) respectively.

In some cases, the label between parentheses may refer to another calculator model, which will be indicated as follows. For example, the A key can be described as A (⚙️, DM-42 Σ+, DM-32 √x).

However, if you are using DB48X on a DM42, it is possible to do it without a keyboard overlay, because great care was taken to have the DB48X keboard layout remain close to that of the DM42, in order to preserve muscle memory. New features were positioned on the keyboard at positions that are close to what is familiar in the original DM42 firmware.

A few keys that have little use in RPL are reassigned to features that you should be able to quickly remember. For example, the DM-42 RCL key is used for the DB48X VAR key, which invokes the VariablesMenu.

Note that the LOG and e^x keys are swapped relative to the DM-42. The HP42 has LOG and LN with shifted 10^x and e^x. DB48X has e^x and LN with shifted 10^X and LOG, so that the more frequently used mathematical functions are available without shifting. Note that in the future, full keyboard remapping similar to the HP41 or HP48 will allow you to change that if you prefer.

Here are a few of the interesting RPL-specific key mappings:

  • A (⚙️, DM-42 Σ+, DM-32 √x) is used to invoke a context-sensitive ToolsMenu, which select a softkey menu based on what is on the stack and other context.

  • 🟨 A (←MENU, DM-42 Σ-, DM-32 ) selects the LastMenu command, which displays the previously selected menu.

  • 🟦 A (MAIN, DM-32 PARTS) selects the MainMenu, a top-level menu giving indicrect access to all other menus and features in DB48X (see also the Catalog feature).

  • F (' (), DM-42 XEQ, DM-32 Σ+) opens an algebraic expression, i.e. it shows '' on the command-line and switches to equation entry. If already inside an equation, it inserts a pair of parentheses. This can be used to evaluate expressions in algebraic mode instead of RPN.

  • 🟨 G (CPLX, DM-42 COMPLEX, DM-32 CMPLX) lets you work with complex numbers. It opens the ComplexMenu, which can be used to enter complex numbers in rectangular or polar form, and perform common operations on these numbers. The same menu can be accessed without shift using A (⚙️) when there is a complex number on the stack.

  • H (VAR, DM-42 and DM-32 RCL) opens the VariablesMenu showing user variables in the current directory.

  • I (STK, DM-42 and DM-32 R↓) will open the StackMenu, giving access to stack operations.

  • 🟨 I (CONST, DM-42 π, DM-32 HYP) will show a ConstantsMenu giving access to various constants. In a future version of the firmware, you will be able to provide your own constants in a CONSTANTS.CSV file on disk.

  • M (X⇆Y) executes the RPL Swap function

  • 🟨 M (LAST, DM-42 LAST x, DM-32 MEM) is LastArg, which recalls the arguments of the last command.

  • 🟦 M (Undo, DM-32 X⇆) restores the previous state of the stack. This is like Last Stack on the HP48, but on DB48X, it is a real command that can be used in programs.

  • N (+/-) executes the equivalent RPL Negate function. While editing, it changes the sign of the current number on the command-line.

  • O (EEX, DM-42 and DM-32 E) is used to enter the exponent of a number in scientific notation. However, when not entering or editing values, it invokes the Cycle command, which cycles between various representations of a number, for example polar and rectangular for a complex number, or fraction and decimal for a decimal number.

  • EXIT (DM-32 ON) corresponds to what the HP48 manual calls Attn, and typically cancels the current activity. It can also be used to interrupt a running program.

  • 🟨 EXIT (OFF) shuts down the calculator. The state of the calculator is preserved.

  • 🟦 EXIT (SAVE) saves the current state of the calculator to disk. This state can be transferred to another machine, and survives system reset or firmware upgrades.

  • 🟨 0 (SETUP) shows the firmware's SystemMenu, for example to load the original DM-42 or DM-32 program, activate USB disk, and to access some calculator preferences.

  • The R/S keys inserts a space in the editor, an = sign inside equations, and maps to Evaluate otherwise.

  • 🟨 R/S («PROG», DM-42 and DM-32 PRGM) inserts the delimiters for an RPL program, « and », while 🟦 R/S ({LIST}) inserts the list delimiters, { and }.

  • 🟨 + (CAT, DM-42 CATALOG, DM-32 LBL) shows a complete context-sensitive catalog of all available functions, and enables auto-completion using the soft-menu keys. Note that the + key alone (without shift) activates the catalog while in Alpha mode.

  • 🟦 + (HELP, DM-32 RTN) activates the context-sensitive help system.

Soft menus

The DM42 has 6 dedicated soft-menu keys at the top of the keyboard. Most of the advanced features of DB48X can be accessed through these soft menus. Soft menu keys have no label on the physical calculator, but in this documentation, they may sometimes be referred to as F1 through F6.

All built-in soft-key menus are named, with names ending in Menu. For example, the VariablesMenu is the menu listing global variables in the current directory. Unlike HP RPL calculators, menus cannot be accessed by number, but they can be accessed by name. In a future version of the firmware, a Menu special variable will return the name of the current menu. The LastMenu command selects the previous menu.

Menus are organized internally as a hierarchy, where menus can refer to other menus. A special menu, MainMenu, accessible via the 🟦 A, contains all other menus.

Menus can contain up to 18 entries at once, 6 being directly accessible, 6 more being shown when using the 🟨 key, and 6 more with 🟦. Three rows of functions are shown on screen, with the active row highlighted.

A long press on a function key invokes the on-line help for the associated function.

When a menu contains more than 18 entries, then the F6 function key turns into a ▶︎, and 🟨 F6 turns into . These keys can be used to navigate across the available menu entries. This replaces the NXT and PREV keys on HP calculators.

The VariablesMenu is used to access global varibales. It is invoked using the H key, which is labeled RCL on SwissMicros hardware. This menu is special in the sense that:

  • Selecting an entry evaluates that menu entry, for example to run a program

  • The 🟨 function recalls its name without evaluating it.

  • The 🟦 function stores into the variable.

Differences with other RPLs

Multiple implementations of RPL exist, most of them from Hewlett-Packard. A good reference to understand the differences between the various existing implementations from HP is the HP50G Advanced User's Reference Manual.

There are a number of intentional differences in design between DB48X and the HP48, HP49 or HP50G's implementations of RPL. There are also a number of unintentional differences, since the implementation is completely new.

User interface

  • DB48X features an extensive built-in help system, which you are presently using. Information for that help system is stored using a regular markdown file named /HELP/DB48X.md, stored in the calculator's flash storage.

  • DB48X features auto-completion for commands while typing, through the Catalog key (CatalogMenu).

  • Many RPL words exist in short and long form, and a user preference selects how a program shows. For example, the Negate command, which the HP48 calls NEG, can display, based on user preferences, as NEG, neg, Neg or Negate. In the help, it will be shown as Negate (NEG).

  • The DB48X dialect of RPL is not case sensitive, but it is case-respecting. For example, if your preference is to display built-in functions in long form, typing inv or INV will show up as Invert in the resulting program. This means that the space of "reserved words" is larger in DB48X than in other RPL implementations. Notably, on HP's implementations, DUP is a keyword but you can use DuP as a valid variable name. This is not possible in DB48X.

  • The saving of the stack arguments for the LastArg command is controled independently by two distinct settings, SaveLastArg and SaveLastArgInPrograms. The first one controls if LastArg is saved for interactive operations, and is enabled by default. The second one controls if LastArg is saved before executing commands while running a program or evaluating an expression, and is disabled by default. This impacts commands that evaluate programs, such as ROOT. On the HP48, LastArg after running ROOT interactively gives arguments used by some operation within ROOT, whereas on DB48X with the default settings, it returns the arguments to ROOT.

Representation of objects

  • Internally, the calculator deals with various representations for numbers. Notably, it keeps integer values and fractions in exact form for as long as possible to optimize both performance and memory usage. This is somewhat similar to what the HP49 and HP50 implemented, where there is a difference between 2 (where TYPE returns 28) and 2. (where TYPE return 0).

  • The calculator features at least 3 floating-point precisions using 32-bit, 64-bit and 128-bit respectively, provided by the DMCP's existing Intel Binary Decimal Floating-Point library. The 128-bit format gives the calculator 34 significant digits of precision, like the DM42. DB48X may support other formats in the future, like the arbitrary-precision floating-point found in newRPL. The Precision command (in the DisplayModesMenu) can be used to select the precision for arithmetic operations.

  • Based numbers with an explicit base, like #123h keep their base, which makes it possible to show on stack binary and decimal numbers side by side. Mixed operations convert to the base in stack level X, so that #10d #A0h + evaluates as #AAh. Based numbers without an explicit base change base depending on the Base setting, much like based numbers on the HP48.

  • The storage of data in memory uses a denser format than on the HP48. Therefore, objects will almost always use less space on DB48X. Notably, the most frequently used functions and data types consume only one byte on DB48X, as opposed to 5 nibbles (2.5 bytes) on the HP48.

  • Numerical equality can be tested with =, whereas object equality is tested using ==. For example, 0=0.0 is true, but 0==0.0 is false, because 0 is an integer whereas 0.0 is a floating-point.

Alignment with SwissMicros calculators

  • DB48X will borrow to the DM-42 the idea of special variables for settings, which are variables with a special meaning. For example, the Precision special variable is the current operating precision for floating point, in number of digits. While there is a SetPrecision command, it is also possible to use 'Precision' STO. This does not imply that there is an internal Precision variable somewhere. Special variables will be available for most settings in a later revision of the firmware.

  • The DB48X also provides full-screen setup menus, taking advantage of the DM42 existing system menus. It is likely that the same menu objects used for softkey menus will be able to control system menus, with a different function to start the interaction.

  • The whole banking and flash access storage mechanism of the HP48 will be replaced with a system that works well with FAT USB storage. It should be possible to directly use a part of the flash storage to store RPL programs, either in source or compiled form.

List operation differences

The application of a same operation on arrays or matrices has never been very consistent nor logical across RPL models from HP.

  • On HP48 and HP50, { 1 2 3 } 4 + gives {1 2 3 4}. However, { 1 2 3} 4 * gives a type error on the HP48 but applies the operation to list elements on the HP50, yielding { 4 8 12}.

  • For arrays, [ 1 2 3 ] 4 + fails on both the HP48 and HP50, but [ 1 2 3 ] 4 * works.

  • The HP50 has a MAP function, which works both for list and matrices. [ 1 2 3 ] « 3 + » will return [ 4 5 6 ], and { 1 2 3 } « 3 * » will return { 3 6 9 }. That function has no direct equivalent on the HP48.

DB48X considers lists as bags of items and treat them as a whole when it makes sense, whereas arrays are focusing more on the values they contain, and will operate on these items when it makes sense. Therefore:

  • { 1 2 3 } 4 + gives { 1 2 3 4 }, { 1 2 3 } 2 - gives { 1 3 } (not yet implemented), and { 1 2 3 } 3 × gives { 1 2 3 1 2 3 1 2 3 }. The ÷ operator is equivalent to the ListDivide function, and partitions a list in chunks of the given size and returns the number of partitions so generated (the last partition being possibly shorter), i.e. { 1 2 3 4 5 } 2 ÷ will generate {1 2} {3 4} {5} 3 on the stack (this is not yet implemented).

  • [ 1 2 3 ] 4 + gives [ 5 6 7 ], [ 1 2 3 ] 2 - gives [ -1 0 1 ], [ 1 2 3 ] 3 × gives [ 3 6 9 ] and [ 1 2 3 ] 5 ÷ gives [ 1/5 2/5 3/5 ].

Vectors and matrices differences

  • On DB48X, vectors like [ 1 2 3 ] are very similar to lists. The primary difference is the behavior in the presence of arithmetic operators. On lists, addition is concatenation, e.g. { 1 2 3} { 4 5 6} + is { 1 2 3 4 5 6 }, whereas on vectors represents vector addition, e.g. [1 2 3] [4 5 6] + is [5 7 9]. However, unlike on the HP original implementation, a vector can contain any type of object, so that you can do [ "ABC" "DEF" ] [ "GHI" "JKL" ] + and obtain [ "ABCGHI" "DEFJKL" ].

  • Size enforcement on vectors only happens during these operations, not while you enter vectors from the command line. It is legal in DB48X to have a non-rectangular array like [[1 2 3] [4 5]], or even an array with mixed objects like [ "ABC" 3 ]. Size or type errors on such objects may occur if/when arithmetic operations are performed.

  • In particular, a matrix is nothing but a vector of vectors. DB48X also supports arrays with dimensions higher than 2, like [[[1 2 3]]].

  • As a consequence, The GET and GETI functions work differently on matrices. Consider a matrix like [[ 7 8 9 ][ 4 5 6 ][ 1 2 3 ]]. On the HP48, running 1 GET on this object gives 7, and the valid range of index values is 1 through 9. On DB48X, that object is considered as an array of vectors, so 1 GET returns [7 8 9]. This is intentional. The behavior of { 1 1 } GET is identical on both platforms, and is extended to multi-dimensional arrays, so that [[[4 5 6]]] { 1 1 2 } GET returns 5.

  • Matrices and vectors can contain integer values or fractions. This is closer to the HP50G implementation than the HP48's. In some cases, this leads to different results between the implementations. If you compute the inverse of [[1 2 3][4 5 6][7 8 9] on the HP48, you get a matrix with large values, and the HP48 finds a small, but non-zero determinant for that matrix. The HP50G produces a matrix with infinities. DB48X by default produces a Divide by zero error.

  • DB48X accept matrices and vectors as input to algebraic functions, and returns a matrix or vector with the function applied to all elements. For example, [a b c] sin returns [ 'sin a' 'sin b' 'sin c' ].

  • Similarly, DB48X accept operations between a constant and a vector or matrix. This applies the same binary operation to all components of the vector or matrix. [ a b c ] x + returns [ 'a+x' 'b+x' 'c+x' ]. Consistent with that logic, inv works on vectors, and inverts each component, so that [1 2 3] inv gives [1/1 1/2 1/3].

Unicode support

DB48X has almost complete support for Unicode, and stores text internally using the UTF-8 encoding. The built-in font has minor deviations in appearance for a few RPL-specific glyphs.

Overall, a text file produced by DB48X should appear reliably in your favorite text editor, which should normally be GNU Emacs. This is notably the case for state files with extension .48S which you can find in the STATE directory on the calculator.

Help

The DB48X project includes an extensive built-in help, which you are presently reading. This help is stored as a HELP/DB48X.md file on the calculator. You can also read it from a web browser directly on the GitHub page of the project.

The Help command makes it possible to access the built-in help in a contextual way. It is bound to 🟦 +. If the first level of the stack contains a text corresponding to a valid help topic, this topic will be shown in the help viewer. Otherwise, a help topic corresponding to the type of data in the stack will be selected.

The DB48X help viewer works roughly similarly to the DM42's, but with history tracking and the ability to directly access help about a given function by holding a key for more than half a second.

To navigate the help on the calculator, use the following keys:

  • The soft menu keys at the top of the keyboard, references as F1 through F6, correspond to the functions shown in the six labels at the bottom of the screen.

  • While the help is shown, the keys ◀︎ and ▶︎ on the keyboard scroll through the text.

  • The F1 key returns to the Home (overview).

  • The F2 and F3 keys (labels Page▲ and Page▼) scroll the text one full page at a time.

  • The F4 and F5 keys (labels Link▲ and Link▼) select the previous and next link respectively. The keys ÷ and 9 also select the previous link, while the keys × and 3 can also be used to select the next link.

  • The F6 key correspond to the ←Menu label, and returns one step back in the help history. The key achieves the same effect.

  • To follow a highlighted link, click on the ENTER key.

Acknowledgements and credits

DB48X is Free Software, see the LICENSE file for details. You can obtain the source code for this software at the following URL: https://github.com/c3d/DB48X-on-DM42.

Authors

This software is (C) 2022-2023 Christophe de Dinechin and the DB48X team.

Additional contributors to the project include:

  • Camille Wormser
  • Jeff, aka spiff72

The authors would like to acknowledge

This work was placed by Christophe de Dinechin under the patronage of Carlo Acutis

Hewlett and Packard

Hand-held scientific calculators changed forever when Hewlett and Packard asked their engineers to design and produce the HP35, then again when their company introduced the first programmable hand-held calculator with the HP65, and finally when they introduced the RPL programming language with the HP28.

Christophe de Dinechin, the primary author of DB48X, was lucky enough to meet both Hewlett and Packard in person, and this was a truly inspiring experience. Launching the Silicon Valley is certainly no small achievement, but this pales in comparison to bringing RPN and RPL to the world.

The Maubert Team

Back in the late 1980s and early 1990s, a team of young students with a passion for HP calculators began meeting on a regular basis at or around a particular electronics shop in Paris called "Maubert Electronique", exchanging tips about how to program the HP28 or HP48 in assembly language or where to get precious technical documentation.

It started with Paul Courbis, who carefully reverse-engineered and documented the internals of RPL calculators, encouraging his readers to boldly cut open these wonderful little machines to solder IR receivers acting as makeshift PC connection tools, or to waste countless hours debugging video games.

There were more serious efforts as well, notably the HP48 Metakernel, which completely reinvented the HP48 user interface, making it both much faster and better. It is fair to see DB48X as a distant descendent from such efforts. The Metakernel was the work of many now well-known names in the HP community, such as Cyrille de Brébisson, Jean-Yves Avenard, Gerald Squelart and Étienne de Foras. Many of these early heroes would go on to actually change the history of Hewlett-Packard calculators for the better.

The original author of DB48X, Christophe de Dinechin, was part of this loose team, focusing on cross-development tools, which he used at the time to write several games for the HP48, notably PacMan or Lemmings clones. If DB48X exists, it's largely because of that community.

HP Museum

The HP Museum not only extensively documents the history of RPN and RPL calcuators, it also provides a very active forum for calculator enthusiasts all over the world.

HPCalc

Much of the work from early enthusiasts can still be found on hpcalc.org to this day.

Back in the 1990s, long before Internet was widely available, HP48 programs were busily swapped over floppy disks, or propagated from machine to machine using the built-in infrared ports. This may have been the first case of large-scale viral distribution of software. This is probably the reason why all this software. which originated from all over the world, can still be downloaded and used today.

newRPL project

newRPL is a project initiated by Claudio Lapilli to implement a native version of RPL, initially targeting ARM-based HP calculators such as the HP50G.

DB48X inherits many ideas from newRPL, including, but not limited to:

  • Implementing RPL natively for ARM CPUs
  • Adding indicators in the cursor to indicate current status
  • Integrating a catalog of functions to the command line

A first iteration of DB48X started as a branch of newRPL, although the current implementation had to restart from scratch due to heavy space constraints on the DM42.

WP43 and C47 projects

The DB48X took several ideas and some inspiration from the WP43 and C47 projects.

Walter Bonin initiated the WP43 firwmare for the DM42 as a "superset of the legendary HP42S RPN Scientific".

C47 (initially called C43) is a variant of that firmware initiated by Jaco Mostert, which focuses on compatibility with the existing DM42, notably with respect to keyboard layout.

DB48X borrowed at least the following from these projects:

  • The very idea of writing a new firmware for the DM42
  • The idea of converting standard Unicode TrueType fonts into bitmaps (with some additional contributions from newRPL)
  • How to recompute the CRC for QSPI images so that the DM42 loads them, thanks to Ben Titmus
  • At least some aspects of the double-shift logic and three-level menus
  • The original keyboard layout template and styling, with special thanks to DA MacDonald.

SwissMicros DMCP

SwissMicros offers a range of RPN calculators that emulate well-known models from Hewlett-Packard. This includes the DM42, which is currently the primary target for the DB48X firmware.

Special thanks and kudos to Michael Steinmann and his team for keeping the shining spirit of HP RPN calculators alive.

The DM42 version of the DB48X software relies on SwissMicro's DMCP SDK, which is released under the following BSD 3-Clause License:

Copyright (c) 2015-2022, SwissMicros All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Intel Decimal Floating-Point Math

Floating-point computations in DB48X take advantage of Intel's decimal floating-point math library, which is released with the following end-user license agreement:

Copyright (c) 2018, Intel Corp.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, his list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Introduction to RPL

The original RPL (Reverse Polish Lisp) programming language was designed and implemented by Hewlett Packard for their calculators from the mid-1980s until 2015 (the year the HP50g was discontinued). It is based on older calculators that used RPN (Reverse Polish Notation). Whereas RPN had a limited stack size of 4, RPL has a stack size only limited by memory and also incorporates programmatic concepts from the Lisp programming language.

The first implementation of RPL accessible by the user was on the HP28C, circa 1987, which had an HP Saturn processor. More recent implementations (e.g., HP49, HP50g) run through a Saturn emulation layer on an ARM based processor. These ARM-based HP calculators would be good targets for a long-term port of DB48X.

DB48X is a fresh implementation of RPL on ARM, initially targetting the SwissMicros DM42 calculator. This has implications on the design of this particular implementation of RPL.

The RPL stack

The RPL stack can grow arbitrarily in size.

By convention, and following RPN usage, this document gives the names X, Y, Z and T to the first four levels of the stack. This is used to describe the operations on the stack with synthetic stack diagrams showing the state of the stack before and after the operation.

For example, the addition of two objects in levels 1 and 2 with the result deposited in stack level 1 can be described in synthetic form using the following stack diagram:

Y XY+X

The duplication operation Duplicate (DUP) can be described in synthetic form using the following synthetic stack diagram:

XX X

Algebraic mode

Unlike earlier RPN calculators from Hewlett-Packard, RPL calculators from HP includes complete support for algebraic objects written using the standard precedence rules in mathematics. This gives you the best of both worlds, i.e. the keyboard efficiency of RPN, requiring less keystrokes for a given operation, as well as the mathematical readability of the algebraic notation. Better yet, it is possible and easy to build an algebraic expression from RPN keystrokes. These nice properties are also true for DB48X.

In RPL, algebraic expressions are placed between ticks. For example, '2+3×5' will evaluate as 17: the multiplication 3×5, giving 15, is performed before the addition 2+15, which gives 17. An algebraic expression can also be symbolic and contain unevaluated variables. For example, 2+x is a valid algebraic operation. If, having this expression on the stack, you type 3 and then hit the × key, you will end up with (2+x)×3, showing how the algebraic expression was built from RPN keystrokes.

Algebraic expressions are not evaluated automatically. The R/S key (bound to the Evaluate function) will compute their value as needed. On the DB48X keyboard overlay, this key is also marked as = for that reason.

Rich data types

Since introducing the first scientific pocket calculator, the HP-35, in 1972, and with it the reverse polish notation (RPN), Hewlett-Packard perfected its line-up for decades. This led to such powerhouses pocket computers such as as the HP-41C series, or tiny wonders of pocket efficiency such as the HP-15C. Many of these calculators, including the models we just cited, were capable of advanced mathematics, including dealing with complex numbers, matrix operations, root finding or numeric integration.

Then in 1986, everything changed with the HP-28C, which introduced a new user interface called RPL. While the most evidently visible change was an unlimited stack, what instantly made it both more powerful and easier to use than all its RPN predecessors was the introduction of data types. Every value on the stack, instead of having to be a number, could be a text, a name or an equation. This made operations completely uniform irrespective of the data being operated on. The same + operation that adds numbers can also add complex numbers, vectors, matrices, or concatenate text. The exact same logic applies in all case. This solved a decade-long struggle to extend the capabilities of pocket calculators.

For example, whereas the HP-41C had some support for text, with an "Alpha" mode and an alpha register, text operations were following their own logic, with for example ARCL and ASTO dealing with at most 6 characters at a time, because they were artificially fitted in a register designed to hold a numerical value. Dealing with complex numbers on the HP-41C was similarly clunky. Even the HP-15C, which had built-in support for complex numbers, remained a bit awkward to use in "complex mode" because its display could only show one half of a complex number, e.g. the real or imaginary part. Similarly, matrix or statistic operations had non-obvious interactions with numbered data registers.

All this was solved with RPL, because now a complex number, a matrix or a text would occupy a single entry on the stack. So whereas adding two integers would require a sequence like 1 ENTER 2 + like in RPN, a very similar sequence would add two texts: "ABC" ENTER "DEF" +, and the exact same logic would also add two vectors in [1 2 3] ENTER [4 5 6] +.

DB48X adopts this extremely powerful idea, with a focus on making it as efficient as possible for interactive calculations as well as for custom programmed solution.

Quickstart guide

This quickstart guide will rapidly give you an overview of the capabilities of DB48X, and show you how to use it efficiently.

Installation process

Installation process

Downloading the software

Connecting the calculator to a computer

Setup menu system (firmware menus)

Exposing internal storage as a USB disk

Copying DB48X installation files

Copying DM42 installation files

Installing the DB48X QSPI file

Installing the DB48X program file

Switching between DM42 and DB48X

Checking that the DM42 firmware works with the DB48X QSPI file

Running the DB48X program

Running the DM42 program

Saving and restoring DM42 state

Saving and restoring DB48X state

Shared state between the two programs

Operations on whole numbers

Demo of v0.4.8

Entering whole numbers

Arithmetic on integers

Changing the sign of a number with +/-

Exact division

Computing on large numbers: 2^40, 25!

Separators to make large numbers more readable

Built-in functions: example of 1/x

Using the shift key

Primary function: 1/x

First shifted function: y^x and square

Second shifted function: Help

The shift annunciator

Invoking the on-line Help

Long-press on a function key

Moving up and down

Following links

Navigating back to a previous topic

Exiting the on-line help

Contextual help

The annunciator area

Battery level

USB vs. battery power

Showing or hiding the date and time

Current state file name

Future direction

Decimal values

Entering a decimal number

Entering a number in scientific notation with EEX

Arithmetic on decimal values

Arithmetic on fractions

Using EEX to cycle between decimal and fraction

Separators for the fractional part

Live separators during number editing

Soft keys and menus

Soft keys

The DISP menu

Effect of shift state on the menu

Submenus

Menu history (Last Menu)

Displaying decimal values

Standard display mode

FIX display mode

Switching to scientific mode

Digits to show for small values

SCI display mode

ENG display mode

SIG display mode

Emulating HP48 standard display

Scientific functions

Square and power

Square root and xroot

Exponential and Log

Exponential and log in base 10

DM42 layout difference: EXP LN instead of LOG LN

Trigonometric functions and their inverse

Functions in menus: example of hyperbolic functions

Using an infinite stack

Showing multiple stack levels

Result vs. other levels

When a result is too large

An example of complicated calculation - The Mach number benchmark

How to proceeed with that computation

Correcting an error in the middle

Saving results for later with Duplicate

Dropping results and cleaning up with Drop

LastArg to recall last arguments

Undo to restore previous stack state

The command line

Editing an object on the stack with Right key

Moving left and right on the command line

Repeating keys: Insert, left, right, delete

Inserting characters in the middle

Deleting characters left and right

Space key on R/S

Command line: entering three numbers at once

The editor menu

Selecting the editor menu

Moving word by word

Moving to beginning and end

Selecting text

Cut, copy and paste

Incremental search

Search and replace

Command line history

Recalling a previous command line

Optimization of command-line space

Exiting the command line

Entering letters and symbols

Alpha mode with Shift Enter

Alpha mode with Long Shift

Transient Alpha mode, upper and lowercase

Shift on digits and operations while in Alpha mode

Shifted characters

2nd shifted characters

White cursor for Alpha mode

C and L cursor indicators in text

Entering names

Executing a command by typing its name

Catalog with + key

Auto-completion

Example: VERSION

What happens if the name is not a command

Multi-line text editor

Multi-line Text editor

Up and down by shifting

Repeat up and down by holding key

Entering text

Entering text with 2nd shift ENTER

The C and L cursors

Mixed operations, e.g. adding text

Multiplying text by a number

Entering an algebraic expression

The ' () key

Entering an expression

Evaluating an expression with =

Cursor in algebraic mode

Comparing the sin key in direct and algebraic mode

Entering parentheses

Automatic elimination of parentheses

Symbolic algebraic expressions

Performing RPN operations on algebraic expressions

Automatic simplification of 0+x, 1*x, etc.

The Tools menu

Tools menu on empty stack

Tools menu for a decimal value

Tools menu for an integer

Tools menu for a text

Tools menu for an expression

Computations on complex numbers

The complex menu

Entering numbers in rectangular form

Entering numbers in polar form

Switching between polar and rectangular with EEX

Arithmetic on complex numbers

Exact angles and exact computations: 2<45 * 3<90 ^ 8

Functions on complex numbers, e.g. sin and log.

Effect of angle mode on display in polar form

Computations on vectors

Entering a vector

The M cursor

Adding and subtracting vectors

Component-wise multiplication and division

Operations between vector and a constant

Component-wise functions: 1/x

The tools menu on vectors

Computing the norm of a vector

The Matrix menu

Computations on matrices

Entering a matrix

Adding and subtracting matrices

Multiplication and division by a constant

Multiplying square matrices

Multiplying a matrix and a vector

Computing a determinant

Computing an inverse with 1/x

Advanced matrix operations

Matrix of complex numbers

Symbolic matrix

Inverse and determinant of 2x2 symbolic matrix

Entering data in lists

Entering a list

Adding elements to a list

Applying a function to a list

Repeating a list (multiply)

Lists containing lists

Computations with based numbers

Entering based numbers

Entering hexadecimal directly with A-F

Logical operations

Setting the word size

Changing to common bases (2, 8, 10, 16)

Changing to an arbitray base

Entering number in arbitrary base

The tools menu on based number

Binary operations

Emulating a 16-bit or 256-bit CPU

The Cycle key on based numbers

Adding a suffix to force a base (DM32 only)

Unit objects

Entering a value with a unit

The units menus

Applying a unit

Converting to a unit

Dividing by a unit

Entering a program

Computing a VAT

Evaluating a program with Evaluate

Modifying a program with LastArg

Modifying a program with Undo

Modifying a program with command-line history

The three roles of the R/S key: Space, =, EVAL

Storing values in global variables

Storing a value in a new variable 'VATRate'

Evaluating a variable

Case insensitivity

Naming a variable on the command line

Using quotes to avoid evaluation

Overwriting a variable value

Expressions containing variables

Storing and modifying programs

Creating a new VAT command

Evaluating a program by name

Evaluting a program from variables menu

Taking input and computing output

The variables menu

Showing the variables menu

Evaluating a variable with F1

Recalling a variable with shift F1

Storing in an existing variable with xshift F1

Rationale for the difference with HP48

Using variables menu while editing a program

Menus with too many entries

Adding more variables overflows

Going from 6 to 7 entries

No next key, using F6 and shift F6 for next and previous

Saving your state to disk

The system menu

Saving the calculator state

Restoring another state

Merging states

Returning to the calculator

Saving state quickly with xshift-EXIT

Plotting a function

Plotting a wave function sin(x * a) * cos(x * b)

Plotting a polar function

Plotting a parameteric function

Drawing two functions on the same screen

Changing line width

Changing line patterm

The numerical solver

Solving an equation

Expressions that must be zero

Equations A=B

Solving for different variables

Numerical integration

Integrating x^2 from 0 to 1 (exact results)

What happens with 0.0 to 1.0

Integration 1/x from 2 to 22

Comparing with LN(2) - LN(2)

Symbolic expression manipulation

Collecting terms

Expanding terms

General expression rewriting facility

Local variables

Why use local variables

Inserting local variables in a program

Inserting local variables in equations

Localized number display preferences

Changing the decimal separator

Changing the spacing for numbers

Changing the character used for spacing

User interface preferences

Square and rounded menu styles

3-level, 1-level and flat menu styles

Changing result font size

Changing stack font size

Changing editor font size

Changing multi-line editor font size

Comparisons and tests

Truth: True, False, 0, 1

Equality tests

Differences between = and ==

Relational operators

Logical operations (AND, OR, NOT)

More sophisticated programming

Testing with IF THEN ELSE END

Conditional expression with IFTE

Counted loop with START NEXT

Stepping loop with START STEP

Named loop with FOR NEXT

Named loop with FOR STEP

WHILE conditional loop

UNTIL conditional loop

Enjoy the calculator!

Types

DB48X, like HP RPL, supports a wide variety of data types.

Integers

The DB48X version of RPL distinguishes between integer values, like 123, and decimal values, like 123. Integer values are represented internally in a compact and efficient format, saving memory and making computations faster. All values between -127 and 127 can be stored in two bytes. All values between -16383 and 16383 in three bytes.

Integers can be as large as memory permits.

Big integers

The DB48X version of RPL can perform computations on arbitrarily large integers, limited only by available memory, enabling for example the exact computation of 100! and making it possible to address problems that require exact integer computations, like exploring the Syracuse conjecture.

Decimal numbers

Decimal numbers are used to represent values with a fractional part. DB48X supports three decimal numbers, using the 32-bit, 64-bit and 128-bit binary decimal representation. In memory, all decimal numbers use one additional byte: a 32-bit decimal number uses 5 bytes, a 128-bit binary decimal number uses 17 bytes.

The 32-bit format offers a 7 digits mantissa and has a maximum exponent of 96. The 64-bit format offers a 16 digits mantissa and has a maximum exponent of 384. The 128-bit format offers a 34 digits mantissa and a maximum exponent of 6144.

The Precision command selects the default precision.

Note that a future implementation of DB48X is expected to feature variable-precision decimal numbers similar to newRPL.

Based numbers

Based numbers are used to perform computations in any base. The most common bases used in computer science, 2, 8, 10 and 16, have special shortcuts. The Bases Menu list operations on based numbers.

Like integers, based numbers can be arbitrary large. However, operations on based numbers can be truncated to a specific number of bits using the STWS command. This makes it possible to perform computations simulating a 16-bit or 256-bit processor.

Complex numbers

Complex numbers can be represented in rectangular form or polar form. The rectangular form will show as something like 2+3 on the display, where 2 is the real part and 3 is the imaginary part. The polar form will show as something like 1∡90° on the display, where 1 is the modulus and 90° is the argument. The two forms can be mixed and matched in operations. The calculator typically selects the most efficient form for a given operation.

Available operations on complex numbers include basic arithmetic, trigonometric, logarithms, exponential and hyperbolic functions, as well as a few specific functions such as conj or arg. These functions are available in the Complex Menu.

Expressions

Algebraic expressions and equations are represented between quotes, for example X+1 or A+B=C. Many functions such as circular functions, exponential, logs or hyperbolic functions can apply to algebraic expressions.

An expression that contains an equal sign, e.g. sin X + 1 = cos X, is called an equation. It can be given as an argument to the solver.

Lists

Lists are sequence of items between curly braces, such as { 1 'A' "Hello" }. They can contain an arbitrary number of elements, and can be nested.

Operations such as sin apply to all elements on a list.

Vectors and matrices

Vector and matrices represent tables of numbers, and are represented between square brackets, for example [1 2 3] for a vector and [[1 2] [3 4] for a 2x2 matrix.

Vector and matrices follow their own arithmetic rules. Vectors are one-dimensional, matrices are two-dimensional. DB48X also supports tables with a higher number of dimensions, but only offers limited operations on them.

DB48X implements vector addition, subtraction, multipplication and division, which apply component-wise. Multiplication and division are an extension compared to the HP48.

DB48X also implements matrix addition, subtraction, multiplication and division. Like on the HP48, the division of matrix A by matrix B is interpreted as left-multiplying A by the inverse of B.

As another extension, algebraic functions such as sin apply to all elements in a vector or matrix in turn.

Units

Unit objects represent values with an associated unit. They are represented using the _ operator, e.g. 1_km/s, although on display this operator is shown as a thin space, e.g. 1km/s.

Units as implemented in DB48X are modernized compared to what the HP48 implements, and differ from the HP RPL implementation in the following ways:

  • Add recent SI prefixes, Z (zetta), Y (yotta), R (ronna) and Q (quetta) for large scale, z (zepto), y (yocto), r (ronto) and q (quecto) for small scale.

  • Take into account the impact on unit conversions of the revised 2023 definition of the foot.

  • Use exact (fraction-based) conversions wherever possible. This notably matters for the conversions of pre-2023 US Survey units, where the ratio is 1_ft = 1200/3937_m, which is not well represented using decimal values.

  • Add computer-related units, like the byte, the bit, the baud, as well as a menu supporting these units.

  • In order to support the computer-related units better, also recognize the power-of-two variants, e.g. 1_kiB is 1024_B. Also recogize the K prefix in addition to k.

Units file

The built-in units can be overriden by your own set of units, which is defined in a CSV file called config/units.csv in the calculator. CSV stands for "Comma separated values, and is a common interchange format for spreadsheet data.

Here is an example of file that would let you have a units menu called Money to convert between various monetary units:

"Money" "USD", "1_USD" "EUR", "1.07_USD" "GBP", "1.24_USD" "CAD", "0.73_USD" "AUD", "0.65_USD" "CHF", "1.11_USD"

  • All values must be placed between quotes. Separators between text values are mostly ignored.

  • Rows in a file containing a single value denote unit menus, unless the value begins with an = sign.

  • Rows in a file containing two ore more values denote unit menu entries, which will be added to the previous menu.

  • The first column in these rows give the name of the unit as shown in the menu.

  • The second column in these rows gives the definition of the unit.

  • The definition should be reduced to = if the first column contains what would be a valid unit expression. For example, to place km/h in a menu, use "km/h", "=" since km can be deduced from existing unit m using the standard "kilo" unit prefix, and h is an existing unit.

A unit where the value is 1 of the same unit is a base unit. This is the case for USD in the example above, which is considered the base units for monetary exchanges. Units that refer to the same base unit can be converted with one another. For example, you can convert between GBP and AUD because they both have the same USD base unit.

The commands ShowBuiltinUnits and HideBuiltinUnits indicate if the built-in uits should be shown after the units loaded from the file. The default is that when a units file is present, the built-in units are hidden. This only affects the menus. Built-in units can always be used in expressions if they are typed manually. However, units loaded from file will be looked up first, so that a built-in unit can be overriden by the units file, which can be useful if a definition changes like the US Survey foot changed on January 1st, 2023.

If you build a units file, it is recommended that you do not exceed 17 unit submenus so that all unit categories fit on a single screen.

Cycle command customization

The menu name "=Cycle" is reserved to define sequences of units that the Cycle command (bound to the EEX key) will recognize as special. For example, you can ensure that mm and in convert to one another as follows:

"=Cycle" "in", "mm" "mm", "in" "USD", "EUR" "EUR", "CHF" "CHF", "USD"

If you do provide a Cycle customization for a unit, other normal behaviours of the Cycle command for units are disabled, notably conversion between various relevant scales and conversion between fractions and decimal. To force a particular conversion to happen in decimal, you can override the definition of the corresponding unit in the units file, for example:

"in", "25.4_mm"

Release notes

Release 0.4.9 - Full support for units (All Saints Edition)

This release focuses on support for units, but also adds a large number of other fixes and improvements.

New features

  • Power-off message indicating low-battery situation (#521)
  • Add ConvertToUnixPrefix command and SI prefix menu keys (#513)
  • Recognize all units that exist in the HP48, and a few more (#491)
  • UFACT (FactorUnit) command (#512)
  • Unit simplification, e.g. turn 1_m^2*s/s/m into 1_m (#506)
  • Converting unity units to numbers (#502)
  • →Unit command (#501)
  • UnitValue (UVAL) command (#493)
  • Implement "kibibytes" (KiB) and power-of-two SI prefixes (#492)
  • Unit arithmetic (#481)
  • Add B->R and R->B to BasesMenu (#488)
  • Implement term reordering capability in rewrite (#484)
  • BaseUnits (UBase) command (#483)
  • Unit parsing for complex units, e.g. 1_cm^2 (#482)
  • Unit arithmetic (#481) including automatic conversions (#480)
  • Convert command (#480)
  • Implement the Cycle command for unit objects
  • Add character for angstroem (#477)
  • Add Merge state to State system menu (#475)
  • Use Unicode font to display the name of a program when executing it (#469)
  • Allow incremental search to find digits and Unicode (#468)
  • Add tool glyph to user interface font

Bug fixes

  • Do not parse symbols beyond input buffer (#524)
  • Parse unit menu entries as expressions, not symbols (#523)
  • Fix reduced-precision arithmetic (#521)
  • Do not parse empty denominator as zero, e.g. 2/s (#520)
  • Do not parse a fraction inside a power, e.g. X^2/3 (#519)
  • Convert fractions to decimal in numeric mode (#516)
  • Do not emit mantissa_error for valid numbers (#515)
  • Apply negation correctly on unit objects (#500)
  • Do not emit separator after trailing 0 in integer decimals (#489)
  • Do not emit extra spacing before decimal separator (#485)
  • Fix stack depth in one error case of evaluate_function()
  • Fix display of next/previous icons for large menus (#478)
  • Clear settings when loading a state (#474)
  • Fix separators in whole part of decimal numbers when setting is not 3 (#464)
  • Parse (sin x)²+(cos x)² correctly, as well as HP67 Mach example (#427)

Improvements

  • Rename equation as expression (#518) and labelText as label_text
  • Do not update LastArg except for command line (#511)
  • ToolsMenu: Connect units to the UnitsConversionMenu (#514)
  • Display unit using / and ·, e.g. 1_m·s^2/A (#507)
  • Show units menu for inverse units as mm⁻¹ (#503)
  • Display battery level more accurately, i.e. consider 2.6V "low" (#476)
  • No longer acccept empty equations or parentheses, e.g. 1+() (#487)
  • Make StandardDisplay mode obey MinimumSignificantDigits (#462)
  • Add algebraic evaluation function for easier evaluation in C++ code
  • Reimplement unit type as a derivative of complex (#471)
  • documentation: Use 🟨 and 🟦 for more commands (#467)
  • Swap Search and Copy commands in EditorMenu (#466)
  • STO stores variables at beginning of directory (#462)
  • documentation: Add quickstart guide, used for video recording
  • documentation: Add links to YouTube videos
  • documentation: Add release notes
  • documentation: Some typos and other improvements
  • documentation: Rework section on keyboard mappings

Implementation status

This section documents the implementation status for all HP50 RPL commands as listed in the HP50G Advanced Reference Manual. This is a strict superset of the HP48 implementation.

Implemented commands

The following is a list of the HP50 RPL commands which are implemented in DB48X.

Unimplemented commands

The following is a list of unimplemented HP50 RPL commands, which is a superset of the HP48

commands.

  • ABCUV
  • ACK
  • ACKALL
  • ACOS2S
  • ADDTMOD
  • ADDTOREAL
  • ALGB
  • AMORT
  • ANIMATE
  • ANS
  • APPLY
  • ARC
  • ARCHIVE
  • ARIT
  • ARRY→
  • →ARRY
  • ASIN2C
  • ASIN2T
  • ASN
  • ASR
  • ASSUME
  • ATAN2S
  • ATICK
  • ATTACH
  • AUGMENT
  • AUTO
  • AXL
  • AXM
  • AXQ
  • BAR
  • BARPLOT
  • BASIS
  • BAUD
  • BEEP
  • BESTFIT
  • BINS
  • BLANK
  • BOX
  • BUFLEN
  • C$
  • C2P
  • CASCFG
  • CASCMD
  • CASE
  • CEIL
  • CENTR
  • CF
  • %CH
  • CHINREM
  • CHOLESKY
  • CHOOSE
  • CHR
  • CIRC
  • CKSM
  • CLEAR
  • CLKADJ
  • CLOSEIO
  • CLΣ
  • CLUSR
  • CLVAR
  • CMPLX
  • CNRM
  • →COL
  • COL→
  • COL
  • COL+
  • COLCT
  • COLLECT
  • COLΣ
  • COMB
  • CON
  • COND
  • CONIC
  • CONLIB
  • CONST
  • CONSTANTS
  • CORR
  • COV
  • CR
  • CROSS
  • CSWP
  • CURL
  • CYCLOTOMIC
  • CYLIN
  • C→PX
  • DARCY
  • DATE
  • →DATE
  • DATE+
  • DDAYS
  • DECR
  • DEDICACE
  • DEF
  • DEFINE
  • DEGREE
  • DELALARM
  • DELAY
  • DELKEYS
  • DEPND
  • DERIV
  • DERVX
  • DESOLVE
  • DET
  • DETACH
  • DIAG→
  • →DIAG
  • DIAGMAP
  • DIFF
  • DIFFEQ
  • DISPXY
  • DISTRIB
  • DIV
  • DIV2
  • DIV2MOD
  • DIVIS
  • DIVMOD
  • DIVPC
  • dn
  • DOLIST
  • DOMAIN
  • DOSUBS
  • DOT
  • DRAW3DMATRIX
  • DROITE
  • DUPDUP
  • D→R
  • e
  • EDIT
  • EDITB
  • EGCD
  • EGV
  • EGVL
  • ENDSUB
  • EPSX0
  • EQNLIB
  • EQW
  • EQ→
  • ERASE
  • EULER
  • EXLR
  • EXP&LN
  • EXP2HYP
  • EXP2POW
  • EXPANDMOD
  • EXPFIT
  • EXPLN
  • EYEPT
  • F0λ
  • FACTOR
  • FACTORMOD
  • FACTORS
  • FANNING
  • FAST3D
  • FCOEF
  • FC?
  • FC?C
  • FDISTRIB
  • FFT
  • FILER
  • FINDALARM
  • FINISH
  • FLASHEVAL
  • FLOOR
  • FONT6
  • FONT7
  • FONT8
  • FONT→
  • →FONT
  • FOURIER
  • FP
  • FREE
  • FREEZE
  • FROOTS
  • FS?
  • FS?C
  • FXND
  • GAUSS
  • GBASIS
  • GCD
  • GCDMOD
  • GETI
  • GRAD
  • GRAMSCHMIDT
  • GRAPH
  • GREDUCE
  • GRIDMAP
  • →GROB
  • GROBADD
  • *H
  • HADAMARD
  • HALFTAN
  • HEAD
  • HEADER→
  • →HEADER
  • HERMITE
  • HESS
  • HILBERT
  • HISTOGRAM
  • HISTPLOT
  • HMS
  • HMS+
  • HMS→
  • →HMS
  • HORNER
  • IABCUV
  • IBASIS
  • IBERNOULLI
  • IBP
  • ICHINREM
  • IDN
  • IDIV2
  • IEGCD
  • IFFT
  • ILAP
  • IMAGE
  • INCR
  • INDEP
  • INFORM
  • INPUT
  • INT
  • INTEGER
  • INTVX
  • INVMOD
  • IP
  • IQUOT
  • IREMAINDER
  • ISOL
  • ISOM
  • ISPRIME?
  • I→R
  • JORDAN
  • KER
  • KERRM
  • KEY
  • KEYEVAL
  • →KEYTIME
  • KEYTIME→
  • KGET
  • LABEL
  • LAGRANGE
  • LANGUAGE→
  • →LANGUAGE
  • LAP
  • LAPL
  • LAST
  • LCD→
  • →LCD
  • LCM
  • LCXM
  • LDEC
  • LEGENDRE
  • LGCD
  • LIBEVAL
  • LIBS
  • lim
  • LIMIT
  • LIN
  • ΣLINE
  • LINFIT
  • LININ
  • LINSOLVE
  • LIST→
  • ∆LIST
  • ΠLIST
  • ΣLIST
  • LNAME
  • LNCOLLECT
  • LOCAL
  • LOGFIT
  • LQ
  • LR
  • LSQ
  • LU
  • LVAR
  • MAD
  • MAIN
  • MANT
  • MAP
  • ↓MATCH
  • ↑MATCH
  • MATHS
  • MATR
  • MAX
  • MAXR
  • MAXΣ
  • MCALC
  • MEAN
  • MENU
  • MENUXY
  • MERGE
  • MIN
  • MINEHUNT
  • MINIFONT→
  • →MINIFONT
  • MINIT
  • MINR
  • MINΣ
  • MITM
  • MKISOM
  • MODSTO
  • MODULAR
  • MOLWT
  • MROOT
  • MSGBOX
  • MSLV
  • MSOLVR
  • MULTMOD
  • MUSER
  • →NDISP
  • NDIST
  • NDUPN
  • NEWOB
  • NEXTPRIME
  • NIP
  • NOVAL
  • NSUB
  • NUM
  • NUMX
  • NUMY
  • OBJ→
  • OLDPRT
  • OPENIO
  • ORDER
  • P2C
  • PA2B2
  • PARITY
  • PARSURFACE
  • PARTFRAC
  • PCAR
  • PCOEF
  • PCONTOUR
  • PCOV
  • PDIM
  • PERINFO
  • PERM
  • PERTBL
  • PEVAL
  • PICK3
  • PICTURE
  • PINIT
  • PIX?
  • PIXOFF
  • PIXON
  • PKT
  • PLOT
  • PLOTADD
  • PMAX
  • PMIN
  • PMINI
  • POLYNOMIAL
  • POP
  • POS
  • POTENTIAL
  • POWEXPAND
  • POWMOD
  • PR1
  • PREDV
  • PREDX
  • PREDY
  • PREVAL
  • PREVPRIME
  • PRLCD
  • PROMPT
  • PROMPTSTO
  • PROOT
  • PROPFRAC
  • PRST
  • PRSTC
  • PRVAR
  • PSDEV
  • PSI
  • Psi
  • PTAYL
  • PTPROP
  • PUSH
  • PUT
  • PUTI
  • PVAR
  • PVARS
  • PVIEW
  • PWRFIT
  • PX→C
  • →Qπ
  • qr
  • QR
  • QUAD
  • QUOT
  • QUOTE
  • QXA
  • RAND
  • RANK
  • RANM
  • RATIO
  • RCEQ
  • RCI
  • RCIJ
  • RCLALARM
  • RCLF
  • RCLKEYS
  • RCLMENU
  • RCLVX
  • RCLΣ
  • RDM
  • RDZ
  • RE
  • RECN
  • RECV
  • REF
  • REMAINDER
  • RENAME
  • REORDER
  • REPL
  • RES
  • RESTORE
  • RESULTANT
  • REVLIST
  • RISCH
  • RKF
  • RKFERR
  • RKFSTEP
  • RL
  • RLB
  • RND
  • RNRM
  • ROMUPLOAD
  • ROW
  • ROW+
  • ROW→
  • →ROW
  • RPL>
  • RR
  • RRB
  • rref
  • RREF
  • RREFMOD
  • RRK
  • RRKSTEP
  • RSBERR
  • RSD
  • RSWP
  • RULES
  • R→D
  • R→I
  • SBRK
  • SCALE
  • SCALEH
  • SCALEW
  • SCATRPLOT
  • SCATTER
  • SCHUR
  • SCLΣ
  • SCONJ
  • SCROLL
  • SDEV
  • SEND
  • SEQ
  • SERIES
  • SERVER
  • SEVAL
  • SF
  • SHOW
  • SIDENS
  • SIGMA
  • SIGMAVX
  • SIGNTAB
  • SIMP2
  • SIMPLIFY
  • SINCOS
  • SINV
  • SIZE
  • SL
  • SLB
  • SLOPEFIELD
  • SNEG
  • SNRM
  • SOLVE
  • SOLVEQN
  • SOLVER
  • SOLVEVX
  • SORT
  • SPHERE
  • SR
  • SRAD
  • SRB
  • SRECV
  • SREPL
  • START
  • STD
  • STEQ
  • STIME
  • STOALARM
  • STOF
  • STOKEYS
  • STOVX
  • STO+
  • STO
  • STO*
  • STO/
  • STOΣ
  • STR→
  • STREAM
  • STRM
  • STURM
  • STURMAB
  • SUB
  • SUBST
  • SUBTMOD
  • SVD
  • SVL
  • SYSEVAL
  • SYLVESTER
  • SYST2MAT
  • %T
  • TABVAL
  • TABVAR
  • TAIL
  • TAN2CS2
  • TAN2SC
  • TAN2SC2
  • TAYLOR0
  • TAYLR
  • TCHEBYCHEFF
  • TCOLLECT
  • TDELTA
  • TESTS
  • TEVAL
  • TEXPAND
  • TEXT
  • TIME
  • →TIME
  • TINC
  • TLIN
  • TLINE
  • TMENU
  • TOT
  • TRACE
  • TRAN
  • TRANSIO
  • TRIG
  • TRIGCOS
  • TRIGO
  • TRIGSIN
  • TRIGTAN
  • TRN
  • TRNC
  • TRUNC
  • TRUTH
  • TSIMP
  • TSTR
  • TVARS
  • TVM
  • TVMBEG
  • TVMEND
  • TVMROOT
  • UFL1→MINIF
  • UNASSIGN
  • UNASSUME
  • UNBIND
  • UNPICK
  • UNROT
  • UTPC
  • UTPF
  • UTPN
  • UTPT
  • V→
  • →V2
  • →V3
  • VANDERMONDE
  • VAR
  • VARS
  • VER
  • VISIT
  • VISITB
  • VPOTENTIAL
  • VTYPE
  • *W
  • WIREFRAME
  • WSLOG
  • ΣX
  • ΣX2
  • ΣX^2
  • XCOL
  • XGET
  • XMIT
  • XNUM
  • XPON
  • XPUT
  • XQ
  • XRECV
  • XRNG
  • XSEND
  • XSERV
  • XVOL
  • XXRNG
  • ΣXY
  • ΣX*Y
  • ΣY
  • ΣY2
  • ΣY^2
  • YCOL
  • YRNG
  • YSLICE
  • YVOL
  • YYRNG
  • ZEROS
  • ZFACTOR
  • ZVOL
  • | (Where)
  • ?
  • Σ
  • Σ+
  • Σ–
  • % (Percent)
  •  (Store)
  • ; (Semicolon)

Additional commands

The following commands are unique to DB48X and are not found in any Hewlett-Packard RPL implementation.

Performance measurements

This sections tracks some performance measurements across releases.

NQueens (DM42)

Performance recording for various releases on DM42 with small option (which is the only one that fits all releases). This is for the same NQueens benchmark, all times in milliseconds, best of 5 runs, on USB power, with presumably no GC.

Version Time PGM Size QSPI Size Note
0.4.10+ 1205 651108 RPL stack runloop
0.4.10 1070 650116 Focused optimizations
0.4.9+ 1175 Range-based type checks
0.4.9+ 1215 Remove busy animation
0.4.9 1447 646028 1531868 No LastArgs in progs
0.4.8 1401 633932 1531868
0.4.7 1397 628188 1531868
0.4.6 1380 629564 1531868
0.4.5 1383 624572 1531868
0.4.4 1377 624656 1531868 Implements Undo/LastArg
0.4.3S 1278 617300 1523164 0.4.3 build "small"
0.4.3 1049 717964 1524812 Switch to -Os
0.4.2 1022 708756 1524284
0.4.1 1024 687444 1522788
0.4 998 656516 1521748 Feature tests 7541edf
0.3.1 746 618884 1517620 Faster busy 3f3ab4b
0.3 640 610820 1516900 Busy anim 4ab3c97
0.2.4 522 597372 1514292
0.2.3 526 594724 1514276 Switching to -O2
0.2.2 723 540292 1512980

NQueens (DM32)

Performance recording for various releases on DM32 with fast build option. This is for the same NQueens benchmark, all times in milliseconds, best of 5 runs. There is no GC column, because it's harder to trigger given how much more memory the calculator has. Also, experimentally, the numbers for the USB and battery measurements are almost identical at the moment. As I understand it, there are plans for a USB overclock like on the DM42, but at the moment it is not there.

Version Time PGM Size QSPI Size Note
0.4.10+ 1804 761252 RPL stack runloop
0.4.10 1803 731052 Focused optimizations
0.4.9 2156 772732 1534316 No LastArg in progs
0.4.8 2201 749892 1534316
0.4.7 2209 742868 1534316
0.4.6 2204 743492 1534316
0.4.5 2171 730092 1534316
0.4.4 2170 730076 1534316 Implements Undo/LastArg
0.4.3 2081 718020 1527092
0.4.2 2242 708756 1524284
0.4.1 2152 687500 1522788
0.4 Feature tests 7541edf
0.3.1
0.3
0.2.4
0.2.3

Collatz conjecture check

This test checks the tail recursion optimization in the RPL interpreter. The code can be found in the CBench program in the Demo.48S state. The HP48 cannot run the benchmark because it does not have integer arithmetic.

Timing on 0.4.10 are:

  • HP50G: 397.438s
  • DM32: 28.507s (14x faster)
  • DM42: 15.769s (25x faster)

Menus

Menus display at the bottom of the screen, and can be activated using the keys on the top row of the calculator. Menus can refer to other menus. The calculator keeps a history of the menus you visited previously, and you can return to an earlier menu with the BackMenu function.

Here are the main menus in DB48X, in alphabetical order.

MainMenu

The Main menu gives access to all the functions in your calculator, sorted by cathegory. It includes the following submenus:

  • Math: Mathematical operations
  • Symb: Symbolic operations
  • Units: Unit conversions
  • System: System configuration
  • Prog: Programming
  • Vars: User variables

MathMenu

The Math menu gives access to mathematical functions like SIN in your calculator. It includes the following submenus:

  • Arith: Arithmetic functions
  • Base: Based numbers
  • Trans: Transcendental functions
  • Stats: Statistics
  • Lists: List operations
  • Matrix: Matrices and vectors
  • Solve: Numerical solver

VariablesMenu (VARS)

The variables menu displays the variables in the current directory. It is a three row menu, where for each variable:

VariablesMenuExecute

Hitting the primary function in the Vars menu evaluates the corresponding variable.

VariablesMenuRecall

Hitting the first shifted function in the Vars menu will recall the corresponding variable on the stack.

VariablesMenuStore

Hitting the second shifted function in the Vars menu will store the top of stack in the corresponding variable.

ToolsMenu

The ToolsMenu maps to the A key (Σ+ on the original DM42 keyboard). It invokes a context-dependent menu adapted to the top level of the stack.

LastMenu

The LastMenu function (🟨 A), returns back in the history of past visited menus. The history contains up to 8 entries.

Operations with Angles

TAGDEG

Mark a number as an angle in degrees

TAGRAD

Mark a number as an angle in radians

TAGGRAD

Mark a number as an angle in grads (gons)

TAGDMS

Mark a number as an angle in DMS (DD.MMSS)

ANGTODEG

Convert an angle to degrees

ANGTORAD

Convert an angle to radians

ANGTOGRAD

Convert an angle to grads (gons)

ANGTODMS

Convert an angle to DMS (DD.MMSS)

TORECT

Convert vector or complex to cartesian coordinates

TOPOLAR

Convert vector or complex to polar coordinates

TOSPHER

Convert vector or complex to spherical coordinates

Arithmetic

+ (add)

Add two values.

Y XY+X

  • For integer, fractional, decimal or complex numbers, this performs the expected numerical addition. For example, 1 2 + is 3.
  • For equations and symbols, build a sum, eliminating zero additions if autosimplify is active.
  • For lists, concatenate lists, or add objets to a list. For example, { A } { B } + is { A B }, and { A B C } "D" + is { A B C "D" }.
  • For text, concatenate text, or concatenate the text representation of an object to an existing text. For example "X" "Y" + gives "XY", and "X=" 1 + gives "X=1".

- (sub)

Subtract two values

Y XY-X

  • For integer, fractional, decimal or complex numbers, this performs the expected numerical subtraction. For example, 1 2 - is -1.
  • For equations and symbols, build a difference, eliminating subtraction of 0 if autosimplify is active.

× (*, mul)

Multiply two values.

Y XY×X

  • For integer, fractional, decimal or complex numbers, this performs the expected numerical multiplication. For example, 3 2 * is 6.
  • For vectors, multiply individual elements (this is a deviation from HP48). For example, [ 1 2 3 ] [ 4 5 6 ] + is [ 4 10 18 ].
  • For matrices, perform a matrix multiplication.
  • For a matrix and a vector, apply the matrix to the vector.
  • For equations and symbols, build a product, eliminating mulitplication by 1 or 0 when autosimplify is active.
  • For a list and a positive integer, repeat the list For example, { A } 3 * is { A A A }.
  • For a text and a positive integer, repeat the text. For example "X" 3 * gives "XXX".

÷ (/, div)

Divide two values two values

Y XY÷X

  • For integer, build a fraction. For example 1 7 / gives 1/7.
  • For fractional, decimal or complex numbers, this performs the expected numerical division. For example, 1. 2. / is 0.5.
  • For vectors, divide individual elements. For example, [ 1 2 3 ] [ 3 2 1 ] / is [ 1/3 1 3 ].
  • For equations and symbols, build a ratio, eliminating division by one and division of 0 when autosimplify is active.

↑ (^, pow)

Raise to the power

Y XY↑X

  • For integer, fractional, decimal or complex numbers, this raises the value in level 2 to the value in level 1. For example, 2 3 ↑ is 8.
  • For vectors, raise individual elements in the first vector to the power of the corresponding element in the second vector.
  • For equations and synbols, build an expression, eliminating special cases when autosimplify is active.

xroot

Raise to the inverse power. X Y xroot is equivalent to X Y inv pow.

Y XY↑(1/X)

Integer arithmetic and polynomials

This section documents newRPL commands that are not implemented yet in DB48X.

SETPREC

Set the current system precision

GETPREC

Get the current system precision

FLOOR

Largest integer less than the input

CEIL

Smallest integer larger than the input

IP

Integer part of a number

FP

Fractional part of a number

MODSTO

Set the current system modulo for all MOD operations

MODRCL

Get the current system modulo

POWMOD

Power operator MOD the current system modulo

MOD

Remainder of the integer division

SQ

Square of the input

NEXTPRIME

Smallest prime number larger than the input

FACTORIAL

Factorial of a number

ISPRIME

Return true/false (1/0) if a number is prime or not

MANT

Mantissa of a real number (M*10exp)

XPON

Exponent of a number represented as (M*10exp)

SIGN

Sign of a number, -1, 0 or 1.

For complex numbers, returns a unit number on the unit circle with the same argument as the original number.

PERCENT

Percentage of a number

PERCENTCH

Percentage of change on a number

PERCENTTOT

Get percentage of a total

GCD

Greatest common divisor

LCM

Least common multiple

IDIV2

Integer division, get quoteiant and remainder

IQUOT

Quotient of the integer division

ADDTMOD

Addition operator MOD the current system modulo

SUBTMOD

Subtraction operator MOD the current system modulo

MULTMOD

Multiplication operator MOD the current system modulo

PEVAL

Evaluation of polynomial given as vector of coefficients

PCOEF

Coefficients of monic polynomial with the given roots

IEGCD

Extended euclidean algorithm

IABCUV

Find integers u,v to solve au+bv=c

PTCHEBYCHEFF

Nth Tchebycheff polynomial

PLEGENDRE

Nth Legendre polynomial

PHERMITE

Nth Hermite polynomial as used by physics

PTCHEBYCHEFF2

Nth Tchebycheff polynomial of the second kind

PHERMITE2

Nth Hermite polynomial as used in probabilities

DIV2

Polynomial euclidean division as symbolic

PDIV2

Polynomial euclidean division as coefficient vector

PDER

Derivative of polynomial as coefficient vector

PINT

Integration of polynomials as coefficient vector

PMUL

Multiplication of polynomials as coefficient vectors

PADD

Addition of polynomials as coefficient vector

PSUB

Subtraction of polynomials as coefficient vector

MIN

Smallest of 2 objects

MAX

Largest of 2 objects

RND

Round a number to the given number of figures

TRNC

Truncate a number to the given number of figures

DIGITS

Extract digits from a real number

PROOT

All roots of a polynomial

PREVPRIME

Largest prime smaller than the input

FACTORS

Factorize a polynomial or number

Base functions

Evaluate (EVAL)

Evaluate the object at stack level 1.

Mapped to the _ R/S _ key

X ▶ Result of X evaluation

Drop

Negate (NEG)

Negate the value in level 1.

Mapped to the _ +/- _ key

X0-X

Invert (INV)

Invert the value in level 1

Mapped to the _ 1/X _ key

X1/X

Bitwise operations

STWS

Store current word size in bits (0-63)

RCWS

Recall the currnent word size in bits

BOR

Bitwise OR operation

BAND

Bitwise AND operator

BXOR

Bitwise XOR operation

BLSL

Bitwise logical shift left

BLSR

Bitwise logical shift right

BASR

Bitwise arithmetic shift right

BRL

Bitwise rotate left

BRR

Bitwise rotate right

BNOT

Bitwise inversion of bits

BADD

Bitwise addition with overflow

BSUB

Bitwise subtraction with overflow

BMUL

Bitwise multiplication

BDIV

Bitwise integer division

BNEG

Bitwise negation

Bitmaps

TOSYSBITMAP

Comments

STRIPCOMMENTS

Remove all comments from a compiled program

Operations with Complex Numbers

RE

Real part of a complex number

IM

Imaginary part of a complex number

ARG

Argument of a complex number

CONJ

Conjugate of a complex number

CPLX2REAL

Split Complex into two Reals

REAL2CPLX

Make Complex from real and imaginary parts

Lists, Matrix and String commands

PUT

Replace an item in a composite

PUTI

Replace an item and increase index

GET

Extract an item from a composite

GETI

Extract an item and increase index

HEAD

Extract the first item in a composite

TAIL

Removes the first item in a composite

OBJDECOMP

Explode an object into its components

REPL

Replace elements in a composite

POS

Find the position of an element in a composite

NPOS

Find object in a composite, starting from index N

POSREV

Find the position of an element, starting from the end

NPOSREV

Find the position from the end, starting at index N

SUB

Extract a group of elements from a composite

SIZE

Number of elements in a composite

RHEAD

Returns the last element from the composite

RTAIL

Removes the last element from the composite

Constants

PICONST

ICONST

ECONST

JCONST

Debugging

DB48X offers a variety of capabilities to help debugging RPL programs. These are made available through the DebugMenu, which is the menu that ToolsMenu selects when a program is on the stack.

DebugMenu

The debug menu contains operations necessary to debug RPL programs:

Debug (DBUG)

The Debug command takes a program or expression as an argument, and starts debugging execution of it. When a program is halted for debugging, the header area shows a symbol, and the next instruction to be executed is shown above the stack. When a program is single-stepping, the header area shows a symbol.

While a program is being debugged, you can use the command line normally and even execute programs from it. However, only a single debugging session can exist. If the program being executed halts, e.g. through the HALT command or by being interrupted using the EXIT key, then this is seen as part of the same debugging session.

SingleStep (SST)

The SingleStep command steps through a single instruction in the RPL program.

StepOver

The StepOver command steps over the next instruction. If the next instruction is a variable name containing a program, execution halts after executing the program. If the next instruction being shown is a sequence of instructions, for example the test or the sequence of instructions in tests or loops, then the entire sequence is evaluated at once.

StepOut

The StepOut command steps out of the current code block.

MultipleSteps

The MultipleSteps instruction evaluates an arbitrary number of steps in the program being debugged. The number of steps to execute is passed as an argument in the first level of the stack. For example, 40 MultipleSteps will execute the next 40 RPL instructions.

Continue (CONT)

The Continue command resumes execution of the current RPL program at the current instruction.

Halt

The Halt instruction interrupts the execution of a program, making it possible to insert breakpoints at specific locations in a program.

Kill

The Kill instruction stops the execution of the program currently being debugged.

Variables

Variables are named storage for RPL values.

Store (STO)

Store an object into a global variable

Recall (RCL)

Recall the contents of a variable

StoreAdd (STO+)

Add to the content of a variable

StoreSubtract (STO-)

Subtract from the contents of a variable

StoreMultiply (STO×)

Multiply contents of a variable

StoreDivide (STO÷)

Divide the content of a variable

Increment (INCR)

Add one to the content of a variable

Decrement (DECR)

Subtract one from content of a variable

Purge

Delete a global variable from the current directory

Remark: Purge only removes a variable from the current directory, not the enclosing directories. Since Recall will fetch variable values from enclosing directories, it is possible that 'X' Purge 'X' Recall will fetch a value for X from an enclosing directory. Use PurgeAll if you want to purge a variable including in enclosing directories.

PurgeAll

Delete a global variable from the current directory and enclosing directories.

Remark: If a variable with the same name exists in multiple enclosing directories, PurgeAll may purge multiple variables. Use Purge if you want to only purge a variable in the current directory.

CreateDirectory (CRDIR)

Create new directory

PurgeDirectory (PGDIR)

Purge entire directory tree

UpDirectory (UPDIR)

Change current directory to its parent

HomeDirectory (HOME)

Change current directory to HOME

DirectoryPath (PATH)

Get a path to the current directory

Variables (VARS)

List all visible variables in a directory

ALLVARS

List all variables in a directory

ORDER

Sort variables in a directory

QUOTEID

Add single quotes to a variable name

UNQUOTEID

Remove single quotes from a variable name

HIDEVAR

Hide a variable (make invisible)

UNHIDEVAR

Make a hidden variable visible

CLVAR

Purge all variables and empty subdirectories in current directory

LOCKVAR

Make variable read-only

UNLOCKVAR

Make variable read/write

RENAME

Change the name of a variable

TVARS

List variables of a specific type

TVARSE

List all variables with extended type information

SADD

Apply command ADD to the stored contents of the variable

SPROP

Store a property to a variable

RPROP

Recall a property of a variable

PACKDIR

Pack a directory in an editable object

Errors and error handlers

EXITRPL

Panic exit - abort the RPL engine.

EVAL1NEXT

Perform EVAL1 on the next object in a secondary and skips it

RESUME

End error handler and resume execution of main program

DOERR

Issue an error condition

ERRN

Recall the previous error code

ERRM

Recall the previous error message

ERR0

Clear previous error code

HALT

Halt the execution of RPL code

CONT

Continue execution of a halted program

SST

Single-step through a halted program, skip over subroutines

SSTIN

Single-step through a halted program, goes into subroutines

KILL

Terminate a halted program

SETBKPOINT

Set a breakpoint on a halted program

CLRBKPOINT

Remove a breakpoint

DBUG

Halt the given program at the first instruction for debugging

BLAMEERR

Issue an error condition, blame other program for it

EXIT

Early exit from the current program or loop

Flow control

If

The if statement provides conditional structurs that let a program make decisions. It comes in two forms:

  • if condition then true-clause end: This evaluates condition and, if true, evaluates true-clause.

  • if condition then true-clause else false-clause end: This evaluates condition and, if true, evaluates true-clause, otherwise evaluates false-clause.

A condition is true if:

  • It is a number with a non-zero value
  • It is the word True

A condition is false if:

  • It is a number with a zero value
  • It is the word False

CASE

Conditional CASE ... THEN ... END THEN ... END END statement

THENCASE

Conditional CASE ... THEN ... END THEN ... END END statement

ENDTHEN

Conditional CASE ... THEN ... END THEN ... END END statement

ENDCASE

Conditional CASE ... THEN ... END THEN ... END END statement

FOR

Loop FOR ... NEXT/STEP statement

START

Loop START ... NEXT/STEP statement

NEXT

Loop FOR/START ... NEXT statement

STEP

Loop FOR/START ... STEP statement

DO

Loop DO ... UNTIL ... END statement

UNTIL

Loop DO ... UNTIL ... END statement

ENDDO

Loop DO ... UNTIL ... END statement

WHILE

Loop WHILE ... REPEAT ... END statement

REPEAT

Loop WHILE ... REPEAT ... END statement

ENDWHILE

Loop WHILE ... REPEAT ... END statement

IFERR

Conditional IFERR ... THEN ... ELSE ... END statement

THENERR

Conditional IFERR ... THEN ... ELSE ... END statement

ELSEERR

Conditional IFERR ... THEN ... ELSE ... END statement

ENDERR

Conditional IFERR ... THEN ... ELSE ... END statement

FORUP

Loop FORUP ... NEXT/STEP statement

FORDN

Loop FORUP ... NEXT/STEP statement

Menus, Flags and System Settings

SETLOCALE

Change the separator symbols

SETNFMT

Change the display format for numbers

SF

Set a flag

CF

Clear a flag

FCTEST

Test if a flag is clear

FSTEST

Test if a flag is set

FCTESTCLEAR

Test if a flag is clear, then clear it

FSTESTCLEAR

Test if a flag is set, then clear it

TMENU

Display the given menu on the active menu area

TMENULST

Display the given menu on the menu area the user used last

TMENUOTHR

Display the given menu on the menu are the user did not use last

MENUSWAP

Swap the contents of menu areas 1 and 2

MENUBK

Display the previous menu on the active menu area

MENUBKLST

Display the previous menu on the area the user used last

MENUBKOTHR

Display the previous menu on the area the user did not use last

RCLMENU

Recall the active menu

RCLMENULST

Recall the menu the user used last

RCLMENUOTHR

Recall the menu the user did not use last

DEG

Set the angle mode flags to degrees

GRAD

Set the angle mode flags to grads (gons)

RAD

Set the angle mode flags to radians

DMS

Set the angle mode to DMS (as DD.MMSS)

ASNKEY

Assign a custom definition to a key

DELKEY

Remove a custom key definition

STOKEYS

Store and replace all custom key definitions

RCLKEYS

Recall the list of all custom key definitions

TYPEE

Get extended type information from an object

GETLOCALE

Get the current separator symbols

GETNFMT

Recall the current display format for numbers

RCLF

Recall all system flags

STOF

Store and replace all system flags

VTYPE

Get type information on the contents of a variable

VTYPEE

Get extended type information on the contents of a variable

FMTSTR

Do →STR using a specific numeric format

Fonts

FNTSTO

Install a user font for system use

FNTRCL

Recall a system font

FNTPG

Purge a user-installed system font

FNTSTK

Recall name of current font for stack area

FNT1STK

Recall name of current font for stack level 1

FNTMENU

Recall name of current font for menu area

FNTCMDL

Recall name of current font for command line area

FNTSTAT

Recall name of current font for status area

FNTPLOT

Recall name of current font for plot objects

FNTFORM

Recall name of current font for forms

STOFNTSTK

Change current font for stack area

STOFNT1STK

Change current font for stack level 1

STOFNTMENU

Change current font for menu area

STOFNTCMDL

Change current font for command line area

STOFNTSTAT

Change current font for status area

STOFNTPLOT

Change current font for plot objects

STOFNTFORM

Change current font for forms

FNTHELP

Recall name of current font for help

FNTHLPT

Recall name of current font for help title

STOFNTHELP

Change current font for help text

STOFNTHLPT

Change current font for help title

Graphic commands

DB48X features a number of graphic commands. While displaying graphics, the stack and headers will no longer be updated.

Coordinates

DB48X recognizes the following types of coordinates

  • Pixel coordinates are specified using based numbers such as #0, and correspond to exact pixels on the screen, and . Pixels are counted starting from the top-left corner of the screen, with the horizontal coordinate going from 10#0 to 10#399, and the vertical coordinate going from 10#0 to 10#239.

  • User unit coordinates are scaled according to the content of the PPAR or PlotParameters reserved variables.

  • Text coordinates are given on a square grid with a size corresponding to the height of a text line in the selected font. They can be fractional.

Coordinates can be given using one the following object types:

  • A complex number, where the real part represents the horizontal coordinate and the imaginary part represents the vertical coordinate.

  • A 2-element list or vector containing the horizontal and vertical coordinates.

  • A 1-element list of vector containing one of the above.

For some operations, the list or vector can contain additional parameters beyond the coordinates. The selection of unit or pixel coordinates is done on a per coordinate basis. For exmaple, { 0 0 } will be the origin in user coordinates, in the center of the screen if no PPAR or PlotParameters variable is present.

Note that unlike on the HP48, a complex value in DB48X can contain a based number.

ClearLCD (cllcd)

Clear the LCD display, and block updates of the header or menu areas.

DrawText (disp)

Draw the text or object in level 2 at the position indicated by level 1. A text is drawn without the surrounding quotation marks.

If the position in level 1 is an integer, fraction or real number, it is interpreted as a line number starting at 1 for the top of the screen. For example, "Hello" 1 disp will draw Hello at the top of the screen.

If the position in level 1 is a complex number or a list, it is interpreted as specifying both the horizontal or vertical coordinates, in either pixel or unit coordinates. For example "Hello" { 0 0 } disp will draw Hello starting in the center of the screen.

Text is drawn using the stack font by default, using the foreground and background patterns.

If level 1 contains a list with more than 2 elements, additional elements provide:

  • A font number for the text

  • An erase flag (default true) which indicates whether the background for the text should be drawn or not.

  • An invert flag (default false) which, if set, will swap the foreground and background patterns.

For example, "Hello" { #0 #0 0 true true } DrawText will draw Hello in the top-left corner (#0 #0) with the largest (editor) font (font identifier 0), erasing the background (the first true), in reverse colors (the second true).

DrawLine (line)

Draw a line between two points specified by level 1 and level 2 of the stack.

The width of the line is specified by LineWidth. The line is drawn using the foreground pattern.

PlotParameters (PPAR)

The PlotParameters reserved variable defines the plot parameters, as a list, with the following elements:

  • Lower Left coordinates as a complex (default -10-6i)

  • Upper Right coordinates as a complex (default 10+6i)

  • Independent variable name (default x)

  • Resolution specifying the interval between values of the independent variable (default 0). A binary numnber specifies a resolution in pixels.

  • Axes which can be a complex giving the origin of the axes (default 0+0i), or a list containing the origin, the tick mark specification, and the names of the axes.

  • Type of plot (default function)

  • Dependent variable name (default y)

Local Variables

LSTO

Store to a new local variable

LRCL

Recall content of local variable

HIDELOCALS

Hide local variables from subroutines

UNHIDELOCALS

Unhide local variables from subroutines

INTERNAL_NEWNLOCALS

Arbitrary data containers

MKBINDATA

Create binary data container object

BINPUTB

Store bytes into binary data object

BINGETB

Extract binary data as list of bytes

BINPUTW

Store 32-bit words into binary data object

BINGETW

Extract data from a binary data object as a list of 32-bit words

BINPUTOBJ

Store an entire object into a binary data container

BINGETOBJ

Extract an entire object from a binary data container

BINMOVB

Copy binary data block into a binary data object

BINMOVW

Copy 32-bit words between binary data objects

User Libraries

CRLIB

Create a library from current directory

ATTACH

Install a library

DETACH

Uninstall a library

LIBMENU

Show a menu within a library

LIBMENUOTHR

Show library menu in the other menu

LIBMENULST

Show library menu in the last used menu

LIBSTO

Store private library data

LIBRCL

Recall private library data

LIBDEFRCL

Recall private data with default value

LIBCLEAR

Purge all private data for a specific library

Operations with Lists

TOLIST

Assemble a list from its elements

INNERCOMP

Split a list into its elements

CMDDOLIST

Do a procedure with elements of lists

DOSUBS

Do a procedure on a subset of a list

MAP

Do a procedure on each element of a list, recursively

MAPINNERCOMP

Do a procedure on each element recursively, return individual elements

STREAM

Do a procedure on consecutive elements of a list

DELTALIST

First differences on the elements of a list

SUMLIST

Sum of all elements in a list

PRODLIST

Product of all elements in a list

ADD

Concatenate lists and/or elements

SORT

Sort elements in a list

REVLIST

Reverse the order of elements in a list

ADDROT

Add elements to a list, keep only the last N elements

SEQ

Assemble a list from results of sequential procedure

Operations with Matrices and vectors

TOARRAY

Assemble an array from its elements

ARRAYDECOMP

Split an array into its elements

TOCOL

Split an array into column vectors

ADDCOL

Instert a column into an array

REMCOL

Remove a column from an array

FROMCOL

Assemble a matrix from its columns

TODIAG

Extract diagonal elements from a matrix

FROMDIAG

Create a matrix with the given diagonal elements

TOROW

Split an array into its row vectors

ADDROW

Insert a row into an array

REMROW

Remove a row from an array

FROMROW

Assemble an array from its rows

TOV2

Assemble a vector from two values

TOV3

Assemble a vector from three values

FROMV

Split a vector into its elements

AXL

Convert a matrix to list and vice versa

BASIS

Find vectors forming a basis of the subspace represented by the matrix

CHOLESKY

Perform Cholesky decomposition on a matrix

CNRM

Column norm (one norm) of a matrix

CON

Assemble an array with given constant value

COND

Column norm condition number of a matrix

CROSS

Cross produce of vectors

CSWP

Swap two columns in a matrix

DET

Determinant of a matrix

DIAGMAP

DOT

Internal product (dot product) of vectors

EGV

EGVL

Compute the eigenvalues of a matrix

GRAMSCHMIDT

HADAMARD

Multiply corresponding elements in a matrix

HILBERT

Assemble a Hilbert symbolic array

IBASIS

Find a basis of the intersection of two vector spaces

IDN

Assemble an identity matrix

IMAGE

Find a basis of the image of a linear application

ISOM

JORDAN

KER

Find a basis for the kernel of a linear application

LQ

LSQ

LU

LU factorization of a matrix

MAD

MKISOM

PMINI

Minimal polynomial of a matrix

QR

QR Decomposition of a matrix

RANK

Rank of a matrix

RANM

Assemble a matrix with random numbers

RCI

Multiply a row by a constant

RCIJ

Multiply a row by a constant and add to other row

RDM

Change dimensions of an array

REF

Reduce matrix to echelon form (upper triangular form)

RNRM

Row norm (infinity norm) of a matrix

RREF

Fully reduce to row-reduced echelon form

RREFMOD

RSD

Residual R=B-AX' on a system AX=B

RSWP

Swap two rows in a matrix

SCHUR

SNRM

SRAD

SVD

SVL

SYLVESTER

TRACE

Sum of the items in the diagonal of a matrix

TRAN

Transpose a matrix

TRN

Complex conjugate transpose of a matrix

VANDERMONDE

LDUP

Decompose A into LDUP such that PA=LD-1*U

MMAP

Apply expression or program to the elements of a matrix

Numerical functions

∫ (Integrate)

Perform a numerical integration of a function for a specified variable on a numerical interval. For example 2 3 'X*(X-3)' 'X' Integrate returns -7/6.

The function takes four arguments:

  • The lower bound of the integration range
  • The higher bound of the integration range
  • The program or expression to evaluate
  • The integration variable

Root

Root-finder command. Returns a real number that is a value of the specified variable for which the specified program or algebraic object most nearly evaluates to zero or a local extremum. For example, 'X^2=3' 'X' 0 returns X:1.732050807568877293527446341953458.

The function takes three arguments:

  • The program or expression to evaluate
  • The variable to solve for
  • An initial guess, or a list containing an upper and lower guess.

Cycle

Cycle through various representations of the object on the first level of the stack.

  • Polar <-> Rectangular for complex numbers
  • Decimal <-> Fraction
  • Integer <-> Based (cycles through the 2, 8, 10 and 16 base)
  • Array <-> List <-> Program
  • Text <-> Symbol

For unit objects, Cycle will cycle through all SI prefixes such that the decimal representations fits within the StandardExponent range (i.e. that would not display in scientific mode), increasing the numerical value, and then switch the value to a fraction and cycle through all fraction representations that fit within the same numerical range.

For example, if the StandardExponent is set to 6, the value 0.1_m will cycle as follows:

  • 0.1_m being a decimal, we move to next scale up as decimal
  • 1._dm
  • 10._cm
  • 100._mm
  • 100000._μm, which is the limit of what can be displayed with 6 digits, so we switch to a fractional representation.
  • 100000_μm being a fraction, we go through the prefixes going down.
  • 100_mm
  • 10_cm
  • 1_dm
  • 1/10_m
  • 1/100_dam
  • 1/1000_hm
  • 1/10000_km, at which point the conversion would be out of range, so we switch back to decimal.
  • 0.0001_km
  • 0.001_hm
  • 0.01_dam
  • 0.1_m at which point the cycle repeats.

Scalable plots and graphics

BEGINPLOT

Initialize a new current plot object

EDITPLOT

Set the current plot object to the given graphic

ENDPLOT

Finish current plot object and leave it on the stack

STROKECOL

Change the current stroke color

STROKETYPE

Change current stroke type

FILLCOL

Change the current fill color

FILLTYPE

Change the current fill type

FILL

Fill the last polygon

STROKE

Draw the outline of the last polygon

FILLSTROKE

Draw the outline and fill the last polygon

MOVETO

Move current coordinates

LINETO

Draw a line

CIRCLE

Draw a circle

RECTANG

Draw a rectangle

CTLNODE

Add a control node to the current polygon

CURVE

Draw a curve using all previous control points

BGROUP

EGROUP

DOGROUP

BASEPT

TRANSLATE

ROTATE

SCALE

CLEARTRANSF

SETFONT

TEXTHEIGHT

TEXTOUT

INITRENDER

Set which library will be used as default renderer

DORENDER

Render a graphics object using the current renderer

PANVIEW

Shift the center of viewport to render graphics

ROTVIEW

SCLVIEW

Set scale to render graphics

VIEWPORT

VIEWALL

SD Card

SDRESET

Reset the file system module

SDSETPART

Set active partition

SDSTO

Store a an object into a file

SDRCL

Recall an object from a file

SDCHDIR

Change current directory

SDUPDIR

Change to parent directory

SDCRDIR

Create a new directory

SDPGDIR

Delete an entire directory

SDPURGE

Delete a file

SDOPENRD

Open a file for read-only operation

SDOPENWR

Open a file for writing

SDOPENAPP

Open a file in append mode

SDOPENMOD

Open a file in modify mode

SDCLOSE

Close an open file

SDREADTEXT

Read text from an open file (UTF-8 encoding)

SDWRITETEXT

Write text to a file (UTF-8 encoding)

SDREADLINE

Read one line of text from a file

SDSEEKSTA

Move position to given offset from start of file

SDSEEKEND

Move position to given offset from end of file

SDSEEKCUR

Move position to given offset from the current point.

SDTELL

Get the current position

SDFILESIZE

Get the file size in bytes

SDEOF

Return true if last operation reached end of file

SDOPENDIR

Open a directory to scan entries

SDNEXTFILE

Get the next entry in a directory that is a file

SDNEXTDIR

Get the next entry in a directory that is a subdirectory

SDNEXTENTRY

Get the next entry in a directory

SDMOVE

Move or rename a file

SDCOPY

Copy a file

SDPATH

Get the path to current directory

SDFREE

Get the free space in the current volume

SDARCHIVE

Create a full calculator backup on a file

SDRESTORE

Restore from a backup stored in a file

SDGETPART

Get the current partition number

Settings

The calculator has a number of user-configurable settings:

The current preferences can be retrieved and saved using the Modes command.

Modes

Returns a program that will restore the current settings. This program can be saved into a variable to quickly restore a carefully crafted set of preferences. Note that the calculator automatically restores the mode when it loads a state.

Display settings

The display mode controls how DB48X displays numbers. Regardless of the display mode, numbers are always stored with full precision.

DB48X has five display mode (one more than the HP48)s:

StandardDisplay (STD)

Display numbers using full precision. All significant digts to the right of the decimal separator are shown, up to 34 digits.

FixedDisplay (FIX)

Display numbers rounded to a specific number of decimal places.

ScientificDisplay (SCI)

Display numbers in scientific notation, i.e. with a mantissa and an exponent. The mantissa has one digit to the left of the decimal separator and shows the specified number of decimal places.

EngineeringDisplay (SCI)

Display nunmbers as a mantissa with a sepcified number of digits, followed by an exponent that is a multiple of 3.

SignificantDisplay (SIG)

Display up to the given number of digits without trailing zero. This mode is useful because DB48X can compute with large precision, and it may be useful to not see all digits. StndardDisplay is equivalent to 34 SignificantDisplay, while 12 SignificantDisplay should approximate the HP48 standard mode using 12 significant digits.

StandardExponent

Select the maximum exponent before switching to scientific notation. The default value is 9, meaning that display uses scientific notation for exponents outside of -9..9.

MinimumSignificantDigits

Select the minimum number of significant digits before switching to scientific notation in FIX mode.

The default value is 0, which is similar to how HP calculators before the HP Prime perform. For example, with 2 FIX, the value 0.055 will display as 0.06, and 0.0055 will display as 0.01.

A higher value will switch to scienfic mode to show at least the given number of digits. For instance, with 2 FIX, if the value is 1, then 0.055 will still display as 0.06 but 0.0055 will display as 5.50E-3. If the value is 2, then 0.055 will display as 5.5E-2. A setting of 1 correspond to what the HP Prime does.

A value of -1 indicates that you do not want FIX mode to ever go to scientific notation for negative exponents. In that case, 0.00055 will display as 0.00.

TrailingDecimal

Display a trailing decimal separator to distinguish decimal from integer types. With this setting, 1.0 will display as 1.. This can be disabled with NoTrailingDecimal.

NoTrailingDecimal

Hide the trailing decimal separator for decimal values with no fractional part. In that mode, 1.0 and 1 will both display identically, although the internal representation is different, the former being a floating-point value while the latter is an integer value.

FancyExponent

Display the exponent in scientific mode using a fancy rendering that is visually similar to the normal mathematical notation.

ClassicExponent

Display the exponent in scientific mode in a way reminiscent of classical HP48 calculators, for example 1.23E-4.

MixedFractions

Display fractions as mixed fractions when necessary, e.g. 3/2 will show up as 1 1/2.

ImproperFractions

Display fractions as improper fractions, e.g. 3/2 will show up as 3/2 and not 1 1/2.

SmallFractions

Show fractions using smaller characters, for example ¹²/₄₃

BigFractions

Show fractions using regular characters, for example 12/43

Angle settings

The angle mode determines how the calculator interprets angle arguments and how it returns angle results.

DB48X has four angle modes:

  • Degrees: A full circle is 360 degress
  • Radians: A full circle is 2π radians
  • Grads: A full circle is 400 radians
  • PiRadians: Radians shown as multiple of π

Degrees (DEG)

Select degrees as the angular unit. A full circle is 360 degrees.

Radians (RAD)

Select radians as the angular unit. A full circle is 2π radians, and the angle is shown as a numerical value.

Grads (GRAD)

Select grads as the angular unit. A full circle is 400 grads.

PiRadians (PIRAD)

Select multiples of π as the angular unit. A full circle is 2π radians, shown as a multiple of π.

Command display

DB48X can display commands either using a short legacy spelling, usually identical to what is used on the HP-48 series of calculators, or use an alternative longer spelling. For example, the command to store a value in a variable is called STO in the HP-48, and can also be spelled Store in DB48X.

Commands are case insensitive, and all spellings are accepted as input irrespective of the display mode.

DB48X has four command spelling modes:

LowerCase

Display comands using the short form in lower case, for example sto.

UpperCase

Display comands using the short form in upper case, for example STO.

Capitalized

Display comands using the short form capitalized, for example Sto.

LongForm

Display comands using the long form, for example Store.

Decimal separator settings

The decimal separator can be either a dot (1.23) or a comma (1,23).

DecimalDot

Select the dot as a decimal separator, e.g. 1.23

DecimalComma

Select the comma as a decimal separator, e.g. 1,23

Precision settings

Precision

Set the default computation precision, given as a number of decimal digits. For example, 7 Precision will ensure at least 7 decimal digits for compuation, and 1.0 3 / will compute 0.3333333 in that case.

In the current implementation, this selects one of three decimal formats:

  • The decimal32 for up to 7 digits mantissa and an exponents up to 96
  • The decimal64 for up to 16 digits mantissa and an exponents up to 384
  • The decimal128 for up to 34 digits mantissa and an exponents up to 6144

The intent in the long run is to allow arbitrary precision like in newRPL.

Base settings

Integer values can be reprecended in a number of different bases:

Binary (BIN)

Selects base 2

Octal (OCT)

Selects base 8

Decimal (DEC)

Selects base 10

Hexadecimal (HEX)

Selects base 16

Base

Select an arbitrary base for computations

StoreWordSize (STWS)

Store the word size for binary computations

WordSize (RCWS)

Recall the word size for binary computations

MaxRewrites

Defines the maximum number of rewrites in an equation.

Equations rewrites can go into infinite loops, e.g. 'X+Y' 'A+B' 'B+A' rewrite can never end, since it keeps rewriting terms. This setting indicates how many attempts at rewriting will be done before erroring out.

MaxBigNumBits

Define the maxmimum number of bits for a large integer.

Large integer operations can take a very long time, notably when displaying them on the stack. With the default value of 1024 bits, you can compute 100! but computing 200! will result in an error, Number is too big. You can however compute it seting a higher value for MaxBigNumBits, for example 2048 MaxBigNumBits.

ToFractionIterations (→QIterations, →FracIterations)

Define the maximum number of iterations converting a decimal value to a fraction. For example, 1 →FracIterations 3.1415926 →Frac will give 22/7, whereas 3 →FracIterations 3.1415926 →Frac will give 355/113.

ToFractionDigits (→QDigits, →FracDigits)

Define the maximum number of digits of precision converting a decimal value to a fraction. For example, 2 →FracDigits 3.1415926 →Frac will give 355/113.

User interface

Various user-interface aspects can be customized, including the appearance of Soft-key menus. Menus can show on one or three rows, with 18 (shifted) or 6 (flat) functions per page, and there are two possible visual themes for the labels, rounded or square.

ThreeRowsMenus

Display menus on up to three rows, with shift and double-shift functions showns above the primary menu function.

SingleRowMenus

Display menus on a single row, with labels changing using shift.

FlatMenus

Display menus on a single row, flattened across multiple pages.

RoundedMenu

Display menus using rounded black or white tabs.

SquareMenus

Display menus using square white tabs.

CursorBlinkRate

Set the cursor blink rate in millisecond, between 50ms (20 blinks per second) and 5000ms (blinking every 5 seconds).

ShowBuiltinUnits

Show built-in units in the UnitsMenu even when a units file was loaded.

HideBuiltinUnits

Hide built-in units in the UnitsMenu when a units file was loaded. The built-in units will still show up if the units file fails to load.

States

The calculator can save and restore state in files with extension .48S. This feature is available through the Setup menu (Shift-0).

The following information is stored in state files:

  • Global variables
  • Stack contents
  • Settings

Numeric solvers

NUMINT

Numerical integration (adaptive Simpson)

ROOT

Root seeking within an interval

MSOLVE

Multiple non-linear equation solver/optimization search

BISECT

Root seeking (bisection method)

Stack manipulation

Clear

Remove all objects from the stack

Depth

Get the current stack depth

Drop

Remove an object from the stack

Drop2

Remove two objects form the stack

DropN

Remove N objects from the stack, N being given in level 1.

Duplicate (DUP)

Duplicate an object on the stack

Duplicate2 (DUP2)

Duplicate two objects on the stack

DuplicateTwice (DUPDUP)

Duplicate the same object twice on the stack

DuplicateN (DUPN)

Duplicate a group of N objects, N being given in stack level 1

LastArguments (LASTARG)

Put the last arguments back on the stack

LastX

Put the last first argument on the stack.

This command does not exist on HP RPL calculators, and is here to make it easier to adapt RPN programs that use LastX a bit more often.

Undo

Restore the stack to its last state before executing an interactive command. Note that this command can be used from a program, but it will restore the state prior to program execution.

NDUPN

Replicate one object N times and return N

NIP

Remove object at level 2 on the stack

Over

Duplicate object at level 2 on the stack

PICK

Duplicate object at position N on the stack

PICK3

Duplicate object at level 3 on the stack

ROLL

Move object at level N to level 1

ROLLD

Move object from level 1 to level N

ROT

Move object from level 3 to level 1

SWAP

Exchange objects in levels 1 and 2

Mapped to X⇆Y key

Y XX Y

UNPICK

Move object from level 1 to level N.

UNROT

Move object from level 1 to level 3

IFT

Evaluate objects on the stack conditionally

IFTE

Evaluate objects on the stack conditionally

STKPUSH

Push a snapshot of the current stack on the undo stack

STKPOP

Pop a stack snapshot from the undo stack

STKDROP

Drop a snapshot from the undo stack

STKPICK

Copy snapshot in level N to the current stack

STKDEPTH

Get the depth of the undo stack

STKNEW

Push a snapshot of the current stack on the undo stack and clears the current stack

Statistics

RDZ

Initialize random number generator with a seed

RAND

Generate a random real number

Operations with Strings

TOUTF

Create a Utf8 string from a list of code points

FROMUTF

List all code points in a Utf8 string

TOSTR

Decompile any object (convert to string)

FROMSTR

Compile a string into RPL objects

SREV

Reverse the characters on a string

NTOKENS

Number of tokens in a string

NTHTOKEN

Token at position N in a string

NTHTOKENPOS

Position of token N in a string

TRIM

Remove characters at end of string

RTRIM

Remove characters at start of string

SSTRLEN

Length of string in characters

STRLENCP

Length of string in Unicode code points

TONFC

Normalize a string to Unicode NFC

SREPL

Find and replace text in a string

TODISPSTR

Decompile formatted for display

TOEDITSTR

Decompile formatted for edit

Operations with Symbolic Expressions

Rewrite

Applies an arbitrary transformation on equations. The first argument is the equation to transform. The second argument is the pattern to match. The third argument is the replacement pattern. Patterns can contain variable names, which are substituted with the corresponding sub-expression.

In the matching pattern, variables with a name that begins with i, j, k, l, m, n, p or q must match a non-zero positive integer. When such a match happens, the expression is evaluated after rewrite in order to compute values such as 3-1.

Additionally, variables with a name that begins with u, v or w must be unique within the pattern. This is useful for term-reordering rules, such as 'x*u*x' 'x*x*u', which should not match a*a*a where it is a no-op. If multiple variables with a unique name exist in the same pattern, then they must match symbols, and the symbols must be sorted in the same order as in the pattern. For example, rewriting v*u as u*v and x*v*u as x*u*v and applying these rules repeadely will result in a sorting of terms in multiplications.

Eq From ToEq

Examples:

  • 'A+B+0' 'X+0' 'X' rewrite returns 'A+B'
  • 'A+B+C' 'X+Y' 'Y-X' rewrite returns 'C-(B-A)
  • '(A+B)^3' 'X^N' 'X*X^(N-1)' rewrite returns (A+B)*(A+B)^2.

AutoSimplify

Enable automatic reduction of numeric subexpressions according to usual arithmetic rules. After evaluating AutoSimplify 'X+0' will evaluate as 'X' and 'X*1-B*0' witll evaluate as 'X'.

The opposite setting is NoAutoSimplify

NoAutoSimplify

Disable automatic reduction of numeric subexpressions according to usual arithmetic rules. After evaluating NoAutoSimplify, equations such as'X+0' or X*1-B*0 will no longer be simplified during evaluation.

The opposite setting is AutoSimplify

RULEMATCH

Find if an expression matches a rule pattern

RULEAPPLY

Match and apply a rule to an expression repeatedly

→Num (→Decimal, ToDecimal)

Convert fractions and symbolic constants to decimal form. For example, 1/4 →Num results in 0.25.

→Frac (→Q, ToFraction)

Convert decimal values to fractions. For example 1.25 →Frac gives 5/4. The precision of the conversion in digits is defined by →FracDigits, and the maximum number of iterations for the conversion is defined by →FracDigits

RULEAPPLY1

Match and apply a rule to an expression only once

TRIGSIN

Simplify replacing cos(x)^2+sin(x)^2=1

ALLROOTS

Expand powers with rational exponents to consider all roots

CLISTCLOSEBRACKET

RANGE

Create a case-list of integers in the given range.

ASSUME

Apply certain assumptions about a variable to an expression.

Time, Alarms and System Commands

SETDATE

Set current system date in MM.DDYYYY

DATEADD

Add days to a date in MM.DDYYYY

SETTIME

Set current time as HH.MMSS

TOHMS

Convert decimal time to HH.MMSS

FROMHMS

Convert time in HH.MMSS to decimal

HMSADD

Add time in HH.MMSS format

HMSSUB

Subtract time in HH.MMSS format

TICKS

Return system clock in microseconds

TEVAL

Perform EVAL and measure elapsed time

DATE

Current system date as MM.DDYYYY

DDAYS

Number of days between dates in MM.DDYYYY

TIME

Current time in HH.MMSS

TSTR

ACK

Acknowledge oldest alarm (dismiss)

ACKALL

Acknowledge (dismiss) all alarms

RCLALARM

Recall specified alarm

STOALARM

Create a new alarm

DELALARM

Delete an existing alarm

FINDALARM

Get first alarm due after the given time

Version

Return DB48X version information as text.

"Version information"

FreeMemory

Return the number of bytes immediately available in memory, without performing a cleanup of temporary values (garbage collection).

See also: GarbageCollect, FreeMemory

AvailableMemory (MEM)

Return the number of bytes available in memory.

Remark: The number returned is only a rough indicator of usable memory. In particular, recovery features consume or release varying amounts of memory with each operation.

Before it can assess the amount of memory available, AvailableMemory removes objects in temporary memory that are no longer being used. Like on the HP48, you can therfore use MEM DROP to force garbage collection. However, there is also a dedicated command for that, GarbageCollect.

See also: FreeMemory, GarbageCollect

GarbageCollect

Perform a clean-up of temporary objects and return number of bytes reclaimed.

In order to speed up normal operations, temporaries are only discarded when necessary to make room. This clean-up process, also called garbage collection, occurs automatically when memory is full. Since garbage collection can slow down calculator operation at undesired times, you can force it to occur at a desired time by executing GarbageCollect.

See also: FreeMemory, Purge

Bytes

Return the size of the object and a hash of its value. On classic RPL systems, teh hash is a 5-nibbles CRC32. On DB48X, the hash is a based integer of the current wordsize corresponding to the binary representation of the object.

For example, the integer 7 hash will be in the form #7xx, where 7 is the value of the integer, and xx represents the integer type, as returned by the Type command.

XHash Size

Type

Return the type of the object as a numerical value. The value is not guaranteed to be portable across versions of DB48X (and pretty much is guarantteed to not be portable), nor to ever match the value returned by the TYPE command on the HP48.

Note The TypeName command returns the type as text, and this is less likely to change from one release to the next.

TypeName

Return the type of the object as text. For example, 12 type returns "integer".

PEEK

Low-level read memory address

POKE

Low level write to memory address

NEWOB

Make a new copy of the given object

USBFWUPDATE

PowerOff (OFF)

Turn calculator off programmatically

SystemSetup

Display the built-in system setup

SaveState

Save the machine's state to disk, using the current state if one was previously loaded. This is intended to quickly save the state for example before a system upgrade.

Tagged objects

Tagged objects are a way to indicate what a value represents, using a tag between colons and preceding the object. For example, :X:3 is a tagged integer, where the tag is X and the object is 3.

When displayed on the stack, tags are shown without the leading colon for readability. For example, the object above shows as X:3 on the stack.

→Tag (ToTag)

Apply a tag to an object. The tag is in level 1 as text or name. The object to be tagged is in level 2. For example, "Hello" 1 →Tag results in :Hello:1. Like on the HP calculators, it is possible to next tags.

Tag→ (FromTag)

Expand a tagged object in level 1 into its object and tag. The object will be in level 2, the tag will be in level 1 as a text object.

For example, :Hello:1 Tag→ results in "Hello" in level 1 and 1 in level 2.

DeleteTag (DTAG)

Remove a tag from an object. For example, :Hello:1 DeleteTag results in 1. If there is no tag, the object is returned as is.

Transcendental functions

SIN

Compute the sine

COS

Compute the cosine

TAN

Compute the tangent

ASIN

Compute the arcsine

ACOS

Compute the arccosine

ATAN

Compute the arctangent

ATAN2

Compute arctangent(y/x)

LN

Compute natural logarithm

EXP

Compute exponential function

SINH

Compute the hyperbolic sine

COSH

Compute the hyperbolic cosine

TANH

Compute the hyperbolic tangent

ASINH

Compute the hyperbolic arcsine

ACOSH

Compute the hyperbolic arccosine

ATANH

Compute the hyperbolic arctangent

LOG

Compute logarithm in base 10

ALOG

Compute anti-logarithm in base 10

SQRT

Compute the square root

EXPM

Compute exp(x)-1

LNP1

Compute ln(x+1)

PINUM

Numeric constant π with twice the current system precision

User Interface

COPYCLIP

Copy an object to the clipboard

CUTCLIP

Move an object to the clipboard

PASTECLIP

Insert the clipboard contents on the stack

Wait

Wait for a key press or a time lapse.

When the argument is greater than 0, interrupt the program for the given number of seconds, which can be fractional.

When the argument is 0 or negative, wait indefinitely until a key is pressed. The key code for the key that was pressed will be pushed in the stack. If the argument is negative, the current menu will be displayed on the screen during the wait.

KEYEVAL

Simulate a keypress from within a program

KEY

Get instantaneous state of the keyboard

DOFORM

Take a variable identifier with a form list

EDINSERT

Insert given text into the editor

EDREMOVE

Remove characters in the editor at the cursor position

EDLEFT

Move cursor to the left in the editor

EDRIGHT

Move cursor to the right in the editor

EDUP

Move cursor up in the editor

EDDOWN

Move cursor down in the editor

EDSTART

Move cursor to the start of text in the editor

EDEND

Move cursor to the end of text in the editor

EDLSTART

Move cursor to the start of current line in the editor

EDLEND

Move cursor to the end of current line in the editor

EDTOKEN

Extract one full word at the cursor location in the editor

EDACTOKEN

Extract one word at the left of cursor location (suitable for autocomplete)

EDMODE

Change the cursor mode in the editor

SETTHEME

Set system color theme

GETTHEME

Operations with Units

UDEFINE

Create a user-defined unit

UPURGE

Delete a user-defined unit

UnitValue (UVAL)

Return the numeric part of a unit object.

3_km3

BaseUnits (UBASE)

Expand all unit factors to their base units.

3_km3000_m

Convert

Convert value from one unit to another. This convert the values in the second level of the stack to the unit of the object in the first level of the stack. Only the unit in the first level of the stack is being considered, the actual value is ignored. For example:

3_km 2_m3000_m

FactorUnit (UFACT)

Factor the unit in level 1 from the unit expression of the level 2 unit object.

1_W 1_N1_N*m/s

→Unit (ToUnit)

Creates a unit object from a real number and the unit part of a unit object. →Unit adds units to a number, combining the number and the unit part of a unit object. The numerical part of the unit object is ignored.

→Unit is the reverse of Unit→ or of Obj→ applied to a unit object.

3000 2_km3000_km

ULIST

List all user-defined units

USB Communications

USBSTATUS

Get status of the USB driver

USBRECV

Receive an object through USB link

USBSEND

Send an object through the USB link

USBOFF

Disable USB port

USBON

Enable USB port

USBAUTORCV

Receive an object and execute it

USBARCHIVE

Create a backup on a remote machine

USBRESTORE

Restore a backup from a remote machine