HP-71B ROM Versions and Bugs

Return to main page

I present here some information regarding HP-71B mainframe and option ROM versions and bugs:

HP-71B Mainframe and Option ROM Versions

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.

Differences between versions:


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.



HP-71B ROM 1AAAA bugs

The standby current bug, as described in the 1BBBB source code (ROM 1 Fix Module):


The 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.

Some 1AAAA bug fixes mentioned in the 1BBBB IDS:

957-1 issue with array parameter parsing (TI&FX1 ROM 1 Fix Module)
959-7 fix in CALC mode (AB&CLC Calc Mode p21,23)
960-5 unclear, related to functions (AB&FCN Functions p13, TI&FX2 ROM 2 Fix Module)
961-3 scratch registers rearranged with respect to TI%RM5 (AB&FCN Functions p15)

997-7, 998-5, 999-3 RUN/CONT/CHAIN fixes (JP&SYS System Commands, RUN Loop p5)
1000-9 high standby current in RAM port after shutdown, see above (SB&DRV Main Driver p27,37)
1017-3 related to quotes in expression decompile operations (SB&EXD Expression Decompile p4,27, ROM 1 Fix Module)
1025-6 TRANSFORM copy from TAPE to RAM (FH&TFM Transform Execution p11)
1040-5 SST a return with ELSE following the GOSUB (SG&EXC Misc. Exec. Routine p47,43, ROM 2 Fix Module)
(no ref) change in address protection for PEEK/POKE (SG&POK POKE Statement Exec. p13, ROM 4 Fix Module)
(no ref) CALL/SUB with duplicate variables of different type (SC&SUB SUBprog. and DEF FN p22, ROM 4 Fix Module)

(no ref) random access PRINT# bugs (SC&DAT Store & Retrieve data - PRINT# p3,43,60)

HP-71B 1AAAA Owner's Documentation Addendum

This addendum for the HP-71B version 1AAAA describes several bugs and workarounds (known HP bug numbers added):

Using Random Access to Store a String in a DATA File (no ref - see above)

Calling a Subroutine That Creates a File in RAM   (1103-1°)

Single-Stepping through ...GOSUB ELSE...  (1040-5)

Using DATE$ In an Expression   (1078-5°)

Changing the OPTION BASE Setting Within a User Defined Function   (985-2°)

Attempting transformation of Tape File    (situation 2: 1025-6)

Chaining a File from Tape 

Copying a Program from a Magnetic Card

Copying a TEXT File from a Magnetic Card

Using CHAIN :CARD in a Program

Using PROTECT and UNPROTECT in a Program

Using a Complex Subscript for an Array

Using READ# to Read Data into a Complex Variable   (1082-7°)

Using an Expression Like (1,2,3,4,5,6,7,8) in CALC Mode  (1095-9°)


° also present in version 1BBBB, see below


And of course, version 1AAAA has all the other bugs of version 1BBBB !

HP-71B ROM 1BBBB bugs

Note: "UDF" means "User Defined Function".


A more detailed description of the HP-71B 1BBBB bugs can be found in this HP document, dated Feb. 6, 1985.

More bugs:
(source: internal HP documents, Feb. 2, 1986)

1179-1 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.

HP-71B ROM 2CCCC bug


Actually, 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!

HP-71B ROM 2CDCC bug

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!

However, 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:

1186-6: Funny function which creates variables in a UDF corrupts variable chain.

Description: Creation of variable during funny function execution can
             corrupt memory.
Example using FNROOT in MATH pac:
   20 DIM F(9), A$(9)
   30 J=6 @ V=0 @ DISP J;V           ! Compare the value of V ...
   40 F(6)=FNROOT(10,12,FNY)
   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$[34]                     ! 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$[34] with DIM Z$[38], and line 50 shows: 6  1.
Replace DIM Z$[34] with DIM Z$[78], 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$[34]
  Now the program will run correctly, with no corruption of variables.

HP-71B User Manual Addendum

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

HP-71B Hardware Internal Design Specification

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).

HP-IL module

HP-IL ROM version 1A bugs:

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:
  ENTER 2;A$,B$
  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 these precautions:
* 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.

Bugs 2 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.

HP-IL ROM version 1A limitations with the dual HP-IL adapter:

This 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 bugs with mass storage initialization (hidden by HP9114 firmware):

The 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 medium.
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 implements a validity check and replace abnormal values with correct values, see the description of the format command in the HP9114 firwmare document page 30. 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 on 2014 and investigated by myself, Christoph Giesselink and Sylvain. They have been briefly reported on the MoHPC forum on 2015.


The PACK command in the HP-IL ROM (both A and B versions) must be avoided if files may be added later by a HP-41. This problem is known since a long time, for instance see here a discussion of the problem.

