HP35: A Bit-Serial Wonder - 1. Introduction

Part1. Introduction

In this section, we will have a brief look at the ISA of the HP35, the first look into the system.

(The top image is a part of the cover of the advertisement brochure: HP35 technical data)

Note: To better understand this article, you need basic digital circuit and computer architecture knowledge. I'd recommend you read DDCA to have a brief look at both.  The youtube video: How a CPU Works, is a very basic tutorial on CPU structure. Check 'em out!

FIG1. The HP 35 Internal Structural shown in HPJ 1972 issue 6.

FIG2. The HP 35 Motherboard (Source: the HP35 saga)

The HP35 architecture is very unique compared to the "classical" architectures. To understand what makes it tick, we can begin with the ISA. There's a page on hpmuseum.org that has a very comprehensive description of it.

In this passage, everything(register notion, mnemonics) will be written in the patent document format.

Arithmetic Registers

The original HP35 has 7 56-bit "arithmetic registers": A, B, C(X), D(Y), E(Z), F(T), and M. Each arithmetic register can hold 14 4-bit BCD encoded decimal number.

These registers are located in the ARC(Arithmetic and Register Circuit, also known as the A&R) chip. They are not usual general purpose registers, the transfers between them are very limited. As shown in the patent document of HP45

Fig3. The register transfer map (in ARC)

D, E, F are "stack registers" that can only be pushed or popped

A, B directly control the display when the display is enabled (More on that later)

In this map, only the registers in ARC is shown(which is one half of the CPU), no Program Counter or FLAGs register made their presence. Because in the original design, those registers belong to another half of the CPU: the CTC(Control and Timing Circuit, also known as the C&T) chip.

Control Registers (only the important ones)

[P(4)]: the pointer register, we'll talk about its use in the Word Select feature after this section.

[STATUS BITS(12)]: Just like a FLAGs register found in other CPUs. This register can be set, reset, tested, one bit each machine cycle.

[ROM ADDRESS(8)]: The Program Counter, Contains the address of the instruction that's to be fetched in this cycle. This register can only be set by the JSB (Jump to SuB) or BRH (BRancH) instruction.

[RETURN ADDRESS(8)]: You can RTN to this address after jumping to a subroutine via JSB.

[SYSTEM COUNTER(6)]: This register was designed for timing purpose. It's a 56-state self-increment counter that can be decoded for many timing control signals in the system. All chip mentioned(ARC, CTC, and ROM) contain their own version of the system counter(potentially implemented in different ways). They are synced by the SYNC line mastered by the CTC.  This register can't be directly accessed by the programmer.

