Nothing Special   »   [go: up one dir, main page]

HP-67 Simulators

Download as pdf or txt
Download as pdf or txt
You are on page 1of 29

H67 SIMULATORS - by David A.

Munroe
---------------

- CONTENTS -

H67-806

Elementary concepts. . . . . . . . . . . . . . . 1

Explanation of the (6*8)-(3*4) program. . . . . . 2


H67-806 unsupported features. . . . . . . . . . . 4

An appraisal of the.H67-806 . . . . . . . . . . . 4
H67-809A

H67-809A ......... ....... . . . . . 5


Instruction set and memory organization . . . . . 6
Explanation of timing. . . . . . . . . . . . . . 7
Instruction set, detailed description . . . . . . 8
Sample 809A program . . . . . . . . . . . . . . .11

H67-809A Operations . . . . ..... . . . . . .12

41C Useage .13


Avoiding problems. . . . . . . . . . . . . . . .14

H67-809A internals . . . . . . . . . . . . . . . .15

Routine descriptions. . . . . . . . . . . . . . .16

Miscellaneous. . . . . . . . . . . . . . . . . .17

An 809A application: the "AVG" program. . . . . .17

Appraisal of the H67-809A . . . . . . .19

Listing of the H67-809A (6 pages)


-la-

Elementary Concepts

Let's begin by examining the operation of the H67-806 as if it were a


real computer and then see how the 806 is simulated on the [-!P-67or !IP-/41C
(if you are already experienced in machine language programming, feel free
to skip ahead to the next section).

Below is a simplified diagram showing the functional components of the


H6 7-806:

registers:
GJEJ0GJ~ control
'!nit
memory
! I

Nemory on the 806 is quite small -


just 30 words (l;)cat.ions). The first
memory location is location 00 and the last is location 29. The contents
of a memory location can be a 3-digit value ranging from 000 to 999.
:lemor/ is used to hold both data and H67-806 instructions; whether a value
in memory (such as 127) is data or an instruction depends simply on how
the value is used: if the programmer chooses to execute it, it's an instruc-
tion; if it's loaded into a register, it's data.

The 806 has five registers called A, B, C, PC, and CC. The A-register
(accumulator) is used mostly for arithmetic operations; registers Band C
are simple work registers, but B can also be used as an index register
(indexing was described in the PPC article and further examples are given
in the next section of this document). Although values in memory should
range from 000 to 999, the value in a register can range from 0 to
+ 9999999999 E + 99. PC is the program counter; the contents of the PC
is always the address of the next instruction to be executed. For example,
when the instruction in location 20 is being executed, PC will contain the
value 21 -- which is the address of the next instruction to be executed.
For all practical purposes, the PC can be ignored by the programmer since
it is updated automatically by the 806 computer. However, before a program
begins execution the programmer must put the starting address into the PC.
Also, when a program halts, the contents of the PC will point one location
beyond where the program halted (as is typical of all computers). CC is the
condition code register. Some instructions, such as Add, cause the contents
of a register to be changed; others, such as Branch, do not affect any
rp.gisters. Whenever an instruction is executed that affects the contents
of a register, the CC is set to reflect whether the new contents are greater,
equal, or less than zero. This is then used in conjunction with the Branch-
on-Condition instruction, as you will see in the examples. If we were to
execute an instruction that puts the value 16 into A, the CC would also be
set to 16 automatically. Next, if we executed an instruction putting -20
into B, CC would be set to -20. NO'., if we execute an instruction putting
,

the same value 16 into A again, CC would be changed from -20 to 16. The
contents of A was affected even though the new value was the same as the
-1b-

old. :-!ost microcomputers and many minicomputers use condition ~;()dps just lH:e
this -- although they just use single bits to indicate greater. 0qual, or less
than zero, rather than saving the complete value.

Computer operation can best be described by an example. Let's suppose we're


sitting in front of a real 806 computer and that we have some method of
storing values into memory locations 00 through 29. Our example will be to
just add 16 to 24 and store the result. First, let's arbitrarily put the
constant 16 into location 27 and put the constant 24 into location 28. The
computed result will be stored in location 29. The first instruction we'll
want to execute is to load A from location 27; this is coded as 127. Let's
put that instruction in location 00. Next, we'll want to add the contents of
location 28 to register A; the code for that instruction is 328 and is put into
location 01. Next, He want to storl'!the stirn in location 29; that is coded as
229 and the instruction goes into location 02. Finally, ~..ewant to halt, so
the Halt instruction (code 000) is put into location 03. To execute our program
all we have to do is set the PC to point to the address of the first instruction
(location 00) and press the Executp button. Given this, we have:

