\section{Data Path, Registers and ALU}

\subsection{ALU}
The next section to consider mostly located on the {\bf Data Path} PCB. 
The ALU itself consists of a pair of PROMs at locations U19 and U11. For
binary (bit serial) operations, only U19 is used. Since in this case the X
field of the microcode word does not contain 2, {\bf X2} is low (due to
U18c). This disables the higher-order T register inputs via U20a and U20d,
and allows these inputs to the PROM to be driven by the ALU function
select bits of the microinstruction. The bit-serial inputs to the ALU are
{\bf ALUSerIn} which comes from a data selector in the memory system; and
{\bf Regser} fro a data selector on this PCB which will be explained
shortly. The output of this ALU is {\bf ALU(0)} which is fed to the
various CPU registers. 

For decimal (BCD) operations, both PROMs are used. {\bf X2} is high, so 
U20a and U20d are enabled (there is no conflict with the microinstruction 
since for such microinstructions, {\bf $\mu$(13)} and {\bf $\mu$(14)} are 
both set to `1'. The low nybble of the A accumulator and that of the T 
register are fed into the ALU (the LSBs via the data selectors previously 
mentioned), the 4 it output is fed back to the A accumulator.

Flip-flop U12b acts as the carry flag for binary operations. It is 
enabled when {\bf $\mu$(20)} is `1' (ALU operations 4\ldots 7 are the 
ones which alter the carry flag). Similarly U12a is the BCD (decimal) carry 
flag, which is enabled when the X field contains 2. The carry flags can 
be tested as microcode conditions, and the appropriate one is fed back to 
the ALU circuit via U20b or U20c. One other feature that should be noted 
is that the binary carry flag can be directly set by the {\bf SCF} signal 
via U13b. This signal comes from the input/output system and allows the I/O 
flag testing instructions to skip the next machine instruction if the 
I/O flag is in the appropriate state.

\subsection{P Register}
The processor registers are shift registers which can either be rotated 
(recirculated) for reading one bit at a time into the ALU, or which can 
be loaded by shifting the ALU output into the most significant end. The 
complexity of the register control circuitry depends on the register, so 
we will begin with the simplest one, the P register (or program counter).

The P register consists of a dual 8-bit shift register chip at location
U10. The 2 sections are cascaded to form a 16 bit register. For reading,
the R=1, so {\bf R(1)} is low. The output of U18d is thus high, so U18b
applies {\bf Bitclk} to the register. The DS input of U10b is high (since
the X field does not contain 5 for a simple read operation), so the data
input to U10b comes from the output of U10a, the register recirculates.
For writing, the X field contains 5. The clock signal is enabled as before
but now the DS input of U10b is low, so the register is loaded from {\bf
ALU(0)}. Of course during a write operation, the current least significant
bit of the register is available on the {\bf Pout} signal, so the P
register can be modified (for example incremented) without using an
intermediate register. 

\subsection{Accumulator Control}
There are 2 main accumulators, A and B, and in many cases they can be
used interchangeably. In order to simplify the microcode (by allowing
the same routines to be used for either accumulator), the accumulators are
selected by U2 on the {\bf CPU Control} PCB. This JK flip-flop is
controlled in 2 ways. If X=4, then both J and K are set to 1 (via U1a) so
the flip-flop toggles, selecting the other accumulator, whereas if the
X=1, then U1f causes {\bf Q(11)} to be applied to the J input and {\bf
Q(11)/} (from U1b) to go to the K input. Thus the flip-flop is set
according to the 11th bit of the Q register. It turns out that in many
cases a machine instruction which accesses one accumulator has a
counterpart which accesses the other accumulator, and they differ only in
the state of bit 11. Of course in other cases, the appropriate bit can be
shifted into the correct position in the Q register before loading it
into the selection flip-flop. 