[KEY-CODE BUFFER(6)]: Once a key is pressed, this buffer will be filled with the content of the [SYSTEM COUNTER] (as mentioned, the sys counter was for timing purpose, the keyboard is accessed one by one in a machine cycle, and a pressed key will make its presence at a specific time. We can determine the pressed key's keycode by looking at the timing register.), this register can't be directly accessed by the user in earlier models.

All of these registers made their presence in the CTC chip.

There're many single-bit flip-flops in the design. A noticeable one is the :

[ROM ENABLE FF]: Each 256*10bit ROM chip contains one of these. The ROM chips are hard-wired to respond to one of the 8 possible ROM SELECT instructions. And these FFs will be set or reset to determine whether the current ROM is enabled or not. In HP35, there're 3 ROM chips. Later models contain QUADROM chips that, as the name suggests, contains 4 independent ROM chips.

Arithmetic Feature

BCD Arithmetic: In earlier HP models, everything is done in "decimal" fashion. The ARC only does 4-bit BCD arithmetic and no hexadecimal result should be found in those register (Later models added binary mode, enabling binary calculations).

HP assigned specific meaning for every section of a 56-bit arithmetic register, those sections were called "Fields". A picture from hpmuseum shows it clearly:

FIG4. Fields

(The "Sign" and "Exponent Sign" fields are also 4-bit BCDs. digit "9" represents the negative sign.)

One might think that those "fields" have no real meaning, and the programmer can give their own version of field assignment. This is sometimes true, but the hardware was designed in a way that made this field division the most optimistic (for floating point arithmetic). We'll see why in a moment.

There're 8 fields defined(copied from hpmuseum):

M 001 Mantissa
MS 101 Mantissa and Sign
X 010 Exponent
XS 110 Exponent Sign
S 111 (Mantissa) Sign
P 000 Pointer (The nibble indicated by the P register)
W 011 Word (the entire register)
WP 100 Word up to and including nibble indicated by P register from right to left. For example, if P=3, WP would refer to nibbles 0, 1, 2, and 3.

WS: WS or "Word Select" is a very unique and important feature of HP calculator architectures.The programmer can decide which part of the register that is the destination of an arithmetic operation "can be changed", and the non-WS'd part will remain the same.

An example: Say if we want to shift left only the mantissa part of register A. We can execute the instruction "SHIFT LEFT A [M]" where "[M]" stands for the Mantissa Field.

Before: 01234567890123

After: 02345678900123

(Hexadecimal, remember we're talking about BCD numbers)

Fascinating! This "WS" feature is available for almost any operation that's executed in the ARC chip. Including "reg1 EXCHANGE reg2" and "0 -> reg". This feature has made HP architecture extremely powerful when it comes to decimal floating point arithmetic.

But I can't help thinking: how's that possible? It would be over-complicated if you're about to implement it in a parallel fashion. 4bit by 4bit serial micro-coded calculation is also not very elegant. But after we have a look at the "bit-serial" architecture that's going to be discussed in the next article. You'll immediately see why this feature made its presence. And how easy it is to implement such a feature in this architecture.


As mentioned, the calculator supports up to 8 ROMs paging. With 8-bit addressing capability, the calculator is capable of handling 2048 words ROM access. (Later models even added "ROM banking", each ROM bank can contain up to 8 ROMs.)

The HP architecture only supports direct addressing. Namely:

  • JSB address,
  • BRANCH address: Also known as "GOTO address", actually"IF NO CARRY GOTO address"
  • KEY -> ROM ADDRESS: A special one.

The first four are quite general, but the last one is special. It actually substitutes the content of [ROM ADDRESS] register by [KEYCODE BUFFER] (with 2 zeros to make an 8-bit address) to jump to the address indicated by the keycode.

By today's standard, the ROM paging method in early HP models is horrific. First of all, bear in mind that it has no indirect addressing capability, and the programmers have no way to do manual indirect addressing using the "compare and jump" method since there're only have 256 instructions per page, 3 working registers, and no RAM. The reason why I said it's horrific is that after a "ROM SELECT n", the program counter remains the same (+1). Get it?

After this programming nightmare (I can hear the HP engineers saying "Fk it, that's how your grandpa did programming in the 70s, kid."), in later models a set of "DELAYED SELECT" instructions were added, allowing programmers to trigger a ROM select but change the ROM page only when a jump instruction is fetched sometime after the "DELAYED ROM SELECT n" instruction.

Try it out

CCE33 written by Tony at teenix.org is a full-featured microcode emulator and development environment for the entire LED classic series. The software allows you to see into a calculator, modify and interpret the assembly code, do dynamic memory monitoring and edit registers directly. On his website there're microcode files for almost every HP LED calculators ever made.

The author has also written a PIC based emulator called MultiCalc. One can connect the hardware to PC and download modified microcode to it thru CCE33. You can purchase a kit on his website, or with the files he released, you can make one yourself.

HP35 Instruction List

The detailed instruction list is very long. The following content is based on the opcode map provided by George Weigt in this forum article. HP45  specific (RAM chip access)  opcodes were omitted.

Type 00 Misc Instructions
Opcode Mnemonics Description
0000_0000_00 NO OPERATION
nnnn_0001_00 1 -> Sn Set status bit n
nnnn_0011_00 n -> P Set P register
nnn0_0100_00 ROM SELECT n Switch to ROM page n
0011_0100_00 KEY -> ROM ADDRESS Jump to KEY
nnnn_0101_00 IF Sn = 0 Check status bit n
0000_0111_00 P - 1 -> P Decrement P register
nnnn_1001_00 0 -> Sn Clear status bit n
00001_010_00 DISPLAY TOGGLE
00101_010_00 C EXCHANGE M
01001_010_00 C -> STACK
01101_010_00 STACK -> A
10001_010_00 DISPLAY OFF
10101_010_00 M -> C
11001_010_00 DOWN ROTATE Just like the RDN key on the keyboard
11101_010_00 CLEAR REGISTERS
nnnn_1011_00 IF p # n
0000_1100_00 RETURN Return from a subroutine
0000_1101_00 CLEAR STATUS Clear all status bits
0000_1111_00 P + 1 -> P Increment P register
Type 01 & 11 Branching Instructions
Opcode Mnemonics Description
aaaaaaaa_01 JSB addr Jump to address, store return address
aaaaaaaa_11 (THEN) GO TO addr If no Carry, jump to address
Type 10 Arithmetic Instructions
Opcode Mnemonics Mnemonics(HP41 style)
00000_fff_10 IF B[f] = 0 ?B#0
00001_fff_10 0 -> B[f] B=0
00010_fff_10 IF A >= C[f] ?A<C
00011_fff_10 IF C[f] >= 1 ?C<1
00100_fff_10 B -> C[f] C=B
00101_fff_10 0 - C -> C[f] C=-C
00110_fff_10 0 -> C[f] C=0
00111_fff_10 0 - C - 1 -> C[f] C=-C-1
01000_fff_10 SHIFT LEFT A[f] A SL
01001_fff_10 A -> B[f] B=A
01010_fff_10 A - C -> C[f] C=A-C
01011_fff_10 C - 1 -> C[f] C=C-1
01100_fff_10 C -> A[f] A=C
01101_fff_10 IF C[f] = 0 ?C#0
01110_fff_10 A + C -> C[f] C=A+C
01111_fff_10 C + 1 -> C[f] C=C+1
10000_fff_10 IF A >= B[f] ?A<B
10001_fff_10 B EXCHANGE C[f] BC EX
10010_fff_10 SHIFT RIGHT C[f] C SR
10011_fff_10 IF A[f] >= 1 ?A<1
10100_fff_10 SHIFT RIGHT B[f] B SR
10101_fff_10 C + C -> C[f] C=C+C
10110_fff_10 SHIFT RIGHT A[f] A SR
10111_fff_10 0 -> A[f] A=0
11000_fff_10 A - B _> A[f] A=A-B
11001_fff_10 A EXCHANGE B[f] AB EX
11010_fff_10 A - C -> A[f] A=A-C
11011_fff_10 A - 1 -> A[f] A=A-1
11100_fff_10 A + B -> A[f] A=A+B
11101_fff_10 A EXCHANGE C[f] AC EX
11110_fff_10 A + C -> A[f] A=A+C
11111_fff_10 A + 1 -> A[f] A=A+1

Leave a Reply

Your email address will not be published. Required fields are marked *