The binary calculator manipulates numbers that are interpreted as binary numbers, which are bit strings of certain length.

The numbers are entered and kept in the HP-41 stack as normal decimal numbers or, optionally and when the word size allows, as hexalpha numbers, i.e. hexadecimal characters as Alpha data. The word size (maximum 32 bits), active sign mode (signed or unsigned), active base mode (decimal, binary, octal or hexadecimal), output mode preference (decimal or hexalpha), and carry and overflow flags reflecting the result of the last calculation are kept in user flags 00 to 10.

The binary calculator can be used as an *interactive program,*
which has its own *keyboard,* or by executing *programmable XROM
functions.*

The binary calculator program is coded entirely in MCODE. A significant part
of its implementation is in page 4 – for speed and easyness of programming.
The page 4 library part `khp4lib` of the program can also be used by
MCODE programmers as a library of useful subroutines.

The program has been developed and tested in a SY-41CL but no specific CL instructions have been used, so if you have means to store the two program images and use page 4 appropriately for the library image, you can use the program also in any model of HP-41.

Both ROM images and their source code (in KHP-41 assembly language, partially commented) are available on this page.

Copyright © 2019 Kari Pasanen

- Revision history
- Binary images
- Source code
- Compiling
- Additional features
- Usage
- Interactive keyboard
- Modes display
- Binary numbers in display
- Binary numbers in stack
- Binary numbers in Alpha register
- Easy ways to do base conversions
- Binary calculator functions
- Technical information
- License
- Author

- Rev. 1.0 published 2019-05-07: First published revision.

This 4k image must be put in page 4:

This 4k image can be put in any page from 8 to F, like a pluggable ROM module, but you must have the page 4 library in place to use it:

This MOD file, containing both images, can be used in some MLDLs and in the V41 emulator:

KHP-41 assembly source of the page 4 library:

KHP-41 assembly source of the application ROM:

If you wish to compile the source code yourself, you can do it with the
`asm41` program.

For assembly you need this HP-41 mainframe entry points include file:

The following files, in addition to the `.rom` object files, are
results of assembly (listing files and include file of `khp4lib`
entry points):

Page 4 was reserved by HP for the Service Module, which is a take-over ROM. There are calls in the HP-41 operating system code to the beginning of page 4. These calls have now been taken in use for benefit: The binary calculator doesn't wait key presses in an active loop but instead allows the calculator to go into light sleep. When a key is pressed, the operating system calls the Service Module entry point, which returns the control to the binary calculator.

In addition to the implementation of the power-saving trick the beginning of the page 4 library contains a code sequence which solves a problem with the Time Module Clone of Systemyde International, the first one described here, by consuming enough time in a loop executed when the calculator wakes up from light sleep. No Flash image update is needed in a SY-41CL; the added wake-up time is meaningless in other calculators where it isn't needed.

The binary calculator can be used in two ways:

- as an interactive program named
`BIN`; - executing programmable XROM functions.

Also `BIN` itself is a programmable function. It can be used in a
program to receive a binary number as input from the user.

This keyboard map shows the assignment of HP-41 keys within the interactive
binary calculator program `BIN`. The keys work in the following ways:

`SHIFT`key. Toggles non-shifted and shifted keyboard operation: All other key positions are identified as non-shifted or shifted. Later in this document, what is printed on the real key or above it (for the shifted position), is used as the*name*of the key.- Non-shifted
`ON`key. The primary key used to exit the interactive binary calculator. Only exits, doesn't turn the calculator OFF. - Keys that exit the interactive binary calculator and execute their
original function (in USER mode what is assigned to them, if the key is
assignable): shifted
`ON`(turns the calculator OFF or displays the clock),`XEQ`,`ASN`,`STO`,`RCL`,`SST`,`BST`,`R/S`. In the keyboard map these key positions are marked with a square. - Keys that do nothing, even don't terminate digit entry, only cancel
the
`SHIFT`if it is on: non-shifted and shifted`USER`,`PRGM`and`ALPHA`,`COS`,^{-1}`TAN`,^{-1}`CATALOG`,`RTN`. In the keyboard map these key posititions have no marking. - Digit entry keys
`0`to`9`and`A`to`F`in their natural positions. When a key is pressed for a digit which isn't used in the active base mode, or if the already keyed number cannot be extended with that digit within the active word size, the key does nothing, as a key in the previous group. - The backarrow key
`<-`. Works in the ordinary way: If digit entry has been started, digits already entered are removed one at a time beginning from the last one in the display. When there is only one digit and it is removed, the operation is like`CLX`. When there is a message in the display, it is cancelled and the number in X register is displayed. If no message and no digit entry, then the operation is like`CLX`. - Digit entry termination key
`.`. It isn't necessary to specially terminate digit entry before pressing a function key but this is an option. Compared to`ENTER^`, digit entry termination with the specific key doesn't copy the contents of X register to Y register and only enables stack lift. - Sign mode toggle key
`Σ-`. - Base mode selection keys:
`y`for^{x}`BINMODE`, to select binary base mode (remember the position from 'b');`x`for^{2}`OCTMODE`, to select octal base mode (remember the position from 'c');`10`for^{x}`DECMODE`, to select decimal base mode (remember the position from 'd');`e`for^{x}`HEXMODE`, to select hexadecimal base mode (remember the position from 'e').

- Function keys. A function key executes either a function which is
similar to a standard function (
`X<>Y`on the`CLΣ`key [because the non-shifted key is reserved for hex digit`F`],`RDN`,`R^`on`%`key,`ENTER^`,`CLX`,`LASTX`– no XROM function number has been reserved for these) or belongs to the special binary calculator function set. After execution of the function the calculator is still in the interactive binary calculator program.

When you press a function key, the name of the function on that key is displayed until you release the key, then the function is executed. If you press the key down long enough, the function name is NULLed and no function is executed.

When the interactive binary calculator is entered or when the base mode,
sign mode or word size is set or viewed – by a specific key within the
`BIN` program or by an XROM function, but not in a running program, –
the active modes and word size are displayed in the format

`BAS-X-WS=nn`

where

`BAS`is`BIN`,`OCT`,`DEC`or`HEX`;`X`is`N`for unsigned or`S`for signed;`nn`is the word size expressed as a decimal number (one or two digits).

The modes display is a message that can be cancelled by pressing the
backarrow key `<-` to view the X register contents.

When a program executes `BIN`, the modes display is shown only if
there wasn't a message in display. If there was another message, it is allowed
to stay. This feature can be used to prompt the user about what input is
expected.

When displayed in the interactive binary calculator or viewed by the
`BVIEW` function, numbers appear right-justified in the display and
in the following forms according to the active sign and base mode:

- in signed mode prefixed with the sign,
`+`or`-`; - in decimal base mode without a base indicator;
- in binary base mode prefixed with
`B`; - in octal base mode prefixed with
`O`; - in hexadecimal base mode prefixed with
`H`.

The inputs for and outputs from binary calculator functions can appear in the stack in the form of decimal numbers or hexalpha numbers.

Decimal input is the standard way of input. When you work outside of the
`BIN` program, take care of the limits
implied by the active sign and base mode.

Hexalpha input is always an option. Any character has an interpretation
in hexalpha input, so no errors will result from "illegal" characters.
The interpretation rules for character `ab` (hexadecimal value) are:
When `a` is in the set `{0, 1, 2, 3, 8, 9, A, B}` take
`b` as the value of the character. Otherwise take
`(b + 9) mod 16` as the value. Limits should be followed also with
hexalpha input.

Decimal output is the standard way of output.

Hexalpha output is activated when flag 05 is set and the word size is at most 24. Numbers output in hexalpha format don't include a visible sign. Only true hexadecimal characters are used. The number of characters used is the minimum needed to represent all numbers within the active word size.

Binary numbers appear in Alpha register only as input for function
`BANUM` or as output from functions `BARCLX` and
`BARCLYX`.

`BANUM` accepts always a sign, `+` or `-`, even
multiple signs. An odd number of minus signs indicates a negative number.
It also accepts any number of digit grouping characters ('`.`' when
user flag 28 is clear, '`,`' when it is set) in any position of
the number.

`BARCLX` outputs a sign when signed mode is active or when the
input is a negative decimal number. `BARCLYX` outputs a sign when
signed mode is active.