Back on the {\bf Data Path} PC, the {\bf Ld/} signal from U14a is asserted 
(low) when either accumulator is to be loaded from the ALU. This occurs 
when the X=6 (normal load to the accumulator), or R=2 and X=3 (the 
`special case' involving the E register), or when data is being read from 
the input/output system.

\subsection{B Accumulator}
The B accumulator is similar in design to the P registers. It consists of 
a 16 bit shift register U9. For reading, {\bf $\mu$(12)} and {\bf BEn/} 
are both low, so U16a enables the clock via U15c and U17a. The DS input 
of U9a is low, so the register recirculates. For writing, {\bf Ld/} and 
{\bf BEn/} are both low. U16b enables the clock input essentially as 
before, but since DS of U9a is now high, the register is loaded from the 
ALU output.

\subsection{A Accumulator}
The A accumulator is more complicated due to the fact that the low 4 
bits can be read or written at once for BCD operations. It consists of a 
4 bit register U4 cascaded to an 8 bit registers U6 cascaded to a further 
4 bit register U5.
\begin{description}
\item[Binary read of A] : {\bf $\mu$(12)} and {\bf AEn/} are both low. 
The clock is enabled to all sections of the register by U16d and U15d. X 
is not 2, so X2 is low, as is the mode input of U5. The Mode input of U4 is 
also low, so the entire register recirculates. The data output is taken 
from {\bf A(0)}
\item[Binary write of A] : {\bf Ld/} and {\bf AEn/} are both low, so the 
clock is enabled to all sections of the register via U16c and U15d. The 
mode input to U5 is low as before, but that to U4 is now high. Thus U4 
performs a parallel load operation, but due to its connections, this is 
effectively a shift reading the output of the ALU into the most 
significant bit. The remainder of the register shifts as before. The 
overall effect is to shift the register one bit to the right and load the 
ALU output into the most significant bit.
\item[BCD write of A]. The clock to the upper sections of the register is 
disabled. Since X=2 and R$\neq$0, the mode input of U5 is high via U8c. 
Thus U5 is parallel-loaded with the 4 bit output of the ALU, while the 
remainder of the register is unchanged.
\end{description}

\subsection{E register}
Although the E register consists of a single 4 bit shift register U1, it 
has the most complicated control circuitry of any of the processor 
registers. The R register is used when R=2, or X=3, or both and in all cases 
the clock to the E register is enabled by U7d and U8a. It is easiest to 
consider the 3 cases separately. 
\begin{description}
\item[X=3, R$\neq$2] : The mode input of U1 is high via U8b, so the 
register parallel-loads. Owing to its connections, the causes a right 
shift, loading the output of the ALU into the most significant bit. 
\item[X$\neq$3, R=2] : The mode input is now low, so the register shifts 
right in the normal way. U14b is enabled, so the output of the T register 
({\bf T(0)}) is loaded into the E register
\item[X=3, R=2] : Again the register shifts right as the mode input is 
low. U14b is now inhibited, so a 0 is shifted into the most significant 
bit of E.
\end{description}

\subsection{The ALU input data selector}
The input to the ALU, {\bf RegSer} is selected by the AND-OR-Invert gate 
U3, expanded by U2. There are 6 possible inputs as follows : When R=0, 
U17d forces a 1 into the ALU input; When {\bf BRd} is asserted by U16a, 
the output of the B accumulator is fed to the ALU; When R=1, the P 
register output is used; When {\bf ARd} is asserted by U16d, the A 
accumulator is read into the ALU; when R=5, the Q register is read; and 
finally  {\bf ERd} from U7d causes the E register output to be passed to 
the ALU.

\section{Input/Output System}
Although HP refer the input/output controller as a `processor' in their 
documentation, I think it is is more correct to refer to this section as a 
state machine. It transfers data between an accumulator and the I/O 
register. The latter provides a parallel input/output bus to connect to 
the various peripherals.

\subsection{Input/Output controller}
The input/output controller is located on the {\bf CPU Clock} PCB. It is 
a state machine which decodes part of the machine instruction in the Q 
register and controls the I/O register and related circuitry. The 
microcode is not involved in decoding individual I/O instructions, the 
same microinstructions are executed for all such operations.

An I/O instruction has the I/O operation code in bits 5\ldots 8, while 
bits 0\ldots 4 provide 6 `select codes' (00000, 00001, 00010, 00100, 
01000 and 10000) for various devices. Bit 9 is uses for some flag 
operations, the remaing bits are essentially the same for all I/O 
operations and are thus decoded by the microcode.

When no I/O operation is in progress ({\bf I/OOp} is deasserted), the I/O
operation bits (bits 5\ldots 8 in the Q register) are transfered to the
I/O command register in U16 and U17 via the NAND gates U15d, U11b, U15c
and U15b respectively by the {\bf I/OCmdEn/} signal produced by U6d at 
the end of each microinstruction. The outputs of this register are decoded 
by U9 which is eanbled by {\bf I/OOp/} but which is is also briefly 
disabled by {\bf I/OCmdEn/} at the end of each microinstruction. Thus the 
outputs of this decoder are pulses. For example, a logical OR of outputs 
of this decoder (from U3a) is used to clock the I/O register, as descibed 
below.

An I/O operation begins with a microinstruction where {\bf $\mu$(12)} is 
`0', R=1 and {\bf Q(10)} is `1'. This clears the JK flip-flop U1, thus 
asserting {\bf I/OOp}. The I/O command decoder U9 is thus enabled. At 
this point, the processor microcode enters a 2 instruction loop, waiting 
for {\bf I/OOp} to go low again, bringing {\bf Cond(15)} low via U2c.

There are 2 types of I/O operations. Those which involve a data transfer, 
and those (such as flag operations) which do not. The output of U3a ({\bf 
I/OClk} distinguishes between them, being high in the former case and low 
in the latter. 

In the case of a non-transfer operation, the state machine behaves as 
follows. Since {\bf I/OClk} is low, the output of U19a is high. Thus, 
when {\bf I/OOp} goes high, the output of u15a goes low, disabling the 
NAND gates feeding the I/O command register. When {\bf I/OCmdEn/} goes 
high, the command registers is loaded with all '1's. This causes {\bf 
I/OCmd(15)} to be asserted (low) which then clears the I/O Operation 
flip-flop, thus ending the microcode loop as described above.

For data transfer operations, the number of bits to transfer (minus 1) is 
loaded into the 4 bit counter U4. Since {\bf I/OClk} is now `1'. while 
the counter has not underflowed, U19a's output is 0, so the output of 
U15a is kept high. The I/O command register does not change.

When U4 underflows, {\bf I/OBr} goes low, so the output of U19a goes high 
and that of U15a goes low. The input gates to the I/O command register 
are inhibited as before. U11a is enabled, forcing the D input of U17a 
low. The command registers is loaded with `1101', and this `{\bf 
I/OCmd(13)}' state is used for any flag operations at the end of the data 
transfer. {\bf I/OClk} is now low, so on the next clock pulse, the I/O 
command registers is loaded with `1111' and the I/O operation terminates 
as before.
 
\subsection{Input/Output register}
The input/output register is a 16 bit shift register located on the {\bf 
I/O Interface} PCB. For communication with external peripherals, it 
provides 8 parallel data outputs ({\bf DO(0)}\ldots{\bf DO(7)}), 4 status 
outputs ({\bf SO(0)}\ldots{\bf SO(3)}) and 4 control outputs ({\bf 
CO(0)}\ldots{\bf CO(3)}). The last are used for for a 4 bit peripheral 
address. However, for communication with internal devices such as the 
display, the register can be used to provide an arbitrary 16 bit word. On 
input operations it accepts 8 data bits from the peripheral ({\bf 
DI(0)}\ldots{\bf DI(7)}) and 4 status inputs ({\bf SI(0)}\ldots{\bf SI(3)}).

In I/O data transfer instructions, one bit is transferred for each 
microinstruction executed in the I/O loop. Although, for timing reasons, 
each microinstruction is 2 clock cycles long, every alternate {\bf Bitclk} 
pulse is inhibited by U6c on the {\bf CPU Clock} PCB. Thus only one {\bf 
Bitclk} pulse is produced for each instruction. The microinstructions 
also cause the ALU to perform an inclusive OR operation 


An output operation is performed when {\bf I/OCmd(12)} is asserted. On 
the {\bf CPU Clock} PCB, the {\bf $\mu$(12)} is forced low by U19d and U11c, 
causing the selected accumulator to be read. The data selector on the 
memory timing board applies logical 0s to the {\bf ALUSerIn} input, so 
the data is passed through the ALU unchanged and latched in U13b on the 
{\bf I/O Interface} PCB by the {\bf Outclk} signal from U8c on the {\bf 
CPU Clock} PCB.. The output of U13b is then transfered to the I/O 
register by the {\bf I/OClk} signal. Depending on the state of {\bf 
I/OSize}, either the entire 16 bit register or only are used.

There are 2 types of input operation. The simple input (corresponding to
{\bf I/OCmd(10} being asserted) transfers the I/O register to the selected
accumulator, the more complex one (when {\bf I/OCmd(14)} is asserted)
inclusive-ORs the accumulator with the I/O register. The operation is very
similar in the 2 cases. The parallel data from the peripheral has 
previously been loaded into the I/O register by the {\bf I/ORd} signal 
and monostable U8. The I/O register is clocked as before, the {\bf InEn} 
signal is asserted by U2d and U18b on the {\bf CPU Clock} PCB. This 
causes the data selector in the memory system to feed the least 
significant bit of the I/O register (inverted by U20d on the {\bf I/O 
Interface} PCB, to compensate for the inversion in the data selector) into 
the ALU. The date is thus read into the selected accumulator.

The only difference between the 2 types of input instructions is that for 
the second one, the accumulator is also enabled for reading by U19d and 
U11c on the {\bf CPU Clock} PCB. This causes the data to be 
inclusive-ORed with the contents of the accumulator, rather than with 0.

\subsection{I/O Strobes and Flags}
The {\bf I/O Interface} PCB generates strobe signals for th various 
peripherals. Since the logic involved is fairly simple, to save space 
only the display strobe ({\bf DispStb/}) will be described here.

The display strobe is generated by the SR flip-flop consisting of the 
cross-coupled NAND gates U2c and U7a. The strobe is set by an end-of-data 
operation ({\bf I/OCmd(13)} is asserted) when the select code is 01000 
({\bf Q(3)} is high). It is cleared by an end-of-command operation ({\bf 
I/OStb} is high) with the same select code). 

Similarly, many devices have status flag bits, such as the card reader
status flip-flop U4c and U4d. All the peripheral flags are combined by the
AND-OR-Invert gate U9 (controlled by the device select code bits) and fed to
the {\bf I/OFlg} line which goes to the {\bf CPU Clock} PCB. A
skip-on-flag-set instruction, corresponding to {\bf (I/OCmd(5)} being
asserted) will set the CPU carry flag thus skipping the next instruction)
if the associated flag is set (and thus {\bf I/OFlg} is low) via U10d,
U10c and U19c. The skip-on-flag-clear instruction (when {\bf I/OCmd(1)} is 
asserted) does the same thing if {\bf I/OFlg} is high via U19b and U19c.

\subsection{Interrupt}
The {\bf KeyDn/} signal is really an interrupt input to the processor. It 
can be pulled low by any peripheral device whereupon the output of U3f 
on the {\bf I/O Interface} PCB goes high. This brings {\bf Cond(12)} low 
via U4a, and this condition is tested by the microcode near the start of 
the fetch-execute cycle. 

The interrupt handler microcode routine executes an instruction where 
{\bf $\mu$(12)} is low, R=1 and bit 10 of the Q register is 0. This does 
not start an I/O operation because {\bf Q(10)} being low prevents U1 on 
the {\bf CPU Clock} PCB from being cleared, Instead U3c asserts the {\bf 
KeyAck/} signal which sets the SR flip-flop U2a,U2b on the {\bf I/O 
Interface} PCB. Thus {\bf Keylatch} goes low, inhibiting U1b and U4a, and 
deasserting {\bf Cond(12)}. When the device deasserts its interrupt 
output, U2a, U2b is cleared and the processor is ready for the next 
interrupt.

\section{A little of the Microcode}
I do not intend to cover much of the microcode -- those who are 
interested in how machine instructions are executed should spend some 
time with the microcode listings. However, since one way of determining 
what the CPU is actually doing is to examine the microcode address on 
the test connector with the logic analyser, I will give a few important 
addresses.

It is conventional to give the microcode addresses in `split octal' 
format. The 8 bit address is split into 2 4 bit sections, each is 
separately converted to a 2 digit octal number and the these are 
concatenated. In other words, a microcode address consists of 4 digits. 
The first, either 0 or 1, gives the value of bit 7. The next, any octal 
digit, gives bits 6\ldots 4. The next, again either 0 or 1, gives bit 3, 
and the last digit gives bits 2\dots 0.

The fetch-execute loop begins at 0202 which, together with 1603, 
increments the program counter. At 1612, the next machine instruction is 
read into the T register, and at 0616 it's transfered to Q. The interrupt 
signal is tested here too, The interrupt handler begins at 1602, while 
the normal instruction decode begins at 1213 by setting the accumulator 
selecting flip-flop and determines whether this is a memory-reference 
instruction

The other important routine for hardware debugging is the I/O loop at 0512
and 1207. The main processor stays in this loop while the I/O state
machine is in operation. Should there be a failure with the latter, the
processor may end up stuck in this loop. Of course tracing the microcode
address will reveal this. 

