tHP-15C fans --

After preparing this lengthy post over the past few days, I checked Craig Finseth's site, which states that 1 July, 1982 was the date of introduction for the HP-15C. Therefore, __today__ is its **25th anniversary** of its public availability for purchase!

http://www.finseth.com/hpdata/hp15c.html

At the upcoming HHC conference in San Diego, we enthusiasts ought to hold an HP-15C silver anniversary observance as an "undercard" to the HP-35 35th anniversary theme.

The HP-15C offers exactly 700 programmable instructions stemming from well over 100 functions, all without benefit of *bona fide* alphanumerics. It is instructive to examine the fine engineering work that was done, more a quarter-century ago, to make this possible.

A complete instruction stored in program memory is identified by a unique operation code, or "op-code". These are not to be confused with __key__ codes on 7-segment displays, which show the sequence of keystrokes for a programmed instruction using key identifiers that are usually numeric, but are sometimes a individual letter.

Relation and arrangement of op-codes to functionality is an important design consideration for a programmable calculator. Logically-selected codes facilitate testing and processing. Moreover, an insufficiency of available op-codes will restrict the amount of programmable functionality provided for the user.

First, some background: There are 2^{8} = 256 unique one-byte op-codes. The "starting point" for the HP-15C -- namely, the HP-34C and HP-11C -- each use 255 codes for programmable instructions, with one spare code presumably by design, and a few possibilities omitted by necessity. For example, the HP-34C's sophisticated functions SOLVE and INTEG can be invoked with user-defined programs starting with labels A, B, 0, 1, 2, or 3, but __not__ labels 4 through 9. This restriction due to insufficient op-codes caused William Kahan to make a selective statement in his fine article "Handheld Calculator Evaluates Integrals," in *Hewlett-Packard Journal* , 31:8, August 1980:

Quote:

Some constraints ... are nuisances, such as 'Begin the f-program with a special label such as A'. The (INTEG) key is encumbered with no such nuisances. The f-program may begin with any of several labels...

Left unsaid was, "but not __all__ the labels..."

The HP-11C has only flags 0 and 1, omitting flags 2 and 3 that its predecessor HP-34C had. This saved six operations, to get the HP-11C under 256 programmable instructions.

A concise list of differences between HP-34C and the HP-11C programmable instructions is found in the following post within a long thread containing technical insights from Eric Smith:

http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv016.cgi?read=98494#98494

Which brings us back to the HP-15C: With all the functionality of the HP-11C, plus SOLVE and INTEG from the HP-34C, pioneering matrix-based and complex-number functionality, as well as extensions of traditional functions, clearly the uniform single-byte op-code would not be sufficient. If the byte were to remain the standard unit of size, some op-codes would require two bytes -- similar to what was done for the HP-41C. Given the limited RAM of the HP-15C (a maximum of 448 bytes programming space), the two-byte codes would need to be intelligently selected, such that the most commonly-used instructions would have one-byte codes.

The complete set of one- and two-byte HP-15C op-codes was revealed in an excellent article published not long after the HP-15C's introduction in mid-1982: "Synthetic Methods on the HP-15C" by Allyn F. Tennant. *PPC Calculator Journal*, Volume 10, No. 1, January/February 1983, pages 49-53.

An easily-created synthetic matrix pointing to base of the pool of allocatable memory (and not simply the storage of the matrix itself) allowed direct viewing of the operating codes of entered programming instructions. Here's an example:

- Clear all program memory [CLEAR PRGM], clear matrix data [MATRIX 0], and exit complex mode [CF 8]
- Set R19 as the highest-numbered register [19 DIM (i)]
(NOTE: A master clear -- turning on while holding down the "-" key -- would accomplish all of the above.)

- Type 1.000000044, turn calculator off, then turn it back on while holding down the y
^{x}key - Store the (non-letter) descriptor of the resulting matrix to the indirect register [STO I]
- Dimension matrix A as 1x23 [1, ENTER, 23, DIM A]
- Set the matrix pointer to 1,23: [1, STO 0, 23, STO 1]
- Enter program mode and key in the following instructions: DIM I, GTO 0, x
^{2}, DSE 0, RCL*I, LBL 3 - Exit program mode and display the register containing the programmed instructions using [RCL (i)]. In default display mode (FIX 4), the display reads
"4.4536 99"

- View the mantissa by holding down [CLEAR PREFIX]. The display reads
"3PEo 82-r1"

The complete hexadecimal contents of the register are "03DECF82BA1099". Here is a complete breakdown:

display hex value representing

(N/A) 0 Left nibble of "LBL 3" (1-byte code "03")

"3" 3 Right nibble of "LBL 3" (1-byte code "03")

"PE" DE 2nd byte of "RCL*I"

"o " CF 1st byte of "RCL*I"

"82" 82 "DSE 0" (1-byte code)

"-r" BA x^{2}(1-byte code)

"1" 1 Left nibble of "GTO 0" (1-byte code "10")

(N/A) 0 Right nibble of "GTO 0" (1-byte code "10")"99" 99 "DIM I" (displayed in exponent field)

The "DIM I" instruction is displayable as the exponent of the full floating-point number. As stated, the left nibble of the "LBL 3" and the right nibble of the "GTO 0" instructions are not directly displayable. For numbers, these nibbles contain signs for the mantissa and exponent (among other information, such as matrix identifiers and LU decompostion status).

