Rockwell PPS-8
General information | |
---|---|
Launched | 1974 |
Common manufacturer |
|
Performance | |
Max. CPU clock rate | 256 kHz |
Data width | 8 |
Address width | 14 |
Physical specifications | |
Package |
|
The Rockwell PPS-8, short for "Parallel Processing System, 8-bit", was an early 8-bit microprocessor from Rockwell International, announced in 1974. It had a number of unique design features, which Adam Osborne described as "most unusual... more powerful... also one of the most difficult to understand."[1] It was released with a suite of support chips, including ROM and RAM, a GPIO, parallel and serial controllers, and a direct memory access (DMA) system.
The release of simpler and less expensive designs like the MOS 6502 around the same time led Rockwell to pull the design from the market without entering widespread production. National Semiconductor had a cross-licensing arrangement with Rockwell, but they did not produce the PPS-8. The simpler Rockwell PPS-4 did not suffer the same fate, finding a number of roles in low-end systems and being produced into the 1980s.
Description
[edit]Physical construction
[edit]The PPS-8 was built on a metal gate process, compared to the contemporary Intel 8008 and similar designs which were based on the more advanced silicon gate PMOS logic process. The PMOS logic required large amounts of power; the PPS-8 ran on a -17 VDC power supply and also needed separate -12V, +5V and ground.[1] The circuitry dissipated so much power that the chip could not generate a strong enough clock signal internally, and the clock had to be an external chip in its own TO-100 package.[2] Like the PPS-4, the clock was based on a standard NTSC timing crystal as these were widely available. Inside the CPU, the clock's two-phase output, A and B', was used to build a four-phase internal clock running at four times the external clock rate. For instance, the normal 250 kHz clock became 1 MHz inside the CPU.[3]
Like the PPS-4, the PPS-8 was packaged in a 42-pin quad in-line package. The system had a 14-pin address bus, allowing it to address up to 16 kB of main memory. This was normally used in conjunction with the read inhibit (RIH) and write inhibit (WIO) lines to address two banks of memory, up to 16 kB of ROM containing a program, and up to 16 kB of RAM for data storage.[4] In an era when memory was very expensive and machines often used 2 to 4 kB of ROM and even less RAM, the limited address space of the PPS-8 was not a significant limitation. The CPU treated the two banks differently, one was for ROM containing program code, while the other was for RAM and contained data. The shared data bus was 8-bit wide, allowing it to read one instruction or word of data in a single cycle.[5]
Registers and memory
[edit]The PPS-8 is an accumulator-based design with only one general purpose 8-bit processor register, A. A second 8-bit register, W, was used to buffer data for some of the accumulator instructions, but could be used for general storage otherwise. It also had three 8-bit "data counters", X, Y and Z. X and Z mostly acted as index registers, but could only access "data memory", whereas Y was a secondary accumulator and also a buffer (like W) for the X register. The 16-bit L, for Link, register was used as an index register to program memory (ROM), whereas X, Y and Z pointed to data memory (RAM). There was also a 14-bit program counter and 5-bit stack pointer.[4][6]
Referring to a location in the data memory required a 14-bit address to be constructed with a 7-bit "page number" in the Z register and another 7-bit "byte number" in X. If bit 7 of the X register was 0, then the Z register value was ignored. This was used as a form of short addressing, which was more commonly seen in other processors as a "zero page" or "base page", the idea being that only a single byte was needed to specify and address and thus save memory in the program code and the time needed to load an extra byte in the instruction.[6] A single index register is a limitation, and additional addressing could be arranged using the L and Y registers. One operation swapped the values in X and Y, allowing Y to be used as a direct backup for X. A second allowed the values in Z and X to both be copied into L, allowing L to be used as a buffer for a complete 14-bit address.[7]
Additionally, the value in the X register could be automatically incremented or decremented by certain branch instructions. This made loops much faster as a single instruction would increment or decrement the value, test to see if it crossed zero (incremented from 0xFF to 0x00, or decremented from 0x00 to 0xFF), and if it had, skipped the next one or two locations depending on the opcode. To use this feature you would write a loop with one of these instructions at the bottom, followed by the address of the top of the loop. Normally it would not cross zero and the PC would be loaded with the following address, but when it did end, the address would be skipped over and the program would continue at the next instruction. Addresses could be 1 or 2 byte depending on whether the 7th bit of the first byte was a zero or one.[7]
The 5-bit stack pointer is normally implemented as the first 32-bytes of RAM. Like most systems, the S register is updated when data is pushed or pulled.[8] If S ever reaches 31, indicating the stack is full, the next instruction will be skipped, similar to the increment/decrement modes. This feature is intended to be used during power-reset routines. While small by standards set by processors like the Zilog Z80 or even the MOS 6502, this size of stack is suitable for systems that generally used it only for subroutine calls into ROM or interrupt handlers.[9]
Among its more curious features was that it only had two status bits, carry and intermediate carry. These were placed in bit 16 in L, which was otherwise unused due to the 14-bit addresses. Most processors of the era had additional status bits to indicate the outcome of comparisons, like whether the value in A is zero, but in the PPS-8 these were combined with the branch instructions so they did not have to be user-visible.[10]
Instruction set
[edit]The instruction set in the PPS-8 was relatively simple in terms of the numbers and types of instructions, including the typical add and subtract, increment and decrement, logical operations for AND, OR and XOR, shifts and rotates. As was typical for the era, the PPS-8 included instructions for directly working with binary coded decimal (BCD) data. This is a numeric format that stores a decimal digit in 4-bits, with two digits per byte. BCD is generally slower to process than binary numbers due to the "decimal adjust" step that is not needed for binary data, but can more than made up for this because it is very easy to convert to and from ASCII values. Not only did the PPS-8 offer BCD addition and subtraction, it also had instructions that shifted (rolled) an 8-bit value by 4-bits, making it easier to extract individual digits. The system also had instructions to load values from memory to registers, save from registers to memory, and, somewhat uncommon, exchange them in a single operation. Note that it does not have compare operations, as these are combined with the branches into a single operation.[11]
Although the instructions were fairly typical, there were a large number of addressing modes and thus a large number of opcodes. The load/store operations generally came in five versions, the base instruction, L, S or X, which referred to memory pointed to be Z+X, N mode which post-incremented the X value after the instruction, D which post-decremented, NXL and DXL which did the same but also then swapped the ZX value into L, and NXY which incremented X and then swapped it with Y. Finally, the NCX instruction incremented X and then compared it with Y as the decision of whether or not the branch was complete, rather than crossing zero, and DCX was the same with a decrement.[12] Access to the program memory was only through the PC or the L register; when using L, bits 16 and 8 were ignored to produce the 14-bit value. With all of these modes, if the upper bit of the lower byte of the address was zero, the upper byte would be ignored and thus allowed a form of short addressing similar to a zero page.[10]
One of the unique features of the PPS-8 was the concept of "data pooling". This was similar to the concept of a zero page but took this one level further to produce instructions that required only a single byte. To do this, several "pools" of memory were set aside for special purposes.[13] The first pool, the first four bytes in memory, were used to point to the power-on routines. The next 60 bytes, making up the first half of page zero, contained the "command pool". These were single byte values that held the second or third bytes of multi-byte instructions. The idea was to allow those instructions that were widely used in the program to be placed in the command pool and then referred to using a single byte whose lower 6 bits encoded one of the locations in the pool.[14]
The second half of page zero was used as the "literal pool". These could only be used with the instructions LXI, LYI, LZI/AISK and LAI/ANI. Each of these instructions was given its own set of 15 bytes, with the 16th left empty. The "I" in these instructions indicated that they used "immediate" addressing, meaning the operand was a literal value in the code. If this same value appeared in many places, which is often the case for hardware addresses and loop counters, they would normally have to be included in every one of these instructions. But by placing that value in the literal pool the opcode for the instruction could be reduced to two bytes, saving a byte every time it's used. This could be combined with the command pool to reduce the remaining instruction to a single opcode as well, making these common instructions go from three bytes to one.[15]
Finally, the first half of page one held the "subroutine entry pool", a list of addresses in program memory. These were stored with the high bytes in bytes 0 to 31, and the low bytes in 32 to 63. Using these slots, branches and subroutine calls could also be reduced to a single byte opcode. The use of data pools and the increment-compare-and-branch instructions allowed the PPS-8 to build loop structures in very little code, often as few as three instructions, and often with those being a single byte each. This made the system extremely efficient, but at the cost of being much more complex to program.[16]
Bus interface
[edit]The control bus was among the simplest of all processors of the era. The entire multi-chip system, including RAM and ROM, used only two control pins along with the clock signals. Normally the processor itself would alternate access to memory based on four-phase internal clock, with the address on the address bus referring to the data memory (RAM) or other devices on phase 2, and program memory (ROM) on phase 4.[17] When accessing memory, the RIH pin signals whether memory should be read (low) or written (high). To talk to devices, the WIO pin is pulled high, signalling memory to disconnect and devices to listen for read and write instructions based on RIH.[10]
There are three levels of interrupts, signalled by INT0, INT1 and INT2. The system supported vectored interrupts; when one of these pins is pulled high, the processor finishes the current instruction, swaps the PC onto L, and then calls the code located at an address stored in the first three slots in the subroutine entry pool. As these were in program memory, normally in ROM, generally these were dedicated to specific tasks. INT0 was the highest level, and normally used for a power failure signal which required immediate shutdown. INT1 was used for high-priority interrupts like the realtime clock, and INT2 was used for all devices. Once the system entered the interrupt, it pulled the ACK0 line high. The DMRA pin was used in conjunction with the DMAC device (see below), which pulled it high to indicate it wanted to take over the bus, and the processor then pulled it low again to indicate it was releasing the bus when it was ready. PO (power on) was the reset pin, which cleared the contents of all of the registers and began executing the instruction at address zero. SPO (synchronized power on) was then pulled low to cause the same to occur in any attached devices.[18]
Support chips
[edit]Rockwell designed the PPS-8 to be used with a series of additional devices that used the same bus protocol. Among these was a 42-pin 2 kB ROM, a 256 byte RAM, the GPIO, PDC, DMAC, SDC and some device controllers.[1]
The GPIO, short for general purpose input/output, buffered data to and from external devices. The chip included a set of 12 input lines and 12 output lines which would be connected to external devices, 4 lines each. Communications with the processor took place over the existing 8-bit data bus. "Instructions" we sent to the GPIO over the data bus using the upper four bits as a device number, 0 to 15, with the other four bits as an instruction code. The upper four bits are passed through to four "address strap" pins, which activates a single I/O device. This are used as device select lines, selecting which of the GPIOs or PDCs is being addressed. There are no connections from the GPIO to the address bus, meaning that all transfers to memory must be mediated by the CPU.[19] The GPIO also passes through one clock signal on the A pin to allow external devices to match the timing of the system.[20]
The PDC, short for parallel data controller, was essentially a GPIO re-arranged into two 8-bit ports, A and B, instead of three 4-bit ones. The chip includes more logic than the GPIO, which allows it to operate reading or writing data for each instruction from the CPU - essentially a parallel GPIO - reading or writing based on the clock without further intervention, and a "handshake" mode in which it continues to read or write until a stop signal is received on the CA2 pin. Additionally, it offers an alternative way to move data to and from the chip using the pins for channel A.[21] DMA was turned on by the CPU writing a bit to the PDC's internal status register, after which an interrupt was generated whenever the B port had new data.[22]
The DMAC, for DMA controller, was the only I/O chip that had connections to the address bus, allowing it to access data memory as an equal partner with the CPU. The DMAC had internal registers to support up to eight external devices. Each device had an address and buffer length register, mapping the area of memory they could communicate with. When a device had data, it would pull its DMA line high (1 through 8), and the DMAC would then signal this to the CPU by pulling the DMRA line high. When the CPU completed its current operation it would pull the DMRA low again, and the DMAC was then free to take over the bus.[23]
Note that the DMAC does not transfer data to and from the devices, it simply listens for DMA requests and then uses another chip, typically the PDC, to handle the actual transfer. When the request is received, it uses the pin number to select the base address for that device from its registers, offsets that by a counter value, and expresses the result on the address bus. It then uses the DMA0 pin to signal the PDC to activate that device, read a value from channel B, and place the result on the data bus. It is the combination of signals from the DMAC and PDC selects an address and reads or writes it to complete the transfer. DMAC could operate in two basic modes, a one-off mode in which the chip reads data from a device when it receives a signal on one of the device DMA line and then uses cycle stealing to transmit it to memory and decrements the counter, or in a permanent mode that mapped an area of memory to a particular device, which operates in a similar fashion but then resets the buffer length and address to the original values when the transfer is complete.[24]
Another chip in the family is the SDC, serial data controller. In general terms this is a three-output, two-input UART that includes additional logic to allow it to trigger the DMAC to perform the transfer into memory. For instance, one could set up the DMAC with a base address and buffer length, set up the SDC to read from device 1 with a particular setup like 8 bit data with 1 start and stop bit, and then whenever the SDC has received a full byte it will signal the DMAC to transfer it. The SDC could be used synchronous or asynchronous, with 5 to 8 data bits, optional odd or even parity bits, and one or two stop bits.[24] It was quite fast for the era, running in synchronous mode up to 250 kbit/s and async up to 18 kB.[23]
On top of all of this, Rockwell also had a number of chips dedicated to specific devices, like a printer controller (PCC), telecommunication controller (TDI), and keyboard and display (GPKD).[11]
Development
[edit]A PPS-8 assembler and emulator was hosted on Tymshare, GEnie and Rockwell's Time Sharing Option system. These were written in Fortran, and were also combined as a "assemulator". They also offered a number of pre-assembled evaluation systems.[25]
Complexity
[edit]A number of design features of the PPS-8 made it difficult to work with, or as Osborne put it, "the most difficult to understand."[1] Among these was the split addressing system that meant programs and data had to be stored in two banks, and referring to locations in the two banks was very different. Referring to an instruction in program memory used the PC and L registers as a single 14-bit value, whereas data was referred to using the separate X and Z registers, and sometimes Y. As if this were not confusing enough, the L register was also used as a buffer for the X and Z. On top of all of this was the data pooling system which added further addressing modes.[6]
Another feature of the PPS-8 was its bus system, which was designed for very high throughput. Using a combination of tight loops based on code in the data pools and the separate I/O bus formed by the DMAC, the system could process data at up to 250 k bytes per second, even running at a relatively slow system clock of 250 kHz. However, this also required significant complexity. The Rockwell documentation shows a basic system layout containing the clock chip, CPU, DMAC, PDC, SDC, several device controllers, and a user-selected amount of RAM and ROM.[26] In contrast, something like the Fairchild F8's two-chip basic system included ROM and RAM, three parallel ports that could also be used as serial lines or controllers like GPIO, meaning the same system could be built with a total of two standard 40-pin DIPs.[27]
Performance was good overall; Osborne lists a simple looping benchmark where the core of the loop requires only three bytes, allowing it to run much faster than the same program on other systems.[16]
References
[edit]Citations
[edit]- ^ a b c d Osborne 1976, p. 8.1.
- ^ Soucek 1976, p. 381.
- ^ Soucek 1976, p. 385.
- ^ a b Soucek 1976, pp. 383–384.
- ^ Osborne 1976, p. 8.11.
- ^ a b c Osborne 1976, p. 8.4.
- ^ a b Osborne 1976, p. 8.6.
- ^ Soucek 1976, p. 407.
- ^ Soucek 1976, p. 408.
- ^ a b c Osborne 1976, p. 8.9.
- ^ a b Rockwell 1974, p. 2.1.
- ^ Osborne 1976, p. 8.8.
- ^ Osborne 1976, p. 8.24.
- ^ Rockwell 1974, p. 3.24.
- ^ Rockwell 1974, p. 3.25.
- ^ a b Osborne 1976, p. 8.48.
- ^ Soucek 1976, p. 383.
- ^ Osborne 1976, p. 8.10.
- ^ Osborne 1976, p. 8.17.
- ^ Osborne 1976, p. 8.18.
- ^ Osborne 1976, p. 8.19.
- ^ Osborne 1976, p. 8.20.
- ^ a b Osborne 1976, p. 8.21.
- ^ a b Osborne 1976, p. 8.22.
- ^ Rockwell 1974, p. 2.3.
- ^ Rockwell 1974, p. 1.1.
- ^ Osborne 1976, p. 2.1.
Bibliography
[edit]- Introduction and Description Parallel Processing System (PPS-8) (PDF) (Technical report). Rockwell International. October 1974.
- Soucek, Branko (1976). Microprocessors and Microcomputers. John Wiley and Sons.
- Osborne, Adam (1976). An Introduction to Microcomputers, Volume II. Sybex.