The first character after the optional sign string, as input for
`BANUM` or output from `BARCLX` or `BARCLYX`, is the
base indicator:

- none for decimal base [10].
`B`for binary base [2];`O`for octal base [8];`H`for hexadecimal base [16].

Reading of input by `BANUM` stops at the first character which
couldn't be part of the number, as indicated by the base indicator if one
is present. If `BANUM` finds a number in Alpha register that it
can convert, it sets the numeric entry flag 22. Anything may be appended
after a number representation in Alpha register, but only the number which
is at the beginning is recognized as input.

`BARCLX` and `BARCLYX` append their output to the current
contents of Alpha register.

`BANUM` and `BARCLX` don't take the active word size into
account. They accept numbers up to `2 ^{32} - 1` in absolute
value.

The purpose of `BARCLYX` is to convert the output of function
`BSMUL` (in signed mode) or `BMUL` (in unsigned mode) to readable
form. It checks that both inputs, in Y and X registers, are within the range
implied by the active word size. Output of `BARCLYX` is always in
hexadecimal base [16].

Base conversion means only a change in how a number is *displayed.*
The most obvious way to do the conversion from base 'a' to base 'b' is to use
the interactive keyboard and key in the number while the active base mode is
'a' and then switch the mode to 'b'. Example:

`BRESET BIN BINMODE 1101 HEXMODE <-` displays `HD`.

You may also utilize the normal HP-41 operation mode in which binary numbers
are displayed in decimal. Continuing with the previous example, exit the binary
calculator by pressing `ON`, then you see the number `13`.
Continuing further:

`BIN OCTMODE <-` displays `O15`.

The example demonstrates that `B1101` [base 2], `O15`
[base 8], `HD` [base 16] and `13` [base 10] all are
representations of the same binary number but in different bases.

Setting user flag 05 changes the preferred output mode to hexalpha. This control by flag gives more options in doing base conversions where either the initial or target base is hexadecimal, but they work only when the word size is at most 24.

You can use the `BNORM` function to
normalize the number in X, then you
immediately see it in decimal or hexalpha according to the state of user
flag 05, or the `BVIEW` function to normalize the number in X and to
display it in the active sign and base mode, after clearing the display
you see it in decimal or hexalpha. Alternatively you may just visit the
`BIN` program and press the backarrow key `<-` to cancel
the modes display. This does the same things as `BVIEW`.

The `BANUM` and `BARCLX` functions may be used to convert
values between X register and Alpha register, with the benefit that Alpha
register can hold longer values in binary base [2] than X register due to
display limitations. `BARCLX` and `BARCLYX` accept hexalpha
input. User flag 05 doesn't affect the output format of `BANUM` which
is always decimal.

- All functions except
`ENTER^`and`CLX`enable stack lift. - Functions with one or two arguments save original X register contents
in LASTX register and return their result in X register.
`BCHS`,`BNOT`,`BINC`,`BDEC`,`BNORM`and`BVIEW`are exceptions to this rule: they alter X register contents but don't save the original value in LASTX. - Functions with two arguments and only one result drop the stack.
- One function,
`BTEST`, has a Boolean result. Used interactively it displays`YES`or`NO`. When used in a program, the next line is skipped if the test fails.

The XROM module id of the `khpbin` ROM is 16. Nothing prevents you
from changing it to whatever you choose.

All of the XROM functions are programmable.

Most of the function names begin with `B`, which isn't shown in the
keyboard map or in the function name display. Function names that logically
haven't the `B` prefix are `STOWS`, `RCLWS`,
`BINMODE`, `OCTMODE`, `DECMODE`, `HEXMODE`.

In the function descriptions x means the contents of X register interpreted as a binary number, y means the contents of Y register interpreted as a binary number, and ws means the word size.

