I present here some information regarding HP-71B mainframe and option ROM versions and bugs:
HP-71B mainframe versions:
HP71:1AAAA Jul, 25, 1983 12:10pm
HP71:1BBBB Sep, 2, 1983 12:11pm
HP71:2CCCC Mar, 5, 1985 12:10pm
HP71:2CDCC Mar, 5, 1985 12:10pm
Option ROM versions
HPIL:1A Sep, 12, 1983 12:00pm
HPIL:1B Aug, 7, 1984 12:00pm
MATH:1A Nov, 1, 1983 12:00pm
FTH:1A Feb, 23, 1984 12:00pm
FTH41:1A Nov, 25, 1984 01:19am
HP-71B mainframe version date can be read in the ROM at address 1dcce (hex). Versions 2CCCC and 2CDCC have the same timestamp, because only the second ROM was updated (from C to D) and the timestamp is in the fourth ROM. Option ROM dates are taken from the file dates.
A ROM version 0AAAA is known as a “prototype version”, but may have been more a development version. The date of this version is not precisely known but can be estimated to April 1983. See my observations about this version in this forum discussion.
Note also that HP considered a "HP-71A" version during the HP-71 development, differing from the HP-71B only by the amount of built-in RAM (4kb for the HP-71A, 16kb for the HP-71B). A reference to the HP-71A version can be found in an early version of the HP71 diagnostic manual, see this forum discussion.
ROM 1AAAA used code sequences such as:
to drive the OR0 to 0R3 lines at power down or power up.
The OR4 output line is connected to port 5. So it is not recommended to use a RAM module in card reader port (HHP 32K to 160K module for instance) with the 1AAAA ROM version.
698-1 NEXT in running program must check for collapsed statement buffer
issue with array parameter parsing
959-7 fix in CALC mode
960-5 unclear, related to functions
961-3 scratch registers rearranged with respect to TI%RM5
1000-9 risk of high standby current in keep-alive RAM port after shutdown (see above)
1017-3 unclear, related to quotes in expression decompile operations
1025-6 TRANSFORM copy from TAPE to RAM
1040-5 issue with SST a return with ELSE following the GOSUB
(no ref) change in address protection for PEEK/POKE
(no ref) issue with CALL/SUB with duplicate variables of different type
And of course, version 1AAAA has all the bugs of version 1BBBB!
A more detailed description of the HP-71B 1BBBB bugs can be found in this HP document, dated Feb. 6, 1985.
When current file is BINary, UDF in CALC mode cold starts.
1180-9 MERGE at low memory can cause a cold start: with ON ERROR in effect, or with current file in IRAM.
1181-7 MERGE of a line with GOTO or GOSUB can cause cold start. MERGE must be followed by RENUMBER.
1182-5 Doing MERGE & PURGE within a GOSUB can generate an "ERR:System Error".
1183-3 CHAIN can cause infinite BASIC loop.
1184-1 PACK on an HP9114 disc drive can corrupt any or all files on disc.
1185-8 PRINT#, with string item, to external file can lose remaining data.
1186-6 Funny function which creates variables in a UDF corrupts variable chain. See description below.
the bug was corrected in version 2CDCC.
The fix only involves the swap of a few nibbles in the 2nd ROM (hence the D in 2CDCC):
Address ROM 2CCCC: ROM 2CDCC:
0B4A1 167 D0=D0+ 8 167 D0=D0+ 8
0B4A4 14A A=DAT0 B 14A A=DAT0 B
0B4A7 98201 ?C>A P / GOYES #0B4BA 16A D0=D0+ 11 ||
0B4AC 118 C=R0 982D0 ?C>A P / GOYES #0B4BA ||
0B4AF 16A D0=D0+ 11 118 C=R0 ||
0B4B2 142 A=DAT0 A 142 A=DAT0 A
0B4B5 CA A=A+C A CA A=A+C A
0B4B7 140 DAT0=A A 140 DAT0=A A
0B4BA 30A LCHEX #A 30A LCHEX #A
0B4BD A6F D=D-1 B A6F D=D-1 B
0B4C0 50E GONC #0B4A1 50E GONC #0B4A1
Below is the original 1AAAA/1BBBB version. This is the end of the CR-ARR (Create Space for an Array) routine:
Address ROM 1AAAA, 1BBBB:
0B4AD 16F D0=D0+ 16
0B4B0 162 D0=D0+ 3
0B4B3 14A A=DAT0 B
0B4B6 98231 ?C>A P / GOYES #0B4CC
0B4BB 118 C=R0
0B4BE 16A D0=D0+ 11
0B4C1 142 A=DAT0 A
0B4C4 CA A=A+C A
0B4C6 140 DAT0=A A
0B4C9 18A D0=D0- 11
0B4CC 30A LCHEX #A
0B4CF A6F D=D-1 B
0B4D2 5AD GONC #0B4AD
The 2CCCC version saves 6 nibbles. I guess that due to the numerous bug fixes needed between 1BBBB and 2CCCC versions, it was necessary to optimize and pack all routines as much as possible. Unfortunately, the 2CCCC version doesn't do exactly the same thing than the 1AAAA/1BBBB version. But the HP engineers succeeded to fix it in 2CDCC version without adding a single nibble!
Many known bugs of version 1BBBB were corrected in version 2CCCC/2CDCC. I can't give more details at the moment, I need to find the IDS document for version 2CCCC, I know it existed (see here). If you have it (original or copy), please contact me!
I was able to check the status of some of the last bugs:
1179-1 fixed in 2CDCC
1180-9 not able to reproduce it with 1BBBB or 2CDCC ROM
1181-7 fixed in 2CDCC
1182-5 fixed in 2CDCC
1183-3 fixed in 2CDCC
1184-1 not a bug in the HP-71B, but rather a bug in the first release of the 9114 ROM. Don't use PACK with 9114!
1185-8 fixed in 2CDCC
1186-6 still not fixed in 2CDCC !
The last bug is still present in ROM 2CDCC. Below is a description of this bug, from an internal HP bug report document:
Description: Creation of variable during funny function execution can
Example using FNROOT in MATH pac:
10 DESTROY ALL
20 DIM F(9), A$(9)
30 J=6 @ V=0 @ DISP J;V ! Compare the value of V ...
50 DISP J;V @ STOP ! ... with this value.
60 DEF FNY @ BEEP 500,.2 ! Just to count the FNY calls.
70 V=V+1 @ F(6)=FVAR @ Z6=1/V-.9 ! Stuff to make FNROOT work.
80 DIM Z$ ! This is the killer!
90 FNY=Z6 @ END DEF
Running the program will call FNY about 12 time; you can count the
beeps. Line 40 displays: 6 0
but line 50 displays: 6 0.00001001
Replace DIM Z$ with DIM Z$, and line 50 shows: 6 1.
Replace DIM Z$ with DIM Z$, and line 50 shows: 6 14
Creating a variable within a UDF called by a funny function causes the
address of the pending assignment (F(6) in the example above) to
become invalid. The assignment is made, and, in this case, it happens
to be where V resides. Which variables get corrupted, or where, depends
on the length of the new variable -- that's why the length of Z$ affects
the new "value" of V.
Dimension all the variables before you execute a funny function
which calls a UDF.
For example, instead of creating the variables Z6 and Z$ within the
UDF, create it on line 20:
20 DIM F(9), A$(9), Z6, Z$
Now the program will run correctly, with no corruption of variables.
This french addendum for ROM 1BBBB describes the bug referenced as 1110-6 above, and the relevant workarounds:
ON FNJ(T) ^ SIN(M) GOSUB 500, 600, 700
A = FNJ(T) ^ SIN(M)
ON A GOSUB 500, 600, 700
This document provides the full content of the chapter 8 (System Diagrams) that is not provided elsewhere.
HP-71 Hardware IDS Chapter 8, System Diagrams (PDF File, 0.9 Mb).
The list below is based on a french addendum and describes the main bugs found in the HP-IL ROM version 1A.
1 - ENTER: if an under or overflow condition may occur during the entry of numeric data, either enter numeric data into a string variable and then use the VAL function to generate the numeric value, or else don’t suppress warning messages (don’t set flag -1) and don't put other variables after a numeric variable in an enter list.
For example, you can replace:
with either of the techniques below:
A=VAL(A$) @ B=VAL(B$)
2 - OUTPUT and PRINTER IS: avoid the remote
possibility of a Memory Lost condition during OUTPUT and PRINT operations by
taking either of the following precautions:
* use ENDLINE to set the end-of-line sequence to be either zero or three characters long,
* or use OUTPUT and PRINT statements that don't send end-of-line sequences (such as ending the statements with ';' and also setting an infinite print-width for PRINT.
3 - CAT and CAT$: avoid certain conditions that can
cause a Memory Lost condition during a catalog operation by taking either of
* don't press any keys while the mass storage device is busy (while its BUSY light is on),
* or be sure that the first file on the medium isn’t purged (such as by packing the medium whenever you purge the first file).
4 - PACK and PACKDIR: avoid the possibility of a Memory Lost condition while packing a medium by NOT using a user-defined function in the device specifier.
and 3 were the most serious ones. I remember that in these old good days I was
always using a 3-character end-of-line sequence: ENDLINE CHR$(13)&CHR$(13)&CHR$(10)
(bug 2). It was also a good practice to create a dummy first file just after
disc initialisation to protect against bug 3.
See also below why PACK and PACKDIR should be avoided with the HP9114 (i.e. they are not safe workarounds for bug 3).
I compiled a more complete list of ROM 1A bugs from an analysis of the HPIL 1B IDS.
HP82402A owner’s manual addendum
provides updated information on the use of the dual HP-IL adapter and
limitations with the HP-IL ROM version 1A.
In case of using both a module 1A and a module 1B in the dual HP-IL adapter, HP recommends to put the module 1B in the first position (lower position) for the newest version to take precedence. However, if the JPC ROM is present too, the module 1B must be in the high position to correctly take precedence. This can be checked by using the VER$ command: HPIL:1B must appear before HPIL:1A.
HP-IL ROM version 1A has two major bugs related to mass storage initialization.
These two bugs occur with drives supporting the “extended Filbert
protocol”, introduced with the HP9114. The extended Filbert protocol adds
commands to let the controller know the physical size and geometry of the
The two bugs are:
- the directory length is incorrectly set when using no explicit directory size in INITIALIZE,
- the drive geometry is not correctly read, and the values written on the medium by INITALIZE are wrong.
The bugs are documented and fixed in the HP-IL IDS (version 1B), module CAS page 7 and page 11 respectively.
The interesting thing about these bugs is that there are completely hidden by the HP9114. The drive seems to implement a validity check and replace abnormal values with correct values. This is why these bugs have not been reported before and were not known by users. However, the bugs can show up when using mass storage emulations (such as ILPer) with a HP-IL ROM version 1A.
The bugs have been identified by Sylvain Côté during tests of ILPer and investigated by myself, Christoph Giesselink and Sylvain. They have been briefly reported on the MoHPC forum.
3rd and last edition of the HP-IL manual dated January 1985,
incorrectly mentions on page 241 two error messages
(255021 “Low Battery” and 255029 “Medium Protect”) that
are not mentioned in previous editions of the HP-IL manual. These error
messages are actually not present in the HP-IL modules version A or B.
The reason of the addition of these non-existing messages in the edition 3 is unknown.
also that all user manual editions incorrectly mention the error message 255027
“End of File” (page 238 of the 3rd
edition) that is not present in the HP-IL modules version A or B.
Another mistake in the HP-IL user manual (all editions) is that the type of a secured text file is not -7979 (0xE0D5) but -7983 (0xE0D1) as defined in the source code (HP71 IDS, module TAB page 4). This mistake is also found in other documents, for instance in the Forth/assembler ROM manual.
This document provides updated pages for the Internal Design Specification of the HP-71 HP-IL module. It is applicable to the version 1.0 preliminary IDS dated January 1984.
The updated pages come from the IDS release, HP Part No. 82401-90023, dated March 1984.
Note that the actual HP-IL ROM 1B, dated August 1984, exhibits some differences even versus this IDS update in the Display Driver module, the changes are hand-written on the updated pages.
HP-IL IDS Vol.2 update (PDF File, 0.8 Mb).
HP-IL ROM source files version 1B build <840807>
Although no real bug are known, some unexpected behaviours have been noted:
One case of FNROOT failure (actually FNROOT doesn't terminate in a sensible delay) was reported by V.Albillo (Datafile V24N1, 2005):
FNROOT(0, 0, FVAR * FVAR + 1)
FNROOT still didn't terminate after more than 30 minutes with Emu71@1.7GHz, equivalent to about 10 days with real HP-71B.
R. Rosenbaum noticed that FNROOT does terminate in this case if OPTION ROUND POS is used.
Instead of MAT B=INV(A), it is better to do MAT B=SYS(A,I) where I is an identity matrix of same size than A and B.
A = [[1 2][3 4]]
MAT B=INV(A) gives
B = [[-1.99999999998 .999999999994][ 1.49999999999 -.499999999997]]
but MAT B=SYS(A,I) gives:
B = [[-2 1][ 1.5 -.5]]
· DET function
DET may produce a non-integer answer for an integer matrix:
A = [[1 2][3 4]]
DET(A) gives -2.00000000001 instead of -2.
DET may produce weird outputs for a non-invertible (ill-conditioning) matrix:
A = [[0 1][0 0]]
DET(A) gives the correct answer (0), but with the message "Warning: Overflow"
A = [[0 0][1 0]]
DET(A) gives -0.
The assembler in the Forth/Assembler module has the following bugs:
fix of the first two bugs can be easily done by patching the ROM code: Forth assembler fix (note that patching
“ROM” code is only possible in emulators or using a FRAM71 module).
Here is a simple test to check these two
bugs and the fix.
The remaining bugs are minor. The third bug has a simple workaround (as mentioned above) and the last two bugs are described in the chapter 12 of the Forth IDS.
Note also that the D0=HEX and D1=HEX undocumented (but accepted) opcodes don’t work correctly.
A list of JPC ROM features and bug fixes for versions A to F, is described in this JPC ROM version history.
unofficial JPC ROM fix was made by Rodger Rosenbaum as version 'X' circa 1992,
based on the version 'D'. It is described in this
note from J.K. Horn.
A remaining known bug in version X was related to date functions dealing with leap years: e.g. DOW$("02.291999") incorrectly returns "Monday" instead of an error.
A serious bug was introduced in version X: the RED$ and CENTER$ functions crash the HP71 if the argument is a null (“”) or space-only (“ ”) string.
The last version ‘F’ (2007) merges the fixes and improvements of versions X and E together, plus a few extra changes. Revisions up to F04 have the RED$/CENTER$ bug mentioned above, that has been fixed in revision F05.
For more details on the JPC ROM, please have a look at my JPC ROM page.
If you have more information on HP-71B system versions or bugs, please contact me :
J-F Garnier, 2017