String functions for the HP-41

This program is by Torbjörn Wigren and is used here by
permission.

This program is supplied without representation or warranty of any kind.
Torbjörn Wigren and The Museum of HP Calculators therefore assume no responsibility
and shall have no liability, consequential or otherwise, of any kind arising
from the use of this program material or any part thereof.

The code was developed using HP-41CV, SERIAL NO. 2124S13142. It was
independently tested using the HP-41 MCODE Emulator, Release 3. Files
for this emulator are available for download at
http://www.it.uu.se/katalog/tw/information .

Overview

This set of subroutines provides string functions for the HP 41C/CV.
The functions "LEN", "RIGHT", "LEFT", "MID", "ADD", "ROL", "ROR",
"FIND", "VAL", "NUM2STR", "STR2NUM", "STO", "RCL", "STOXYZT" and
"RCLTZYX" are provided. The functions operate on strings in the
alpha-register, according to arguments provided in the x- and
y-registers. String results are returned in the alpha-register whereas
numerical results are returned in the x-register of the stack. All
functions allow string operations on strings with a maximum length of
6, 12, 18 or 24 characters, the choice being made by the user. All
characters of the HP 41C/CV may be used. The characters of the strings
are numbered from 1 and upwards, starting with 1 for the leftmost
character. The extended functions module also contains a set of string
functions that extends the string handling functionality of the HP
41C/CV calculator itself. However, users that do not have access to this module, are familiar with synthetic programming or own a HP 41CX are limited to the basic append, compare and shift functions that operate on strings in the HP 41C/CV. The intention has been to use basic programming techniques, to allow for easy adaptation of the code to specific applications. The provided string manipulating functionality is believed to be useful for a number of programming tasks, including encryption/decryption, password generation, logic simulation and the design of games.

CHARACTER STRING MANIPULATION

All string handling functions require that the number of registers used for holding strings (1,2,3 or 4) is stored in register 15. This results in string handling of strings with a maximum of 6, 12, 18 or 24 characters. The selected number of registers affects the execution
times significantly.

"LEN"

The function returns the length (number of characters) of the string in the alpha-register, in the x-register. The string remains in the
alpha-register after execution. In case the string in the alpha-register is longer than what can be stored according to the specified number of registers used for holding strings, the right part of the string is first truncated, after which the function is applied. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

The algorithm operates by first applying ASHF to remove 6 characters
at a time until the alpha-register is empty. The number of removed
characters are increased by 6 for each shift. The last non-empty
character string of the alpha-register is then restored to the
alpha-register, after which one space is appended to this string. It is then checked if an ASHF leaves the alpha-register empty or not. If
still empty, the value of the length counter is reduced by one and the
space addition is repeated. The process terminates when the ASHF
operation does no longer result in an empty alpha-register.

"RIGHT"

The function returns the right characters of the string stored in the
alpha-register, from and including the character with the number stored in the x-register. The result is returned in the alpha-register, with the argument remaining in the x-register at end of execution. In case the string in the alpha-register is longer than what can be stored according to the specified number of registers used for holding strings, the right part of the string is first truncated, after which the function is applied. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

The algorithm first removes blocks of 6 characters from the string in
the alpha-register, decreasing the argument until it is less than 6.
This is handled by register 03 that is initialized appropriately by
"INIT". The remaining string is stored in registers 06 to 09, at label
04. The remaining characters to remove are processed at label 05.
A string of spaces with a length such that the length plus the remaining characters to remove equals 6 is first created. The first 6 characters of the remaining string are then added to the sting of spaces and ASHF is applied. This removes the remaining characters. The rest of the blocks of characters of the result are finally retrieved from registers 07 to 09.

"LEFT"

The function returns the left characters of the string stored in the
alpha-register, up to and including the character with the number
stored in the x-register. The result is returned in the alpha-register, with the argument remaining in the x-register at end of execution. In case the string in the alpha-register is longer than what can be stored according to the specified number of registers used for holding strings, the right part of the string is first truncated, after which the function is applied. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

The algorithm first stores blocks of 6 characters in register 06 and on, decreasing the argument until it is less than 6. This is handled by register 03 that is initialized appropriately by "INIT", and by the
indirect address stored in register 05. The number of remaining
charcters to include in the result are then computed at label 07 from
the updated indirect address of register 05. If the number of remaing
characters equals 0 the algorithm proceeds to label 16 and terminates.
Otherwise the last block of 6 characters (of which a subset is to be
included in the result) is stored. The final step of the algorithm is
to generate the string of the remaning characters to add from the last
saved block. In order to do so, a string of spaces of length equal to 6 minus the number of characters to add is first constructed at label 8. The last block of 6 characters is appended to the constructed space
string in the alpha-register. The first 6 characters are then stored.
The remaining characters to add are now at the end of the stored result. At label 9 a new string of spaces is generated so that the TOTAL number of spaces in the generated strings of spaces equals 6. The string of length 6 with the characters to add at the end is appended to the alpha-register, rendering a string with 6 spaces at the beginning and the remaining characters to add at the end. Applying an ASHF operation removes the spaces, after which the final block of the result can be stored. Finally, at label 16, the result is appended in the alpha-register from the stored blocks of 6 characters, and the argument is restored to the x-register.