`BRESET`(XROM 16,01) zeros all user flags used by the program (00 to 10) thus resetting carry and overflow flags, setting the default modes (decimal base; unsigned; decimal output preference) and setting the default word size (32 bits). Not available in the interactive binary calculator.`BMODES`(XROM 16,02) displays the modes display. It is useless in a program because when a program is running it doesn't display anything, but still it is programmable.`STOWS`(XROM 16,03) stores x in flags as the word size.`RCLWS`(XROM 16,04) recalls the word size from flags.`BINMODE`(XROM 16,05) sets binary base mode.`OCTMODE`(XROM 16,06) sets octal base mode.`DECMODE`(XROM 16,07) sets decimal base mode.`HEXMODE`(XROM 16,08) sets hexadecimal base mode.`BBIT`(XROM 16,09) returns 2^{x}if x is positive, 2^{ws + x}if x is negative.`BCHS`(XROM 16,10) negates x and outputs it in the active sign mode.`BNOT`(XROM 16,11) reverts all bits of x.`BABS`(XROM 16,12) returns absolute value of x interpreted as a signed number.`BINC`(XROM 16,13) increments x by 1.`BDEC`(XROM 16,14) decrements x by 1.`BSHFL`(XROM 16,15) shifts x left by one bit.`BSSHFR`(XROM 16,16) shifts x, interpreted as a signed number, right by one bit (arithmetic, i.e. sign-preserving shift).`BSHFR`(XROM 16,17) shifts x, interpreted as an unsigned number, right by one bit (logical shift).`BSSHFX`(XROM 16,18) shifts y, interpreted as a signed number, left by x bits if x is positive, right by -x bits if x is negative.`BSHFX`(XROM 16,19) shifts y, interpreted as an unsigned number, left by x bits if x is positive, right by -x bits if x is negative.`BROTL`(XROM 16,20) rotates x left by one bit.`BROTR`(XROM 16,21) rotates x right by one bit.`BROTX`(XROM 16,22) rotates y left by x bits if x is positive, right by -x bits if x is negative.`BAND`(XROM 16,23) returns bitwise AND of x and y.`BOR`(XROM 16,24) returns bitwise OR of x and y.`BXOR`(XROM 16,25) returns bitwise XOR of x and y.`BTEST`(XROM 16,26) calculates bitwise AND of x and y, returns YES if that result is non-zero or NO if it is zero.`B+`(XROM 16,27) adds x to y.`B-`(XROM 16,28) subtracts x from y.`BSMUL`(XROM 16,29) multiplies x by y, both interpreted as a signed number: higher part of the result is returned to Y register, lower part of the result is returned to X register. If u is the result in Y register and v is the result in X register, both interpreted as a signed number, then x * y = u * 2^{ws}+ v. Notice that u and v may have different signs.`BMUL`(XROM 16,30) multiplies x by y, both interpreted as an unsigned number: higher part of the result is returned to Y register, lower part of the result is returned to X register. If u is the result in Y register and v is the result in X register, both interpreted as an unsigned number, then x * y = u * 2^{ws}+ v.`BSDIV`(XROM 16,31) divides y by x, both interpreted as a signed number: y mod x is returned to Y register, y / x is returned to X register.`BDIV`(XROM 16,32) divides y by x, both interpreted as an unsigned number: y mod x is returned to Y register, y / x is returned to X register.`BSQRT`(XROM 16,33) returns the integer square root of x interpreted as an unsigned number.`BNORM`(XROM 16,34) normalizes x. Not available in the interactive binary calculator.`BANUM`(XROM 16,35) reads a binary number representation contained in Alpha register and puts it to X register. Not available in the interactive binary calculator.`BARCLX`(XROM 16,36) appends x in the active base mode to Alpha register, with sign if signed mode is active or x is a negative decimal number. Not available in the interactive binary calculator.`BARCLYX`(XROM 16,37) appends the results of`BSMUL`or`BMUL`from Y and X registers to Alpha register in hexadecimal base [16], with sign if signed mode is active. Not available in the interactive binary calculator.`BVIEW`(XROM 16,38) normalizes x and views it in the active sign and base mode. Not available in the interactive binary calculator.`BIN`(XROM 16,39) stops a running program and activates the interactive binary calculator keyboard.

- Digit entry termination on key
`.`. Not needed in a program. - Sign mode toggle on key
`Σ-`. A program should set or clear flag 04 instead. `X<>Y`,`RDN`,`R^`,`ENTER^`,`CLX`,`LASTX`. These functions are equivalent to the standard functions.

User flags 00 to 05 are used in the following meanings:

- Flag 00 set – carry
- Flag 01 set – overflow
- Flag 02 clear, flag 03 clear – decimal base mode
- Flag 02 clear, flag 03 set – binary base mode
- Flag 02 set, flag 03 clear – octal base mode
- Flag 02 set, flag 03 set – hexadecimal base mode
- Flag 04 set – signed mode
- Flag 05 set – hexalpha output preferred, effective only when word size is at most 24

Flags 00 to 04 have their indicators in the display.

User flags 06 to 10 code the word size. When all of them are clear, word size is 32 bits. Otherwise begin counting the word size from zero:

- Flag 06 set – add 16
- Flag 07 set – add 8
- Flag 08 set – add 4
- Flag 09 set – add 2
- Flag 10 set – add 1

The sign mode affects basically only displaying the results, not what is allowed as input nor the results as such except that in signed mode logically negative results are, of course, output as negative numbers.

Input is generally interpreted neutrally: A positive number x and a negative
number x - 2^{ws} mean the same binary number which is simply a bit
string. Negative input is allowed in unsigned mode, and positive unsigned
input with the uppermost bit (the sign bit) set is allowed in signed mode.
Internally in the binary calculator functions any input is first converted
to a bit string; results are calculated as bit strings and then converted
back to the format in which they are stored in the stack. The sign mode
controls only the latter conversion.

There are specific functions where the input is always interpreted as signed
and also the results should be viewed as signed numbers. To avoid confusion in
interpretation of the results, signed bit shifts, multiplication and division
(`BSSHFR`, `BSSHFX`, `BSMUL` and `BSDIV`) should be
executed in signed mode. `BARCLYX` should be executed in the same sign
mode as `BSMUL` or `BMUL` which gave the result to convert.

The interpretation of a hexalpha number as input for word size or bit number is independent of the active word size and thus unsigned. Hexalpha numbers can be used as input in functions expecting signed input; then the highest bit is interpreted as the sign bit.

In the interactive binary calculator you may key in negative numbers even in unsigned mode, but you should use the negative input immediately to avoid its normalization. Beware of that in unsigned mode the normalized value of a small negative number is a big positive number. Negative input values in unsigned mode are especially valid as bit numbers.

Before use in a function a function argument in stack is first made an integer discarding its fractional part. The absolute integer value is checked to fit in the active word size and converted to a bit string. Then, if the argument has negative sign, that bit string is negated. If the input is Alpha data, the conversion to a bit string is straightforward following the interpretation rules.

Functions that take a bit number argument behave differently in the input conversion as they preserve logically the original sign of the bit number even in unsigned mode.

The results are calculated as bit strings, masked to the word size, and finally put in the stack registers in the format controlled by the sign mode (user flag 04) and output mode preference (user flag 05).

Because only the original contents of X register is saved in LASTX register,
the user cannot always know what the binary calculator *thinks* the given
input means. If you want to check the interpretation of your input, you should
*normalize* it before use in a function. This means doing the input
conversion and the output conversion successively. To do it, call the
`BNORM` or `BVIEW` function, or visit `BIN` and press
either the backarrow key `<-` or the digit entry termination key
`.` before exit.

In the interactive binary calculator you can use the digit entry termination
key `.` to normalize the number that you have just keyed in. This may
change its sign if you have entered a negative number while the active sign
mode is unsigned.

Carry flag is set in a function if the logically correct result of the calculation with unsigned values doesn't fit in the active word size.

Overflow flag is set in a function if the result of the calculation with signed values has the wrong sign. For example, when you add two positive numbers you would expect to get a positive number as the result. However, if you get a negative number, that means an overflow.

Functions that follow the basic rules:

`BSHFL``B+``B-`

Functions that generally clear carry and overflow flags but in special cases set one or both of them:

`BABS`sets overflow flag when the argument is -2^{ws - 1}(ws is the active word size); then the result is -2^{ws - 1}which has the wrong sign.`BSMUL`sets carry flag if higher part of the absolute value of the result is non-zero and sets overflow flag if carry flag is set or lower part of the result has the wrong sign.`BMUL`sets carry flag if higher part of the result is non-zero.`BSDIV`sets overflow flag when -2^{ws - 1}is divided by -1 (ws is the active word size); then the result is -2^{ws - 1}which has the wrong sign.