Here's the principle of the synthetic matrix: The ON/y^{x} processor-reset operation rotates the 56-bit content of the x-register 22 bits to the right. So,

1.000000044 (float) =0000 0001 0000 0000 0000 0000 0000 0000 0000 0

100 0100 0000 0000 0000 (DCB)

becomes

000100010000 0000 0000 0000 0100 0000 0000 0000 0000 0000 0000 0000 (DCB)

after rotation. The first "1" indicates a matrix descriptor; the second "1" is the matrix identifier, which is __not__ among the standard set of A through E that are encoded correspondingly in hexadecimal. (The value "1" in the mantissa is included to prevent automatic normalization to an exponentiated value, which would change the bit pattern.)

The selection and arrangement of the complete set of HP-15C 1-byte and 2-byte op-codes found respectively in Figures 3 and 4 of the PPC article exhibit the thoughtful planning, logical grouping, and overall attention to detail also found in the arrangement of the HP-15C keyboard. Here are some observations:

__One-byte codes:__

- If the right nibble is hex F, then the byte is the first of a two-byte instruction. This enables BST to find instructions quickly (an improvement over the HP-41), but eliminates 16 possible 1-byte op-codes, leaving 240 such codes still available.
- Instructions whose value, register, or label is 0-9 have the corresponding hex value 0-9 as the right nibble. This holds for LBL, GTO, GSB, RCL, STO, TEST, and the numbers 0-9.
- RCL and STO using registers .0-.9 have the corresponding hex value 0-9 as the right nibble.
- Instructions whose value or input argument is A-E have the corresponding hex value A-E as the right nibble. This holds for LBL, GTO, GSB, RCL, STO, RCL g, STO g, RCL MAT, RES, DIM, and RCL DIM.
- RCL MAT A-E uses five 1-byte codes because these instructions would be used routinely for matrix-based calculations. (STO MAT A-E would be used only for
*copying*entire matrices, and are 2-byte codes.) - x< >, DSE, and ISG using register number 0, 1, I, or (i) as an argument are included as 1-byte instructions, whereas the same functions using a different argument are 2-byte instructions. The R0, R1, and I registers, which are non-allocatable and don't store statistical summation values, are always available for these functions.
- Most transcedental-function commands are grouped in the op-code table in the same way that they are located on the keyboard.

__Two-byte codes:__

- There are a total of 460 2-byte op-codes, which exceeds the 256 codes that a second table would provide. Thus, the second byte of some 2-byte codes matches a 1-byte code, making the left nibble of the 1st byte necessary for uniqueness. With the right nibble of the 1st byte being hex F, the 2-byte op-codes are essentially 3-nibble codes, most of which are unused.
- All eight register-arithmetic commands can be used with 0-9, .0-.9, A-E, (i), and I. Because this creates a set of
**216**unique instructions, the instructions are 2-byte -- which is justified anyhow, given that STO and RCL arithmetic functions encompass two or more simple instructions. (RCL arithmetic is unavailable on the HP-41 as well as the HP-34C and HP-11C, which offer only 44 register-arithmetic instructions: STO #0-9 and STO #(i), where # is an arithmetic operation). - LBL, GSB, and GTO with arguments .0-.9 are basically extensions of the corresponding one-byte codes for the arguments 0-9, the only difference being the pre-pended 1st byte: hex FF.
- RCL and STO of matrix elements in user mode are 2-byte. The codes were selected so that the 2nd byte matches the single byte of the corresponding instructions
__outside__user mode, the only difference being the pre-pended 1st byte: hex BF. - Indirect matrix access using stack pointers -- RCL g (i), STO g (i) -- is encoded to correspond with "RCL g D" and "STO g D", the only difference being the pre-pended 1st byte: hex AF: i.e., AF5D and AF6D versus 5D and 6D.
- All SOLVE and INTEG commands are 2-byte. These are infrequent in programs, but account for 50 unique instructions, as they are usable with
__all 25__labels (not just a few, as with the HP-34C). - Flag operations and display-mode settings are 2-byte, as these account for 66 unique instructions. (The HP-15C has
__10__flags, with access through the indirect register I as well.)

NOTE: There is a list of two-byte instructions on page 218 of the HP-15C Owner's Handbook. This list, however, omits [GSB][.]* label* , x< > {A-E}, DSE {A-E}, and ISG {A-E} -- the only mistakes I've ever found in that manual.

Of course, a picture is worth a thousand words; the preceding discussion is much easier to follow with the PPC Journal article and its tables at hand. The article is well worth perusing, and there's __much__ more in it than I have discussed -- including a demonstration synthetic program that displays "HEllo PPC" in the display!

The article, included within the PPC archives, is available as the 10154-kB file "v10n1.pdf" on CD #1 from Jake Schwartz at http://www.pahhc.org/ppccdrom.htm, or on the Extended Archive DVD available from another site.

Tables of op-codes for the HP-11C, HP-34C, and two-byte op-codes for the HP-15C are available at Eric Smith's web pages:

http://www.brouhaha.com/~eric/hpcalc/

http://www.brouhaha.com/~eric/hpcalc/hp15c/two_byte_instructions.html

-- KS

*Edited: 4 July 2007, 1:58 a.m. after one or more responses were posted*