"MID"

The function returns the mid characters of the string stored in the
alpha-register. The x-register specifies the right inclusive character
number defining the extracted string, whereas the y-register specifies
the left character number defining the extracted string. The result is
returned in the alpha-register, with the arguments remaining in the
x-register and the y-register at end of execution. In case the string
in the alpha-register is longer than what can be stored according to the specified number of registers used for holding strings, the right part of the string is first truncated, after which the function is applied. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

The function first extracts the left part, using "LEFT" and the desired right argument. Then the result is produced by execution of "RIGHT" with the desired left argument.

"ROL"

The function rotates the string of the alpha-register the number of
steps left specified in the x-register. The x-register remains after
execution. In case the string in the alpha-register is longer than what can be stored according to the specified number of registers used for holding strings, the right part of the string is first truncated, after which the function is applied. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

The function first stores the string at address 21 and computes its
length with "LEN". The MOD operation avoids any need to rotate more than one complete revolution. The part to become the last part is first extracted by "LEFT" and stored at address 34. The stored complete string is restored to the alpha register and the part that is to form the first part of the result is extracted with "RIGHT". "ADD" applied to address 34 then forms the result.

"ROR"

The function rotates the string of the alpha-register the number of
steps right specified in the x-register. The x-register remains after
execution. In case the string in the alpha-register is longer than what can be stored according to the specified number of registers used for holding strings, the right part of the string is first truncated, after which the function is applied. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

The function computes the number of steps that would result in the same result by a left rotation, then applies "ROL".

"ADD"

The function augments the string with the address provided in the
x-register, to the string in the alpha-register. The use of indirect
addressing ensures that all registers can be used for storage of
strings. The argument remains in the x-register at end of execution. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

Note: No truncation of the right part of the string in the
alpha-register is applied.

The function returns the (2-digit) positions of an up to 6 character
string, stored at the address specified in the x-register, in the string of the alpha register. The string in the alpha register remains after execution and the result is presented in the x-register. In case the string in the alpha-register is longer than what can be stored according to the specified number of registers used for holding strings, the right part of the string is first truncated, after which the function is applied. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

The function first stores the original string and computes its length.
The function also computes the length of the string searched for. Then
all possible positions of the string searched for, in the searched
string, are extracted from the searched string by "MID". It is then
tested whether the extracted part is the same as the string searched
for. If so, the position (leftmost character) is encoded as a two bit
number in the integer result.

NUMERICAL STRING MANIPULATION

"VAL"

The function transforms a string in the alpha-register consisting of the characters 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9, to the corresponding
numerical nonnegative integer value. The result is displayed in the
x-register and the string remains in the alpha-register after execution. In case the string in the alpha-register is longer than what can be stored according to the specified number of registers used for holding strings, the right part of the string is first truncated, after which the function is applied. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied. Note that the execution time is significantly higher than for the character manipulating string functions.

The algorithm first calls "LEN" to compute the length of the character
string, in order to set up loops. The provided string is also stored,
starting at register 21. "MID" is then used to extract each character,
starting at the right. For each character, the value of register 20 is
multiplied by 10, thereby allowing the contribution of each character to be added to the result after multiplication with register 20 of the
number obtained by transforming the character to a numerical value. This transformation is performed by an indirect addressing, using the
extracted character as the address to one of the charactre labels "0" to "9".

"NUM2STR"

The function transforms any numerical value of the x-register to a
string in the alpha register. All formats are covered.

Data register: 00 (numerical value)

"STR2NUM"

The function transforms a string corresponding to a floating point
numerical value, to the numerical value. The string remains in the
alpha-register after execution and the result appears in the x-register.The functions handles FIX, SCI and ENG formats, however there must only be ONE SEPARATOR. This must be the COMMA that separates the integer and fractional parts of the mantissa. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied. Note that the execution time is significantly higher than for the character manipulating string functions. Note also that the number of registers used for string storage (register 15) needs to be set to 3 or 4.

The function first initializes necessary registers for storage of the
different parts of the floating point number. It also stores the string at string address 34. It then uses character manipulating string functions to find the sign of the exponent (if any), the sign of the mantissa, the position of the separator (if any) between the integer and fractional parts of the mantissa, the position of the exponent (if any), represented by the character E. Given this information, the three strings corresponding to the nonnegative integer part of the mantissa, the nonnegative fractional part of the mantissa (if any) and the nonnegative integer part of the exponent can all be extracted from the original string, again using character manipulating string functions. The results are then converted to numerical values using "VAL". From this it is straightforward to build up the umerical result.

GENERAL STRING HANDLING AND SUPPORT FUNCTIONS