Another problem with PACK is documented as bug 1184-1 in this document. Here is a transcription of the description (hard to read on the original document):
Description: PACK on an HP9114 disc drive can corrupt any or all files on the disc.
The problem:
This is not a bug in the HP-71, but rather a bug in the first release of the 9114 ROM. It has been fixed in current release drives.
The bug is that the 9114 does not properly emulate the HP82161 correctly for the "CLOSE RECORD" DLL command. If the last mode was not "write to buffer" the disc does NOT write the data to the medium when the close record is received, while the HP82161 does. The HP-71 (and the 75!) depend on close record always writing the data to the medium to pack it, so this bug causes destruction of data.
The effect of this bug is that the PACKDIR command on the HP-71 becomes a time- ? ? . PACK calls PACKDIR initially, then assumes that there are no PURGED files left in the directory. As this assumption is not correct in the (buggy version of the) 9114, data is lost as files may be moved *farther out* on the medium.

HP-IL ROM end-of-directory bug:

This bug is mentioned by J.K. Horn in the Titan File #16 (HPX Exchange, V2 N1, Jan 1989, page 15; or Titan File Collection):
"The HP-71's HPIL module (both A and B versions) has a bug that allows a disk catalog to contain one too many entries. If this occurs, the first record of the contents of the first file on the disk gets erased."

Actually, the bug is that the end-of-directory mark overrides the first 32 bytes of the first file, when the directory gets full.
It is pretty easy to reproduce the bug by doing INITIALIZE ":TAPE",8 then copying 8 files on :TAPE. The first file is then corrupt.
I found the cause of the bug in the NEWFIL function in the HPIL IDS, module CAS.

Workaround: create a dummy first file (e.g. CREATE DATA DUMMY:TAPE,1) after INITIALIZE.
It is even better to set the name of the dummy file in lower case, so it can't be accessed or purged. There are many ways to do it, but an easy one with the JPC ROM (after INITIALIZE and CREATE dummy file) is:
DIM A$[256] @ A$=RREC$(2,":TAPE") @ A$[1,10]="dummy     " @ WREC A$,2,":TAPE"

HP-IL user manual (edition 3, January 1985) incorrect information:

The 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.

Note 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.


HP-IL Internal Design Specification Update

This is the IDS release, HP Part No. 82401-90023, dated March 1984.

Note that the actual HP-IL ROM 1B, dated August 1984, exhibits some code differences in the Display Driver module, the changes are hand-written on the updated pages of the volume 2.

HP-IL IDS Vol.1 March 1984 (PDF File, 66 MB).

HP-IL IDS Vol.2 March 1984 includes the March 1984 updated pages (PDF File, 42 MB).

HP-IL IDS Vol.2 update  updated pages for the IDS Vol.2 preliminary version dated January 1984.

HP-IL ROM source files version 1B build <840807>

Math Module 1A

Although no real bug are known, some unexpected behaviours have been noted:

·         FNROOT

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.

·         INV

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.

e.g. inverting the matrix [[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:

e.g. with A = [[1 2][3 4]]
DET(A) gives  -2.00000000001 instead of -2.

  DET may produce weird outputs for a non-invertible matrix:

e.g. 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.
·         internal summation weakness

The Math ROM 1A also has a weakness related to the internal 15-digit summation operation used in matrix operations.

The issue is that the Math ROM is using a 15-digit truncating addition instead of rounding each addition result.

For example, computing DOT([-10000 (1/3) 10000],[1 1 1]):

this operation computes (-10000)+(1/3)+(10000) with 15 digits and should return .33333333333
but the Math ROM 1A is returning .33333333334 .

This weakness is causing the HP-71B Math ROM 1A to deliver answers that may be slightly different from later Saturn-based machines (starting with the HP-28C) for several matrix operations using summations such as dot product, matrix product and inversion, determinant and system solving.

For example, computing the determinant of the matrix [[69 58 96][51 43 71][32 55 54]]:

this operation returns  1.00000038313 on the 71B,
the 28S and 42S return  1.00000038333 instead.

This is not considered as a bug since the answer is not clearly wrong, but the Math ROM 1A is not always consistent with later machines.


For more information on the Math ROM, please have a look at my Math ROM page.


FORTH/Assembler Module 1A Bugs

The assembler in the FORTH/Assembler module has the following bugs:


A 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.


Another small bug is that the FORTH Assembler generates null-bytes at the end of some lines in the assembly listing. This can be noticed when using Emu71 or ILPer, see here for a discussion.


The actual assembler message #36 (i.e. MSG$(47036)) in the ROM is "too many ascii chars present", not in accordance with the owner's manual and the FORTH LEX source file that both describe the message as "too many ASCII chars present" (ASCII in upper case).


For an updated version usable in emulators, see my page with the FORTH/Assembler revision B.


JPC ROM Versions and Bugs

A list of JPC ROM features and bug fixes for versions A to F, is described in this JPC ROM version history.

An 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, 2021