Functions that always clear carry and overflow flags:

`BRESET``STOWS``RCLWS``BINMODE``OCTMODE``DECMODE``HEXMODE``BBIT``BCHS``BNOT``BINC``BDEC``BSSHFR``BSHFR``BSSHFX``BSHFX``BROTL``BROTR``BROTX``BAND``BOR``BXOR``BTEST``BDIV``BSQRT``BNORM``BIN`

Functions that don't change carry and overflow flags:

`BMODES``BANUM``BARCLX``BARCLYX``BVIEW`

Functions on the interactive binary calculator keyboard that always clear carry and overflow flags:

- Digit entry termination
- Sign mode toggle
`X<>Y``RDN``R^``ENTER^``CLX``LASTX`

Word size is limited to 32 by the HP-41 register size (56 bits) and the format of decimal numbers, as the stack is intended to be used for storage. Alpha data in stack allows only six hexadecimal characters, which means a word size of 24 bits. Also the display imposes limits for usable word sizes.

In order that the interactive binary calculator can be used with the least possible interruptions, setting of sign and base modes and word size is controlled and the results of functions are restricted to the proper range within the active word size. Thus a result, when it is displayed immediately after execution of a function, is never out-of-range.

However, when modes or word size have been changed after the number is
produced, or when a number which isn't an output of a binary calculator
function is tried to be displayed or used in a function, being out-of-range is
possible for an *input.* This can happen even in the beginning of
`BIN` program after clearing the modes display.

If an error occurs, the interactive binary calculator exits, or a running
program stops except when the error ignore flag 25 was set – then only that
flag is cleared. Setting flag 25 before execution of `BIN` isn't useful,
because then at error the binary calculator program exits without a message.

When the base mode, sign mode or word size is set or when the settings are recalled, the word size is checked against the active modes and, when necessary, cut to the maximum value that can be supported. The modes display indicates then what has really been set.

The maximum supported word size in different modes is as follows:

- 30 bits in signed octal base mode;
- 11 bits in unsigned binary base mode;
- 10 bits in signed binary base mode;
- otherwise 32 bits.

In the interactive binary calculator, keying in a negative number when unsigned mode is active changes the effective limit of number length to that of signed mode. During digit entry, when underscore ('_') is the rightmost character in display, still at least one more digit can be appended to the number, but no more when the underscore disappears.

As input in Alpha register for `BANUM` 32 bits are allowed
because such values can be represented as decimal numbers.

The word size limit of `BANUM` and `BARCLX` imposed by the
capacity of Alpha register is as follows:

- 23 bits in unsigned binary base mode, no sign in input;
- 22 bits in signed binary base mode, or negative input in unsigned mode;
- otherwise 32 bits.

The result of `BARCLYX` is always in hexadecimal base [16] and
thus it fits in Alpha register.

`NO KHP4LIB`- (All functions)
`khp4lib`image wasn't found in page 4.

`DATA ERROR`- (
`BSDIV`,`BDIV`) - Attempted division by zero.

`DATA ERROR`- (
`STOWS`) - Attempted to store zero word size.

`TOO BIG NUM`- (
`STOWS`) - Attempted to store a word size greater than 32.

`TOO BIG NUM`- (
`BBIT`,`BSSHFX`,`BSHFX`,`BROTX`) - A bit number greater than ws - 1 or smaller than -ws was tried to be used (ws is the active word size).

`TOO BIG NUM`- (Interactive binary calculator, All functions)
- An out-of-range value was tried to be displayed or used in a function.

At the time of publication no bugs are known in the program. If you find some, please report them to the author who will make his best to republish a debugged program revision or add an explanation of a surprising phenomenon in this document.

This program is free software: you can redistribute it or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

The full GNU General Public Licence text is available at http://www.gnu.org/licenses/gpl.html.

The attribution of this program to its original author must be preserved in any direct copy or modified version of this program. This is a supplement to the terms of the GNU General Public Licence version 3 allowed by them in section 7. Additional Terms, point b).

The original author of this program is

Kari Pasanen, Jyväskylä, Finland,

Kari Pasanen <kari.pasanen@iki.fi>.

Feel free to propose additions of features to the binary calculator or routines to the page 4 library.