(xxx = don't care)

registt~r: A 13 c PC CC
contents:
I
xxx [1 xxx II
xx-x 00 II xxx

location:
contents:

Hhen execution halts, registers A and CC will contain the sum, 40; the PC will
have the value 04 (since the halt is in location 01); and location 2~ will
contain the sum, t~O:

register: A B e PC ec
contents: I
40 II
xxx 1.1
xxx (
I
04 II
40 r

location: 00 01 02 03 04 26 27 28 29
/
contents:
I
127
I
328
I
229 I
000 xxx I 4 xxx 016 024 I
040
r
I I 1 I

/
microcode and the simulator
---------------------------
The H67-806 simulator i.s an FiP-c.7 (or He) progra!;J. that simulates the opf~rations
of this hypothetical 806 computer. This again raises the question of why anyone
',,1Ould simulate a computer on another computing device. Among the reasons given
in the PPC article, there is an even more important one: the widespread use of
microprogramming to replace hard1..ired logic. In the 1950's and early 60's, if
the instruction "laa" meant "Load A from location aa", then, to decode that,
the computer's central processing unit (CPU) had to have the necessary hardwired
logic gates to perform precisely that operation in ~equenced time intervals.
Not only did this involve designing and testing a lot of tedious circuitry, it
was also inflexible: coming out with the next model computer required designing
and testing a new CPU. Today, the instruction sets of IBM, DEC, and many other
-'c-

computers are not decoded in the r.ardware --


i_nst~ad, the epe i8 designf?r1 ':0
f-~xecute a small, lower-leVf~l instruct~.on set (not seen by the user), <lnd '1<lS
access to a control program that resides in read-only memor:,- (distinct from
main memory). This control program, called "microcode" or "fi-:-ffiware", L:
simply a collection of lower-level routines that defines what will happen when 2
high level instruction is fetched from main memory. For example, when a ~27
is fetched from memory for execution, it is the microcode that determines
that register A is to be loaded. The microcode program actually defines the
high level instruction set that the user sees; the implementation of an
instruction such as "Load A" might require dozens of microinstructions. Since
microprogramming is a flexible and powerful tool, its use by computer
manufacturers is widespread. So, on a simplified scale, the HP-67 program
code (the simulator) defines 806 operation much the samE' ,yay as microcode does
for a real machine.

Before describing the simulator, let's briefly introduc~ the H67-B09A, which
part 2 of this document describes in detail.

First, the similarities: the 809A has the same registers A, B, C, PC, CCj and
also has 30 words of memory. Howev!"r, the 809A has two new instructions (one
allows reading additional instructionsfrom cards) and its memory organization
is a bit different. Everything you've read in these sections so far, including
the example "16+24" program, applies equally well to the 809A.

Now the simulators (both 806 and 809A):

HP-67 users: the


simulator program uses all 224 program steps. Primary registers
RO to R9 and register I are also used exclusively by the simulator program itself.
During simulation, registers A, B, C, 0, E, correspond to A, B, C, PC, and CC.
Secondary registers RSO to RS9 correspond to memory locations 00 to 29 (see below).

HP-41C users: the 41C's card reader will translate the HP-67 program card auto-
matically; the simulator program requires SIZE 026. Registers ROO to R09 and
register R25 are used exclusively by the simulator program itself. During
simulation, registers R20, R21, R22, R23, R24 correspond to A, B, C, PC, and CC.
Registers RIO to R19 correspond to memory locations 00 to 29 (see below). Note:
registers RIO to RI9 are the same as RSO to RS9 on the fIP-67, so to simplify
terminology for both 67 and 41 users, I'll use RSO to RS9 when discussing memory
.
organization.

Memory organization: Each register contains three memory locations. On the 806,
RSO contains locations 00, 01, 02; RSl contains locations 03, 04, 05; and so on.
RS9 contains locations 27, 28, 29. Values are put into 806 memory as a 9-digit
fractional number. So, if locations 06, 07, 08 are to contain the values 116,
720, 020, then the value .116720020 would be put into RS2. Note that this is
only an external representation; from the simulator's viewpoint, location 07
would contain the value 720 and not a fraction. On the S09A however, RSO contains
locations 00, 10, 20; RSI contains locations 01, ]1, 21; RS2 contains 02, 12, 22j
and so on. RS9 contains 09, 19, 29. Values Qre put into 809A memory as a Dumber.
with three digits preceding the decimal point and six digits following it, e.g.
to put 123, 456, 789 into locations 02, 12, 22, then 123.456789 would be put
into RS2.
-ld-

~~~~~E~~~_2f_~_~l~E!~_EE~~E~~
We'll end t~is section by actually executing the 16+24 program on the 309~:

IIP-67 us ers :

1. Load both sides of the S09A simulator program card


2. Press BOOT (the 'B' key)
3. Press f P~
4. Key in the program:
127. 000 000 STO a
328. 000 000 STO 1
229. 000 000 STO 2
000. 000 000 STO 3
000. 000 016 STO 7
000. 000 024 STO 8

5. Press f P~S Memory locations 00 to 29 now cor~taln the progra~ and data.
6. Put the starting address ~nto the PC: key in a STO D (normally this
is not done -- the 809A automatically begins execution at memory loc~tion
10).
7. Begin execution: press E
8. After about 22 seconds, the 809A will halt. Examine registers and memory:
RCL A shows 40 (accumulator)
RCL D shows 4 (PC)
RCL E shows 40 (CC)
.'.
~

DSP 6, f p~S, RCL 9, f P~S shows O. 000 040 (040 in location 29).

HP-41C users:
O. Set USER, SIZE 026, GTC.. (remove any assignments to keys A, B, C, D, E)
1. Load both sides of the 809A simulator program card
2. Press BOOT (the 'B' key)
3. Key in the program:
127. 000 000 STO 10
328. 000 000 STO 11
229. 000 000 STO 12
000. 000 000 STO 13
000. 000 016 STO 17
000. 000 024 STO 18 Memory locations 00 to 29 now contain
the program and data.

,!i. Put the starting address into the PC: kC!y in 0 STO 23 (normally this
is not done -- the 809A automatically begins execution at memory location
10).
5. Begin execution: press E
6. After about 19 seconds, the 809A will halt. Examine registers and memory:
RCL 20 shows 40 (accumulator)
RCL 23 shows 4 (PC)
RCL 24 shows 40 (CC)

FIX 6, RCL 19 shows O. 000 040 (040 in location 29).*

~': ~neasy way to see a single memory location is to use the ADDR ('A') key; first key
in the address and-then press A, e.g. 29 A shows 40; 1 A shows 328. 1\n indexed
address can also b~ keyed in.
-2-

The simulator began by executing instructions according to the PC.


Sinc~ the PC is zero, the 127 is extracted fror::::lemorylocation 00
and then the PC is automatically incremented from 00 to OJ. Next,
the J27 is decoded into an instruction ,.nth opcode :: 1 (load) and
operand address = 27. The opcode is used to go to the simulator's
Load routine, which will then put the contents of location 27 into
register A.

This concludes the elementary concepts involved with the simulator.


A detailed treatment of the 809A begins on pageS, and a detailed
description of the simulator's workings begins on page 15. Also
provided is a fully commented program listing.

~xplanation of the (6*8)-(3*4) program ~prc V8~3P2iJ.

This program illustrates the use of indexing, subroutines, and


accessing parameters.

The important thing to note here is that all data specific to each
subroutine call is obtained relative to rB -- the subroutine never
requires its data to be put in the s~ne fixed locations for each call.

The program begins 'Jith the instruction 802, which puts the value 2 in
rB. The values we want to multiply, 3 and 4, are in locations 02 and
03, and so rB is pointing to the address of the first value.

Note Dhat at this point: o + rB :: address of 1st parameter


1 + rB = address of 2nd parameter
2 + rB :: address for result
3 + rB = address of next instruction to
execute upon exit from the
subroutine
-3-

The second instruction is 513, which branches to the multiplication


routine.

The next instruction executed is 150, which - since rB=2 - loads the
contents of location 00+02 into rA. So, rA now contains the value 3
from location 02.

Next, 020 is used simply to put the 3 into rC (we could have used a
902 instruction, but 020 is faster).

Now, the 151 instruction loads rA from location 01+02, so rA contains


the 4 from location 03.

The steps in locations 16 through 20 simply add 4 to itself 3 times


(giving 3*4 literally). rC starts with the value 3 and is used as
a counter. If, after decrementing rCwith the 702 instruction, rC is
still greater than 0, then the BC instruction (623 021) will not cause
a branch. In this case, the 351 then causes 4 to be added to rA and
then 516 causes a branch back to the 702 instruction. When rC gets
decremented to 0, the BC instruction (623 021) causes a branch to
location 21.

At location 21, the instruction 252 puts the product in rA into location
02+02.

Finally, the routine returns by using a 553 instruction, which branches


to address 03+02. The entire process is then repeated using the values
6 and 8, with rB = 7. Although the value in rB is different, the
meanings of
o+ rB
1+ rB
2+ rB
3+ rB
stay the same as far as the subroutine is concerned.
-4-

H67-806 "Unsupported Features"

First the easy stuff:

* op-codes 72r through 79r increment register r (A, B, C) by a


value from 1 through 8

* since registers A, B, C, PC, CC follow the secondary registers in


the HP-67 addressing scheme (i.e. RS9=19, rA=20), when specifying
H67 addresses of 30,to 49 you can load, store, and even execute in
A, B, C, PC, and CC. The only practical applications Itve found
ar..e'

141 is a good way to set rA to zero


95r puts 25.r in register r (A=O, B=l, C=2)
130 sets rA = 1000*rA
133 sets rA = 1000*rB
136 sets rA = 1000*rC
Now, one would think negative addressing (i.e. executing 150 when rB<O)
would simply address the set of primary registers and retrieve their contents.
Not quite! Looking at the contents of addresses -32 to -1 will produce an
interesting sequence of count-up and other constants, most of which are
independent of the 806 program used to look at them. Despite my knowledge
of the simulator and design notes, it took me eight solid hours one Sunday
afternoon to explain their mysterious originl

An appraisal of the H67-806


Although the 806 is nice, is it possible to simulate an even more powerful
hypothetical computer in the 224-step, 26-register HP-67?
Well, yes it is. There are a few inefficiencies in the 806 that use up
programming steps and make the simulator run slowly.
First, 806 address decoding is awkward: given an effective address of 13,
for example, we have to extract the middle three digits of RS4. The 806
address decoding routine, LBL A, has to do this as follows:
(define an H67 location as an HP-67 register number [reg] and
a field position [pos], where pos=O refers to the leftmost
.
three digits in reg.)
now let ea = 13 (example effective address)
n = int(ea/3) = 4
reg = n+10 = 14 = RS4
pos = ea-3n = 1 = middle three digits

As we will see in the detailed description of the 809Ats addressing routine,


a small change in memory organization produces quite a few nice benefits.
Also in the 806, the routines which handle the increment/decrement instruction
and the transfer register instruction have similar coding, so we should be
able to have a single, smaller routine do the work of both.
-5-

The H67-809A

The H67 model 809A has two new and powerful instructions, while
retaining the ten high-speed memory locations introduced in the
807C.

The first of the new instructions, I/D/T, is a combined increment/


decrement/transfer instruction; a single instruction, therefore,
replaces the I/D, T instructions of the 806 and 807C. The I/D/T
instruction can perform both an increment or decrement and trans-
fer in a single operation.

The second new instruction is lOP (Input/Output/Pause); it can


be used both to monitor program execution and also to overlay
H67 memory during execution. This allows H67 programs to be
written that exceed H67's 30-word memory.
Aside from a new memory organization and the two new instructions,
the other aspects of the 809A are identical to those of the 806.
For example the 809A has the same direct and indexed addressing
modes as the 806, and has the same registers: rA, rB, rC, PC, CC.
-6-

H67-809A Instruction Set Summary

Below is a brief summary of the instruction set; a more detailed


description of each instruction is given in a following section.

HLT 000 Halt and display rA


XCA 020 Exchange rC and rA
L laa Load rA
ST 2aa Store rA
A 3aa Add to rA
S 4aa Subtract from rA
B 5aa Branch to aa
BC 6aa;bb Branch on condition
I/D/T 7mp Combined increment/decrement/transfer
LBI 8U Load rB immediate
lOP 9xx Input/Output/Pause

H67-809A Memory Organization


The 809A has 30 words of memory for program and data storage. This
memory is given addresses 00 to 29, and corresponds to the HP-67
secondary registers as shown in the diagram below.

HP-67 reg. H67-809A memory

RSO 00 10 20
RSl 01 11 21
RS2 02 12 22
RS3 03 13 23
RS4 04 14 24
RS5 05 15 25
RS6 06 16 26
RS7 07 17 27
RS8 08 18 28
RS9 09 19 29
Note that this is completely different from the H67-806.

Similar to the 806, however, is that an address in the range 00 to 29


is a direct address, and an address in the range 50 to 79 is an indexed
address.

Memory locations 00 through 09 is "high-speed" memory: instructions and


data in those locations are fetched from memory faster than in 10 to 29.

Instructions and data are placed in memory as follows: if locations 02,


12, and 22 are to contain
the values 804, 116, and 309, t.hen the value
804.116309 would be put into secondary register 2.
Note that three digits
precede the decimal point and six digits follow it!
-7-

Explanation of timing

For each 809A instruction, the execution time in seconds is given in


the formatz timel!timed!timeh

(low-low) represents the total time for the instruction to


execute when the instruction is fetched from low
core and when the operand, if any, is also fetched
from low core (i.e. locations 00 through 09).

(high-high)represents the total time for the instruction to


execute when the instruction is fetched from high
core and when the operand, if any, is also fetched
from high core (i.e. locations 10 through 29).

when shown, represents the total time for the instruction


to execute when the instruction and its operand are
fetched from differing sections of core.

Special cases are the ST and BC instructions.

In those places where no timed is given, it is because the operands of


those instructions do not require another memory fetch. Thus, only a
single memory fetch is performed (of the instruction itself) -- which
is either in low core (t~mel part) or high core (timeh part). For
example, when the LBI instruction is executed in low core its execution
time is 3.6 seconds; in high core its time is 4.5 seconds. The only
memory fetch required for LBI is that of the instruction itself.

Although the ST instruction accesses memory twice, only the first access
(of the instruction itself) affects the overall execution time of the
instruction. The second access (of memory where rA is to be stored)
always requires a fixed amount of ttme regardless of the operand~ location.

For BC, when CC=O the H67 must do a second memory fetch in order to get
the branch address, bb, in the second word of the instruction. The timed
value represents the unusual case when the first word of the instruction,
6aa, is in low core location 09 and the second word is in high core
location 10.

A detailed explanation of memory addressing is given in the description


of the LBL A routine.
-8-

H67-809A INSTRUCTION SET

HLT 000 HALT & DISPLAY rA

Halts the H67 and displays the contents of rA. At the


time of the halt, the PC will be pointing to the next
instruction and the CC will be unchanged from its last
setting. If the operator keys in a value and then R/S,
the H67 will load the entered value into rA, set the CC,
and then continue execution.*

TIMING: 3.3/-/4.1 @1 CC ALTERED: YES

XCA 020 EXCHANGErC AND rA

Exchanges rC and rA, with the CC set to reflect the new rA


contents (=previous rC contents). On future H67 models that
will have a generalized exchange of any two registers, the
020 opcode will specify rC and rA.

TIMING: 4.0/-/4.8 @1 CC ALTERED: YES

L laa LOADrA

Loads,:the A register from the effective address aa, which may


be direct or indexed.

TIMING: 5.5/6.4/7.2 @2 CC ALTERED: YES

ST 2aa STORE rA

Stores the contents of the A register into memory at the effective


address aa, which may be direct or indexed.

TIMING: 7.3/-/8.2 @2 CC ALTERED: NO

A 3aa ADD TO rA

Adds the contents of memory at effective address aa to the contents


of rA. aa may be direct or indexed.

TIMING: 5.6/6.4/7.2 @2 CC ALTERED: YES

* Whenever execution is continued from a halt (by keying R/5), both


rA and the CC is set to the latest contents. of stack register X.
This is also true of the H67-806.
-9-

S 4aa SUBTRACT FROM rA

The contents of memory at effective address aa is subtracted from


the contents of rA, leaving the result in rA. aa may be direct
or indexed.
TIM!NG: 5.6/6.4/7.2 @2 CC ALTERED: YES

B 5aa BRANCH TO aa

Branches to effective address aa and continues execution there.


aa may be direct or indexed.
TIMING: 4.4/-/5.2 @1 CC ALTERED: NO

BC 6aa;bb BRANCH ON CONDITION


This is a two-word instruction. The first word contains the
opcode '6' and address aa, the second word contains the address
bb. aa and bb may be direct or indexed, independently of each
other. If the CC is less than 0, the H67 branches to effective
address aa. If the CC equals 0, the H67 branches to effective
address bb. If the CC is greater than 0, the H67 continues
execution at the next sequential instruction.
TIMING: 4.7/---/5.5 @1 (CC<O) CC ALTERED: NO
6.5/7.3/8.2 @2 (CC=O)
4.0/---/4.8 @1 (CC>O)

I/D/T 7mp INCREMENT/DECREMENT/TRANSFER


The digit p specifies a register pair, r1 and r2, according to the
table below; the digit m specifes an operation to be performed on
register r1. This instruction performs operation m on register r1
and then transfers the contents of r1 to r2.
examples: 701 decrements rA and then transfers rA to rB
715 transfers (copies) rB to rC
726 increments rC and then transfers rC to rA
708 decrements rC
724 increments rB
770 increments rA by 6
755 increments rB by 4 and then transfers rB to rC

TIMING: 5.3/-/6.1 @1 CC ALTERED: YES


-10-

TABLES FOR I/D/T

i = increment by i-l
m =
2 = increment by 1
1 = unmodified operation
o = decrement by 1

pair: rl, r2
9 PC,A
8 C,C
7 C,B
6 C,A
p = 5 B,C
4 B,B
3 B,A
2 A,C
1 A,B
o A,A

LBI 8U LOAD rB IMMEDIATE


Loads rB with the two-digit value ii.
TIMING: S.~/-/4.5 @1 CC ALTERED: YES

lOP 9xx INPUT/OUTPUT/PAUSE


The operation of this instruction depends on whether a 'magnetic
card has been inserted into the HP-67 during the time the 809A is
running. If no card has been inserted, the value xx is momentarily
displayed and then execution continues with the next instruction
in sequence. Except for display, xx is ignored. If a card has
been inserted, the lOP instruction causes the card to be read into
809A memory (i.e. the HP-67's secondary registers). The data read
from the card is assumed to Qe 809A instructions; therefore the
existing contents of 809A memory is overlayed with new instructions.
As soon as the card is read through, a "Crd" prompt will appear in
the display; the operator should then press the CLX key and the
809A will then continue execution normally with the new instructions.
Naturally, if the lOP instruction is at location n, the first (new)
instruction to be executed will be at n+l.
TIMING: 4.9/-/5.8 @1 CC ALTERED: NO

Notes: Timing is given for the non-card case.

All of the 809A's memory (locations 00 to 29) is overlayed;


Registers rA, rB, rC, PC, and CC are preserved during the read.
-11-

Sample H67-809A program

Below is the multiplication program that was given for the 806. It has
been optimized for the S09A by putting the multiplication routine in
high speed locations 00 to 09, since that is where the program spends
most of its time. Note that execution begins at location 10 on the 809A
unless explicitly altered beforehand (i.e. on initializing the 809A, the
PC is always set to 10).

LOC CONTENTS LABEL OP ADDR COMMENTS


; start of multiplication routine.
; begins in high speed memory
00 150 MUL: L O,B ; rA= multiplier
01 020 XCA
02 151 L 1,B ; multiplicand
03 708 MLOOP: D C ,
.
if rC=O...
04 629 BC ERR;DONE ,
. ...then done
05 OOS
06 351 A 1,B ; forming product
07 503 B MLOOP ,
.

;
08 252 DONE: ST 2,B ; store product
09 553 B 3,B ; return to caller
;
; *** start of program -Irl:* the S09A always begins at location 10
,
.

10 S12 PGM: LBI PARMS ; rB=address(first parameter)


11 500 B MUL ; call MUL
12 003 PARMS : CON 3 ;
13 004 CON 4 ,.

14 000 ANS1: RES 1 ; reserve 1 word for 3*4 result


15 817 LBI .+2 ; rB=address(first parameter)
16 500 B MUL ; call MUL
17 006 CON 6 .
,

lS OOS CON 8 ;
19 000 ANS2: RES 1 ; will be (6*S)
20 712 T A,C ; rC=rA= (6*8)
21 414 S ANS1 ; rA= (6*8)-(3*4)
22 000 HLT ; display rA
LOC 29
29 000 ERR: HLT ; error halt
010 END PGM ; execution begins at PGM (0)
To load this program, the secondary registers would be loaded as shown below;
this program takes about 3m 56s to execute.

RSO= 150.812712 RS5= 008.817000


RS 1= 020.500414 RS6= 351.500000
RS2= 151.003000 RS7= 503.006000
RS3= 708.004000 RS8= 252.008000
RS4= 629.000000 RS9= 553.000000
-12-

H67-809A Operations

It is suggested that "large" 809A programs first be written on paper, divided


into a main and overlay segment, and then recorded on a card. This section
covers recording, running, and tracing a program. Recording and using overlays
for the lOP instruction is covered in the next section. These sections assume
the use of an HP-67/97; a third section covers use of the 809A on HP-41C's.
About cards: both a main 809A-coded program and an overlay 809A-coded program
can fit on one card. The main program must be on track 1, the overlay on track
2. However, if an overlay is to be used at all, the overlay must be recorded
first according to the instructions given in the next section.

A. Recording a program

1. Load both sides of the 809A simulator program card, unless already done.
2. Press BOOT (the 'B' key). This resets the simulator's flags and sets up
certain constants. 809A memory (the secondary registers) is preserved
(unlike the 806). It is never necessary to reload the program card
between 809A programs, just use BOOT.
3. Press f P~
4. Key the 809A codes into the appropriate registers (e.g. 108.720309 STO 2
will place the code into R2 (RS2 after step 6) ).
S. (optional): to record the program,* press f W/DATA and insert only track 1
of a card. Clear the "Crd" message using CLX. For 41C, see below.
6. Press f pe;s
B. Running a program
O. (optional): BOOT, f P~S, read in track 1 of 809A codes (one side of card
only), CLX, f P~. For 41C, see below.
1. Load rA, rB, rC if required.* If execution is to begin at an address
other than 10, then set the PC to the address where execution is to begin.
2. For single step execution, press 'D'.
3. For normal execution, press 'E'.
4. Be patient.
(note that setting the PC is STO D, and 'D' is an executable operation)
C. Examination of registers and memory**
Halted programs: use "RCL" to examine the H67 registers A, B, C, PC, or CC.
Also, f ~~ allows examination of appropriate secondary registers (do f ~S
when finished). When resuming from a halt, the contents of stack register X
sets rA and the CC.

Single-step operation: in this mode, the H67 will halt before each instruction
fetch and will display the PC value for the instruction about to be executed
next. So, if the value 12 is displayed in single-step mode, this means that
the instruction at location 12 is going to be executed when R/S is pressed.

When halted in this mode, the H67 registers may be examined by 'RCL' and H67
memory may be examined by f P~S (as long as you switch back by f P~).

Execution can be traced easily in single-step mode by pressing R/S and watching
the PC change. Note: it is very important that the current value of the PC is
or has been recalled back into stack register X before pressing R/S.
Single-step can be turned off and normal execution enabled by pressing 'C'.

*registers A, B, C, and PC may also be recorded and read from track 1.


**one nice way of doing this is to put a direct or indexed address into stack register
X and then press the ADDR ('A') key, the H67 itself will fetch the contents at that
address.
-13-

Recording an overlay

1. load both sides of the 809A simulator program card.


2. press BOOT ('B').
3. press f ~ ++
4. key in the 809A codes for the overlay segment of code, keeping in mind that:
(1) if the rop instruction in the main segment is at location n, the first
instruction to be executed in overlayed code will be at n+l. (2) when executing,
the only information the overlay segment can obtain from the previous segment
is that in rA, rB, rC, PC, and CC.
5. press f ~S
6. press f W/DATA
7. insert track 1 of the card and then track 2 (as indicated by "Crd").
++ e.g. 108.720309 STO 2 will place the code into R2 (RS2 after step 5).
The card recorded from the above instructions contains:

track 1: irrelevant information


track 2: overlay 809A code that the 67/97 card reader will automatically read
into the secondary registers

Now the main segment may be entered as described in section A of the previous section.
Note that the main 809A code segment (plus A, B, c, PC) may then be recorded onto track
1 and later read back (see steps AS and BO in the previous section).

Using overlays
When the main program is running, put track 2 of the card into the card reader snugly.
When the rop is executed the card will read through and a "Crd" message will appear.
At this point press only CLX and execution will now resume in the overlay segment.
If the main program contains many pauses or halts, be careful not to insert the card
prior to a halt or the wrong rOPe

41C Useage
Operations are simpler on the 41C; all we need remember is:
registers 00 through 09 are used by the simulator (SIZE= 026)
*
* registers 10 through 19 correspond to the HP-67's secondary registers and thus
also to 809A memory locations 00 to 29.
e.g. 108.720309 STO 12 puts the instructions 108, 720,
and 309 into H67 locations 02, 12, and 22.
(the HP-67 can't do this directly, so it has to use ~S)
* registers 20 through 24 correspond to H67 registers A, B, C, PC, and CC.
In USER mode, the top row keys (A to E) correspond to ADDR, BOOT, CONT,STEP, and EXEC.
Regarding the operations given in the previous section, we have:

step A1: OK
step A2: OK
step A3: omit this step
step A4: the 809A codes can be stored directly into registers 10
through 19, as required
step AS: this step becomes: Enter 10.024 into stack register X, issue WDTAX,
then insert side 1 of the card
step A6: omit this step
-14-

step BO: this step becomes: BOOT ('B'), enter 10.024 into X, issue
RDTAX, then insert side 1 of the card
steps Bl to B4 are OK

Registers A, B, C, PC, CC can be examined by simply recalling registers 20 through


241 H67 memory can be examined by recalling registers 10 through 19 (FIX 6 helps).
You still have to be aware of stack register X when resuming from a halt or single-step.

Overlays and the 41C:

step 1: OK
step 2: OK
step 3: omit this step
step 4: codes can be stored directly into registers 10 through 19
step 5: omit this step
step 6: this step becomes: enter 10.019 into X, issue WDTAX
step 7: this step becomes: insert only side 2

Using overlays on the 41C:

Modify the translated 41C program as follows: find the LBL 09 routine
and the PSE instruction which follows. Replace PSE with:
TONE 9
10.019
VIEW Y ( Y contains the xx of 9xx)
RDTAX
Useage: when the main program sounds the tone (via lOP), insert the
overlay (side 2 of the card). To execute an lOP without reading a
card, just respond to the tone wi th +- or RIS.

Avoiding problems
Since programming the H67 is essentially programming in machine language, it is
very easy to make errors. In the past year, no problem has ever been found in the
simulator itself; the usual reasons one of my programs doesn't seem to be executing
properly are:

1. the algorithm doesn't solve the problem (e.g. a few extra logic steps
need to be added).
2. left an instruction out.
3. used wrong op code or wrong address.
4. didn't key data into registers properly.
5. inadvertently changed data during halt or in step mode.
I would recommend "executing" the code by hand before it gets entered into the machine,
even if it looks okay. Lastly, observing the program in step mode will reveal where
any problems are.

The 809A executes its instructions at a rate about one million times slower than a
typical computer today, so 5-minute program times are common. Putting pauses, halts,
or error halts in a program will help discriminate between a program with a long
execution time and one that is a runaway.
-15-

H67-809A Internals

The 809A simulator consists of these routines:

LBL brief description


A address decoding and memory references
B system reset (initialization)
E instruction fetch and decoding
e effective address calculation
1 Load
2 Store
7 Increment/decrement/transfer
6 Branch on condition
3 Add
8 Load rB immediate
5 Branch
4 Subtract
o Halt and XCA
D Step mode
C continue normal run mode
9 Input/Output/Pause

The ordering of routines E through 0 has been chosen so as to minimize


the HP-67's label search time for the most frequent instructions.

Allocation of RO through R9:

RO = 'pos' value
R1 = the last three digits in secondary register 'reg'
It It to to It It to
R2 = middle
R3 first It to It If to It If
=
R4 = 'reg' value
R5 = constant 20
R6 = most recent effective address referenced
R7 = scratch
R8 = constant 10
R9 = constant 1000

Flags:

flag 0 set means store into memory (LBL A)


flag 1 set means step mode is in effect
flag 2 set means load operation from memory when pos=O (LBL A)
-16-

Routine Descriptions

The most important routine in the simulator is LBL A, which handles addressing
and memory references. It is such an important routine that it is described in
detail here. Once LBL A is understood, most of the other routines are simple
enough to be followed from the listing comments.
Important points about one other routine is described below.

LBL AI addressing and memory references

The two main functions of this routine are:

1) given an address, return ("fetch") the contents of memory at that address


2) given an address and a value, store the value into memory at that address

