The Museum of HP Calculators
This program is supplied without representation or warranty of any kind. The author 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.
He had a big problem: he needed to have in memory (16K) a large array of costs. Each cost ranged between $0 and $10,000,000 say, whole numbers, no cents. Due to that range he was forced to use REALs, which took 8 bytes each, thus limiting the maximum capacity to less than 2,000 numbers. I suggested him compressing the numbers as alpha characters, but the packing and unpacking routines took too long to run, slowing the program to an unacceptable degree.
It seemed to me that the ideal solution would be to have the routines implemented as assembly language BASIC keywords, and this LEX file was the result.
Its main advantage is obviously the greatly expanded integer range, from 0 to 16,777,215 in just 3 bytes, compared to the normal 71B INTEGER range which stores only from -99,999 to 99,999 in 4 bytes.
The savings are 5 bytes per item compared to using REAL precision, so it allows the user to cram more than twice as much data as before in the same or less space.
Packing: A$ = PAK$(N)
where N is any numeric expression which returns an integer-valued
real in the range 0 to 16,777,215.
The result will be a 3-character string.
Execution time (aprox.): 14.6 milliseconds
Unpacking: N=UNPAK(A$)
where A$ is any string expression which returns a 3-character
string.
The result is an integer-valued real in the range 0 to 16,777,215
Execution time (aprox.): 11.6 milliseconds
Then, it should be assembled using the Assembler in that ROM, which will produce the PACK3 LEX file in memory. Once PACK3 is in memory, its keywords are available for inmediate use (don't forget to turn off and on the machine, to register the new LEX file with the 71B's operating system).
Alternatively, you may use any other 71B assembler (such as anyone written for execution on a PC) and then read the resulting LEX file from a disk. Consult your assembler's documentation for the required procedures.
LEX 'PACK3' name off the lex file: PACK3
ID #54 LEX id: 54
MSG 0 no error messages
POLL 0 no poll handling
EXPR EQU #0F23C resumes expression evaluation
FLOAT EQU #1B322 converts a decimal integer to floating point
HXDCW EQU #0ECB4 converts a hexadecimal integer to decimal
RJUST EQU #12AE2 converts a floating point to decimal integer
DCHXW EQU #0ECDC converts a decimal integer to hexadecimal
FNRTN1 EQU #0F216 returns the value of the function to the system
POP1N EQU #0BD1C extracts a floating point from the stack
POP1S EQU #0BD38 extracts a string from the stack
ENTRY DTH 1st keyword: entry in DTH
CHAR #F 1st keyword: is a function
ENTRY HTD 2nd keyword: entry in HTD
CHAR #F 2nd keyword: another function
KEY 'PAK$' 1st keyword: PAK$(N)
TOKEN 1 token 1 in this lexfile
KEY 'UNPAK' 2nd keyword: UNPAK(N$)
TOKEN 2 token 2 in this lexfile
ENDTXT end of tables
NIBHEX 811 PAK$: string function, 1 numeric parameter
DTH GOSBVL POP1N get parameter (floating point) from the stack
GOSBVL RJUST convert it to a decimal integer
C=A W copy it to C
GOSBVL DCHXW convert it to hexadecimal integer
P= 5 point to the 6th hex digit
D1=D1- 6 send digits 1st-6th to the stack
DAT1=C WP
C=0 W preparing the header: 6-nibble string
P= 0
LCHEX 60F
SETDEC
D1=D1- 16 send header to the stack
DAT1=C W
GOVLNG EXPR return to system
NIBHEX 411 2nd keyword: numeric function, 1 string param.
HTD SETHEX
GOSBVL POP1S extract string header from the stack
C=0 W extract string (6 nibbles) from the stack
P= 5
C=DAT1 WP its 6 nibbles are placed in C
D1=D1+ 6
GOSBVL HXDCW convert those 6 hex digits to decimal
GOSBVL FLOAT convert this decimal integer to floating point
C=A W
GOVLNG FNRTN1 return to system
END
It should be 90 bytes once assembled.
PAK$(4276803) gives: 'ABC'
UNPAK('ABC') gives: 4276803
Obviously, the routine can be extended to handle more or less than 3-character strings, or to include different ranges.
For instance, I have also a variation of this routine that packs numbers in the range -82.00000 to +84.77215, that is, non-integer numbers with up to 5 decimal places, in just 3 bytes. This is useful if you have a digital voltmeter connected to your 71B via HP-IL, and need to store a lot of readings from the voltmeter for later processing.
Using that modified LEX, each reading takes just 3 bytes, though it has 7-digit, 5-decimal precission.
Go
back to the software library
Go
back to the main exhibit hall