- Overview
- Detailed operations
- ROM Mapping
1) HP25 vs HP21 vs HP35
The HP-25 was designed as an advanced programmable scientific calculator with a 2048 instruction (10 bits each) ROM (the HP-21 had 1024 instructions and the HP-35).
It had a data storage chip with 16 registers of 56 bits each :
- 8 registers were used for user data (8*14 BCD digits),
- 7 registers were used for user programs (7*56= 392 bits == 49 program lines of 8 bit each),
- 1 were used for the LAST x function.
The firmware study is organized in the following order:
- this 'overview' page will cover the ‘key phrase’ logic, the ‘Key codes” computation, and 3 general sequences (- the Initialization after power up & the ‘wait a key’ loop, the ‘enter a digit sequence’, and the function sequence (ln for example).
- different tabs (upper part of the page) will cover different routines (launching a program, SST, storing data, different display formatting type FIX, SCI, ENG, etc…).
- a last tab will introduce a ROM map for the HP-25.
2) Key phrases
One HP-25 major advance (as compared to the HP-55 or HP-65) is its programming model based on "key phrases" rather than keystrokes.
A key phrase is merely a sequence of keystrokes that together perform one compact operation. For example, STO + 2 is a 3 keystroke "key phrase” : 23 51 02 that takes only one step (see display's photo : step 01 key phrase '23 51 02' entered as 'STO' '+' '2', in PRGM mode).
Another example, prefixed keys takes one step “f sin” and is displayed '14 04'.
In memory such a "key phrase" will be coded with an 8 bit "key code" ; the same token will be used in program memory (PRGM mode) or in direct RUN mode.
Visually, each key on the keyboard has a 2-digit keycode :
- the digit keys being coded 00 through 09,
- all other keys are coded by their position on the keyboard matrix. : for example, the blue 'g' key is coded 15 = row 1, column 5.
The program memory contains space for 49 key codes encoding 49 key phrases : 1 register is 14 digits long = 7 bytes.
49 key codes require 7 Ram registers.
Note that this model allows another innovative advance : the "SST Single Step RUN".
As indicated above, in direct RUN mode, the same "key code" allows the user to execute his program one key phrase at a time with the SST key (a debug key) held down.
When requested by the keyboard or read from program memory the same 'key code " is serviced in the same way.
In SST mode the display will show the program line number (user program counter) and the key phrase that is to be executed (not the code code ; that's the innovation).
When releasing SST the operation's result will appear.
Debugging a program is quite easy : the user can execute the program flow step by step.
3) 8 bit key codes
As explained earlier, an 8 bit key code is used in both modes (PRGM and RUN) to access the HP-25 functions. In the former ‘Classics” models HP-35, 45 etc, this value -which is a token built by the keyboard hardware- was used as a displacement on a table in ROM where the action or a jump to the action was coded.
Another more flexible scheme is used in the Woodstock : the token returned by the hardware and the key-code are two different things. A keystroke returns a ‘token’ which branches to a place in ROM where a key-code is computed and stored in the A register (specifically a[2] and a[1]) and used by the ‘a -> rom address’ to jump to the appropriate rom space and to service the action requested.
Let’s take an example. When key ‘x<->y’ is pressed, a ‘token’ ‘103’o is return by the keyboard hardware and is used as a displacement on Rom 1 (address 0400o).
Adress 503o is the entry point to action ‘kxexy’ : x exchange y key. At this step, register C is null. By a series of steps ‘c + 1 -> c[x ]’ and tests the value in C is incremented to ‘C=000000000000fa’ and control branches to label ‘execut:’ where register A is prepared for execution : C is copied to A and a[2] is forced to 1 - for actions of this type (a + 1 -> a[xs]).
Then the instruction ‘a -> rom address’ (address 1771o) is executed with A=210000000001fa.
From the program counter the current Rom start is extracted : PC AND (NOT 0377o) = 01400o = 0300h (rom 3).
Then a[2]=’a’ <<6 and a[1]=’f’ are added making 0300hex + 10hex + ‘f’hex = 31fhex = 1437o, where execution continues.
NB: to study this in detail, please use the emulator with a breakpoint in 503o.
Use the 'token' code table given below (addresses are in octal starting @ 0400o + displacement):
Most 'tokens' - after being decoded - will end up @ address 1771o where is located the main switching instruction 'a -> rom address'.
Token table (HP25 ROM 1 ).
e.g. the RCL key : key code = 100 > address 0400o + 100 = 0500o.
L00500: | 0100011011 | krcl: go to ercl | ; RCL key | 100 | |
L00501: | 1100011011 | ksto: go to esto | ; STO key | 101 | |
L00502: | 0111101110 | kroll: c + 1 -> c[x ] | ; roll down key | 102 | |
L00503: | 1010010111 | kxexy: if n/c go to kyexy1 | ; x <>y key | 103 | |
L00504: | 0111101110 | ksig+: c + 1 -> c[x ] | ; sigma + key | 104 | |
…/… | |||||
L00540: | 0111101110 | k9: c + 1 -> c[x ] | ; 9 key | 140 | |
L00541: | 1001110111 | k8: if n/c go to k7. | ; 8 key | 141 | |
L00542: | 1001111111 | k7: go to k6. | ; 7 key | 142 | |
L00543: | 1110010100 | k-: if 1 = s sto 14 | ; - key | 143 | |
L00544: | 0100000000 | then go to esto1 | |||
…/… | |||||
L00560: | 0111101110 | k3: c + 1 -> c[x ] | ; 3 key | 160 | |
L00561: | 0111101110 | k2: c + 1 -> c[x ] | ; 2 key | 161 | |
L00562: | 1010011111 | k1: if n/c go to k1. | ; 1 key | 162 | |
L00563: | 0111101110 | k*: c + 1 -> c[x ] | ; * key | 163 | |
…/… | |||||
L00620: | 0000100000 | kr/s: select rom 0 | ; r/s key | 220 | |
L00621: | 1101100111 | k.: go to k.. | ; . Key | 221 | |
L00622: | 1000010000 | k0: return | ; 0 key | 222 | |
L00623: | 0111101110 | k/: c + 1 -> c[x ] | ; / key | 223 | |
…/… | |||||
L00640: | 0111101110 | k6: c + 1 -> c[x ] | ; 6 key | 240 | |
L00641: | 0110110111 | k5: if n/c go to k5. | ; 5 key | 241 | |
L00642: | 0110111111 | k4: go to k3. | ; 4 key | 242 | |
L00643: | 0111101110 | k+: c + 1 -> c[x ] | ; + key | 243 | |
…/… | |||||
L00660: | 1001011111 | kf: go to ef | ; f yellow key | 260 | |
L00661: | 0111100011 | kgto: go to egto | ; gto key | 261 | |
L00662: | 0011100000 | kbst: select rom 3 | ; bst key | 262 | |
L00663: | 0011100000 | bsst: select rom 3 | ; sst key | 263 | |
L00664: | 0010001101 | kg: jsb zap | ; g blue key | 264 | |
…/… | |||||
L00720: | 1101010111 | keex: go to eeex | ; eex key | 320 | |
L00721: | 0000100000 | kchs: select rom 0 | ; chs key | 321 | |
L00722: | 0000000000 | nop | ; nop | 322 | |
L00723: | 1101110011 | kenter: go to eenter | ; enter key | 323 | |
L00724: | 0111101110 | kclx: c + 1 -> c[x ] | ; clx key | 324 |
Key-codes table (Hex values)
The following table gives for each action the key-code built in register A register (a[2] and a[1]) before executing the ‘a -> rom address’.
There are 3 columns, one for the 'plain' key and 2 other for the prefixed keys (f yellow prefix or g blue prefix).
note: x = 4 bit digit (STO 2 = '2a').
plain | f | g | ||
f | s[10]=1 | |||
g | s[9]=1 | |||
SST | - | 5x | - | |
BST | - | 6x | - | |
GTO xx | xx | 7x | - | |
STO x | xa | - | - | |
RCL x | xb | - | - | |
x<>y | fa | da | ea | |
R! | fb | db | eb | |
SUM+ | fc | dc | - | |
ENTER | f6 | - | - | |
CHS | f7 | d7 | e7 | |
EEX | f8 | d8 | e8 | |
CLx | f9 | d9 | e9 | |
. (dp) | f4 | d4 | e4 | |
- | f0 | d0 | e0 | |
+ | f1 | d1 | e1 | |
x | f2 | d2 | e2 | |
/ | f3 | d3 | e3 | |
R/S | f5 | d5 | e5 | |
0 | c0 | a0 | b0 | |
1 | c1 | a1 | b1 | |
2 | c2 | a2 | b2 | |
3 | c3 | a3 | b3 | |
4 | c4 | a4 | b4 | |
5 | c5 | a5 | b5 | |
6 | c6 | a6 | b6 | |
7 | c7 | a7 | b7 | |
8 | c8 | a8 | b8 | |
9 | c9 | a9 | b9 |
material to be published in 2012
4) Init function & Wait a key loop.
5) Enter a digit sequence.
6) Function sequence (ln).
7) Detailed operations
8) HP-25 ROM Map.
All rights reserved.
blue g prefix
yellow f prefix
STORE a value
RECALL a value
Display formatting routines (FIX, SCI, ENG)
Key Phrase building
ENTER a program
SST a programRUN a program
HP-25 ROM map
HP-21 subset