When this routine is called (GSB A), these conventions are used:

- stack register X contains a direct or indexed address, aa


- flag 0 clear means retrieve data from memory location aa and return it in X
- flag 0 set means store data in R7 into memory location aa

The routine first computes an effective address, ea, from the address aa. If 00~aa$29,
then ea=aa; otherwise if 50 ~ aa ~ 79, then ea= (aa-50)+contents(rB). The first digit
of the effective address is called "pos" and the second digit plus 10 is called "reg"
(e.g. if ea=08, then pos=O and reg=18). The value reg, when put into rI of the HP-67
indicates the secondary register in which to find the H67 memory location; in our
example 18 points to RS8. Pos isolates the correct 3-digit section of the register:
pos=O for the first three digits, pos=1 for the middle, pos=2 for the last. Pos will
be used as a pointer to the three components of a register. Given register reg in the
format iii.jjjkkk, the LBL A routine separates the components serially into iii, jjj,
and kkk. After this, flag 0 is tested; if flag 0 is clear (fetch), the routine simply
uses pos to retrieve the appropriate component. If flag 0 is set (store), then the
contents of R7 replaces the component pointed to by pos; the components are then packed
into the iii.jjjkkk format and stored back into reg.

So where does the high speed memory come from? Note that if we're doing a fetch
operation (i.e. we don't have to repack and store), then we can return from LBL A
just as soon as the appropriate component has been extracted from the iii.jjjkkk
format. Since locations 00 to 09 all refer to the iii part which is extracted first (and
where pos=O), we can return from LBL A much earlier than normal if we detect flag 0
clear and pos=O. This also explains the special case of timing for the ST instruction.
We could go a step further and detect that if pos=I, we need not extract kkk, but the
overhead offsets any advantage.

LBL E: main instruction decoding loop

This routine simply retrieves the instruction at the address indicated by the PC. Then,
like all computers, increments the PC by one so that while the instruction at location n
is executing, the PC is at n+l. When the value of the PC, n, is presented to the LBL A
routine, we get an instruction from memory in the format iaa (3-digits), e.g. 152. R6
also contains the effective address of n, so R6+1 is really used to increment the PC.
This is being a bit cautious, since the other routines in the simulator guarantee that
any indexed branch will resolve the effective address before setting the new PC. In any
cas~ the first digit of iaa is used to select the routine to handle the instruction and
stack register X is set to aa. When the instruction-handling routine is entered, it
interprets the value in X according to its own needs, e.g. 7mp, 8ii, etc.
-17-

Miscellaneous

For whatever need, the only no-operation, NOP, is B .+1 --i.e. branch to the next
location. Something like T A,A (opcode 710) is not a NOP since the CC is changed.

Example mnemonics for I/D/T:

- transfer rB to rC (715): T B,C


- increment rA (720): I A
- decrement rA and transfer rA to rB (701): DT A,B
- increment rB by 4 and transfer rB to rC (755): 14T B,C

these last two cases, 701 and 755, are good examples of a common oversight: that the
increment or decrement operation is performed on the source register first and then the
transfer to the destination register is made.

An 809A application: the "AVG" program


This program will let the user input a series of values, allowing erroneous values to
be removed, and then compute the average of the series. For example, if the average
is 7 1/3, then the program will halt with rA=7, rB=I, rC=3. Division is done by
repeated subtraction. During input, the display will show a count of values accumulated
so far. Input of a positive value adds to the accumulation and increments the count.
A negative value does the opposite; zero ends the sequence and starts the computation.
example:
current count: o 1 232 3
user entry: 4 8 3 -3 10 o avg= 7 1/3

when 0 is entered, an overlay segment is read in to compute the average.

MAIN PROGRAM:

LOC CONTENTS LABEL OP ADDR COMMENTS


; this part is in high speed memory since positive values will
; be entered most often
00 716 AWAIT: T C,A ; show current item count
01 000 HLT ; display count, await input
02 615 BC LESS;EQUAL; select appropriate routine
03 019
04 308 A SUM ; add if not less or equal
05 208 ST SUM ;
06 728 I C ; increment count
07 500 B AWAIT ; await next input
08 000 SUM: RES 1 .
, sum is in high speed memory

LOC 10 ; ** main program starts here **


10 800 AVG: LBI 0 .
J initializations:
11 715 T B,C ; set count to zero (rC)
12 713 T B,A ;
13 208 ST SUM ; set sum to zero
14 500 B AWAIT ; await input

15 308 LESS: A SUM ; add sum to negative value in rA


16 208 ST SUM .
.J in order to correct prior entry
17 708 D C , decrement count
.

18 500 B AWAIT ; await input


-18-

19 108 EQUAL: L SUM ; rA=sum, rC=count, ready for overlay


20 999 rop 99 ; overlay read here if card is in
21 520 B .-1 ; keep branching back until card is in
010 END AVG

OVERLAY SEGMENT:

; this overlay is entered with rA=sum, rC=count.


; Overlay begins at 21 since rop is at 20.
21 800 LBI 0 ; rB will be the quotient
22 020 XCA. ;
23 205 ST COUNT ; the denominator = count
24 612 BC ERR;ERR ; can't be negative or zero when dividing
25 012
26 020 XCA ; ready for division
27 500 B LOOP ;

; do division by repeated subtraction in high speed memory


.
,
LOC 0
00 405 LOOP: S COUNT ; subtract count from sum
01 606 BC DONE;CONT ; if negative then done
02 003
03 724 CONT: r B ; otherwise form quotient
04 500 B LOOP ; repeat loop

05 000 COUNT: RES 1 ;

06 305 DONE: A COUNT ; now rA=remainder, rB=quotient


07 715 T B,C ; move things around so that rA=quotient,
08 711 T A,B ; rB=remainder, and rC=denominator
09 105 L COUNT
10 020 XCA .
,
11 000 HLT ; normal halt, PC=12
12 000 ERR: HLT ; error halt, PC=13
END

Code to put into the secondary registers:

RSO =
716.800999 405.020000
RS1 = 000.715520 606.000800
RS2 = 615.713000 003.000020
RS3 = 019.208000 724.000205
RS4 = 308.500000 500.000612
RS5 = 208.308000 000.000012
RS6 = 728.208000 305.000020
RS7 = 500.708000 715.000500
RS8 = 000.500000 711.000000
RS9 = 000.108000 105.000000

Main segment Overlay segment


-19-

You may want to code and record the overlay and the main segment
and then run the program. Each time the program halts with the
current count, enter a value and RIS. After you end the series by
0, RIS, there is sufficient time to insert side 2 of the overlay
card -- or you can wait for the lOP 99 to finish and insert the
card in the short time B .-1 is executing.

Appraisal of the H67-809A

The 809A is nicer than the 806 in that it has a better instruction
set and allows an arbitrary number of overlays to be used. Is it
possible to simulate an even more powerful hypothetical computer in
the 224-step, 26-register HP-67?

The answer is most certainly yes. Aside from a bit of sloppy coding
in the 809A, I've prepared a few designs radically different from
the 809A which, when implemented, will provide a more diverse and
better designed instruction set. The 809A, however, is the most
recent simulator that I've implemented and fully tested.

Although I could have implemented the 806, 809A, or something more


powerful on my 41C system (which I like very much), I chose to use
my HP-67 for several reasons: (1) it's my first and favorite HP
calculator, (2) it benefits other 67 users and 41 users, (3) the
challenge of trying to implement progressively more powerful
simulators in a fixed hardware enviornment of 224 steps and 26
registers is similar to the experience of designing a good instruction
set for a microcoded computer. For example, the instruction set of
the Microdata 810 (Microdata Corp. 1972) is, in fact, implemented
by a Microdata 800 program (Ufirmware") that resides in ROM.

You might also like