This program was written by Valentin Albillo and is used here by permission.
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
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