"STO"

The function stores the string in the alpha-register indirectly in the
registers starting with the address provided in the x-register. The
indirect addressing secures that all registers can be used for storage
of strings. The string remains in the alpha-register after execution.
In case the string in the alpha-register is longer than what can be
stored according to the specified number of registers used for holding
strings, the right part of the string is first truncated, after which
the function is applied. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

The function applies indirect addressing to store a string starting in
the register specified in the x-register. The number of registers used
for storage equals the number spcified in register 15. Six characters
are stored in each register.

"RCL"

The function recalls the string specified with the address provided in
the x-register. The string is recalled to the alpha-register. The
indirect addressing applied secures that all registers can be used for
storage of strings. The argument remains in the x-register after
execution. If the stack needs to be preserved, "STOXYZT" / "RCLTZYX" can be applied.

The function applies indirect addressing to recall a string starting in the register specified in the x-register. The number of registers used for recalling equals the number spcified in register 15. Six characters are recalled from each register.

"STOXYZT"

This function stores the stack. To be applied before string function
calls whenever the stack should be preserved.

SETS OF FUNCTIONS

These functions need no other supporting functions for their execution. The following resources are consumed by this minimum set.

Data register used: <=26.
Labels used: <=17.
Flags used: Flag 0.

Remaining functions can be added to this set as desired. In case of
addition of VAL the limits on data registers and labels above still
holds, otherwise please consult the description above. In case a known
or fixed length is used, then LEN may be omitted by replacements in the code. When the complete set of functions is used, the following limits apply:

Data registers used: <=45.
Labels used: <= 35.
Flags used: Flag 0.

The complete set of functions consume 185 data registers for the code.

In case other combinations of string functions are used the user is
referred to the documentation of each function for information of which subroutines, data registers and labels that are used. The minimum set of functions do not need additional support. However, when other functions are added this may not apply. "STR2NUM" e.g. makes use of "VAL". The user is referred to the documentation of each function for details.

EXAMPLE

3 data registers per string is to be used.
3
STO 15
Also store an empty space in data register 53.
" "
ASTO 53
Store a string in the alpha-register.
"HP-41CV CALCULATOR"
Then store it, starting at data register 50.
50
XEQ "STO"
The numerical display and the alpha-register remain unaffected.
"HP-41C" is now stored in data register 50,
"V CALC" in data register 51 and "ULATOR" in data register 52.
Compute the length of the string in the alpha-register.
XEQ "LEN"
The numerical display shows the result 18. The alpha-register remains
unaffected.
Find the location of the space in the string.
53
XEQ "FIND"
The numerical display shows the result 8.
Extract the first word of the string in the alpha-register.
7
XEQ "LEFT"
The numerical display is unaffected. The alpha-register shows the result "HP-41CV".
Store the result, starting at register 54.
54
XEQ "STO"
"HP-41C" is now stored in register 54, "V" in data register 55 and
"" in data register 56.
Extract the fourth and fifth characters of the string in the
alpha-register.
4
ENTER
5
XEQ "MID"
The x- and y-registers remain unaffected. The alpha-register shows the
result "41".
Transform the result to a numerical value.
XEQ "VAL"
The alpha-register remains unaffected. The numerical dispaly shows the
numerical value 41.
Recall the original string and rotate left 7 steps.
50
XEQ "RCL"
7
XEQ "ROL"
The numerical display remains unaffected. The alpha-register displays
the result " CALCULATORHP-41CV".
Recover the original string.
7
XEQ "ROR"
The numerical display remains unaffected. The alpha-register shows the
result "HP-41CV CALCULATOR".
Then find the location of the letter "C" in the string of the
alpha-register. First store "C" in data register 60.
"C"
ASTO 60
"C" is now stored in alpha-register and in data register 60.
Recall the original string starting in data register 50, and search
for "C".
50
XEQ "RCL"
60
XEQ "FIND"
The display shows 120906, i.e positions 12, 09 and 06. The
alpha-register is unaffected.
Extract the second word of the string and add the string stored at data register 54.
Also compute the length of the result.
9
XEQ "RIGHT"
54
XEQ "ADD"
XEQ "LEN"
The numerical display shows the length 17.
The alpha-register shows the result "CALCULATORHP-41CV".
This is because the space is now gone.
Then set the calculator in scientific mode with 4 decimals. Key in
-34.56e-78.
SCI 4
-34.56
EEX
-78
ENTER
The numerical display shows -3,4560 -77.
Then transform to a string and clear the display.
XEQ "NUM2STR"
CLX
The alpha-register displays the string -3,4560E-77. The numerical
display shows 0.
Finally, restore the numerical value.
XEQ "STR2NUM"
The numerical display shows the result -3,4560 -77. The alpha-register remains unaffected.

Program

Note: In case the code is keyed in manually, it is required to input all alphanumeric labels first. The reasom is that overloading of names of built in functions is used.