Making an Omnibus Peripheral Emulator

Contact for details.


These early PDP-8 systems have pretty front panels that include switches and lights. Many of the PDP-8 systems that are rescued are missing the peripherals, because the processor looks interesting and the peripherals do not. In many cases the processor does not come with the necessary peripheral interface boards, or the peripherals require extensive restoration. In any case, it is common to find the processors, but no peripherals.

I am attempting to use an Emcraft SmartFusion SOM Starter Kit to make an Omnibus Peripheral Emulatortm. I chose the SmartFusion FPGA because it contains a Cortex M3 processor in a hard core. That eliminates the need to invent an interface between the FPGA and a microprocessor. The FPGA has enough I/O to emulate any Omnibus peripheral, including disks and tapes. The Emcraft SOM Kit has 16MB of RAM and 16MB of flash attached to the ARM processor in the FPGA. This is plenty to run an embedded version of Linux.

Earlier, I did a proof of concept using a PDP-8/L and a smaller version of the Emcraft SmatFusion FPGA board to emulate a Posibus attached paper tape reader. The emulated paper tape reader worked just like a real one, but ran 10x faster.

The Plan:

The first project phase was making an interface from the +5.0VDC Open Collector TTL signals that are used on the Omnibus in the PDP-8/e to the +3.3VDC TTL signals that are used in the Actel SmartFusion FPGA. For the Posibus interface I used 74LVC245 ICs to translate the 5V logic levels to 3.3V that the FPGA can handle. Unfortunately these ICs can only sink 24mA on the outputs. The Omnibus wants 100mA Open Collector drivers. After a lot of discussion within the PDP-8 enthusiast community we settled on the AM26S10 ICs. These are 5V parts and have 100mA sink capability, perfect for the Omnibus. Unfortunately the receive signals from these parts are 5V, so we will use a series resistor and a Zener diode to reduce the signals below the 3.6V that the FPGA can handle.

The Emcraft SOM Starter Kit has an Actel SmartFusion A2F500-FG484 FPGA with an ARM CORTEX M3 processor in a hard core, 16 MB RAM and 16 MB of flash memory so that it can run their port of uC Linux. I will create paper tape reader controller logic for the first project and put it in the FPGA. This logic includes the I/O device code and IOT decoding, the paper tape reader flag flip-flop, a signal to drive the skip-bus signal, 8 bits of paper tape data, and a signal to enable the data bus drivers. These functions run at "hardware speed" and do not involve the ARM processor. The rest of the paper tape reader is emulated by the Linux device driver and the Linux application. These functions can be much slower than the hardware.

The PDP-8 6014 RFC (Reader Fetch Character) instruction puts a 6-bit I/O device code on the Posibus and an IOT of 4. This IOT generates an interrupt that is handled by the paper tape reader controller Linux device driver in the ARM. The Linux device driver interacts with the paper tape reader controller logic in the FPGA, and provides a Linux device for the paper tape reader emulator application, and handles the interrupt from the RFC instruction. The paper tape reader emulator application reads a character from the paper tape image file in flash memory, writes the character to the paper tape reader data buffer, sets the reader flag flip-flop, reads another character from the paper tape image file in flash memory, and goes to sleep. When the device driver receives the interrupt from the RCF instruction again, it wakes the application which reads another character from flash and writes it to the paper tape reader device, and goes back to sleep. The double-buffering significantly improves the performance of the emulated reader.

The other IOTs for the paper tape reader will be added, and then the paper tape punch emulation will be added.

The same FPGA logic and Omnibus interface can be used to emulate any Programmed I/O peripheral on the Omnibus. This includes DECtapes, Floppy Disks, Printers, Analog I/O, Punched Card readers, and a boot loader ROM. All it will take is loading circuitry into the FPGA, writing the matching Linux device driver, and writing the device emulator Linux application.

Having a Windows based program to control the Omnibus Peripheral Emulator would be very convenient. The Windows application could be used to select which file image is used by the peripheral emulator, upload/download the file images, and let a PDP-8 application print to a Windows printer.

Taking this emulation further would add emulation for Data-Break (DMA) peripherals. This includes 1/2" magnetic tape, fixed disks, and high-performance video terminals. This would be a significant amount of work because of the complexity of the DMA interface and the timing constraints.

Progress Reports:


I used a Mupac Wire-Wrap board for the Posibus project, but don't have one for the Omnibus. Instead of spending about $600 for one, I bought an inexpensive Douglas 9-DE-8 prototyping board. This is a generic DEC board, so it needs a small modification to remove a connection to +15V on the Omnibus. Just getting started. The 74LVC245 used for the 3.3V->5V logic conversion will not work for this project. I need to select an IC that can drive the 100 mA open collector signals on the Omnibus. Time to talk to some experts.


Based on expert opinion I will use the AM26S10 transceiver to receive and drive the open collector signals on the Omnibus. I have a resistor/zener diode on the output of the AM26S10 to reduce the voltage going to the FPGA. It works so far.


The FPGA board is tied to the Douglas board. Screw machine IC sockets have been installed in the locations next to the Omnibus and AM29S10 IC installed in these locations. Additional IC sockets have been installed above the AM29S10 ICS that hold 330 Ohm resistors and 3.0V zener diodes. The zener reduced signal is only about 2.2V. This is just above the 2.0V TTL threshold. It seems to work OK, but eventually I need to increase this voltage to provide more signal margin. 2mm ribbon cables have been installed to connect the FPGA board to the signals from the Omnibus. It is not as pretty as I would like, but it works OK.


The FPGA will decode the paper tape reader and punch IOTs and respond with an Omnibus INTERNAL IO signal. The response time for decoding the IOT instructions is well within the 70 ns limit.

The next step is to debug the reader and punch Flag and interrupt logic. The flag flip-flops are connected to an ARM GPIO device so I can see and set the state of the flags and interrupt enable.

I need to add more buffer ICs for the DATA[0..11] signals and wire them to the FPGA. The data latches for the reader and punch are already in the FPGA.

I need to debug the Linux device drivers that connect to the reader and punch data latches. The Linux paper tape reader emulator application worked with the 8/L and should require minimal rework for this system. I need to create a Linux application to emulate the paper tape punch and save the output to a binary flash file.


Progress was delayed for a while because the power supply in the PDP-8/e died. Replacing the LM723 on the A2 regulator board fixed it. Nothing was damages when the power supply died.


I keep rethinking the design decisions. The AM29S10 splits the receive and transmit data on the FPGA side. That means I need to use twice as many FPGA I/O pins if it is both transmitting and receiving data on one of the buses. Since the FPGA I/O pins are limited this may be a problem when I implement Data Break. Because of timing restrictions for the Data Break signals, the implementation will need to be done in the FPGA fabric, and have nearly no firmware directly involved. I really need a 74LVCxxx part that can do the +5V<>+3.3V translation, has 100mA sink capability, and doesn't split the receive and transmit data.


I had some interesting challenges with the FPGA tools that wasted quite a few hours. The DEC schematic for the PC8-E shows a D-Type flip-flop for the reader flag. The PRE/ input is not used, the CLR/, CLK, and D inputs, and the Q output are used. I tried to make the logic in the FPGA as close as possible to the real board. To set the flag with the Linux application, an ARM GPIO was connected to the CLK input and D was tied high. The FPGA tool thinks that the CLK input is a clock, and tries to configure the output pin of the ARM GPIO device as an 80 MHz clock. This completely messes up the Verilog that gets created for the GPIO part and then it will not work at all. I ended up just connecting GPIO pins to PRE/ and CLR/, and tying D and CLK low. The Verilog outout works OK now, and I can set, clear, and check the state of the reader and punch flags, and the interrupt enable. Tonight I will wire up the SKIP and INT RQST signals from the FPGA to the Omnibus and see if they affect the processor correctly.


The SKIP and INT RQST signals from the "paper tape reader" from the FPGA cause the correct response from the processor.

The AM26S10 really drives the Omnibus signals hard. The 100mA sink capability is probably overkill. Maybe the 74LVC245 would have been OK as a transceiver.

The next step is to wire up the DATA[0..11] signals and see if it will read a "paper tape". I don't need to wire all of the signals for the paper tape reader, but I will need them all for other peripherals, so I might as well wire them all now. The AM26S10 splits the receive and transmit signals on the FPGA side of the transceiver, so I will need to wire a read and a write set of DATA[0..11] signals. The paper tape punch hardware emulation is ready to test. That will be next after the paper taper reader.


I wired data[0..3] but didn't see any data from the FPGA. It took a few minutes for me to realize that the paper tape reader only uses the lower 8 bits, so data[0..3] were being masked off by the Linux device driver.

I wired data[10..11], but now these bits get copied into the AC, even if the processor is not running! I had the "S" bus driver enable signal with the wrong polarity, so the bus driver was enabled except when the IOT was decoded. I swapped an OR gate for a NOR gate in the FPGA and now the bus driver enable signal has the correct polarity. One of the menu items in the test software running on the ARM in the FPGA will let me write arbitrary data to the paper tape reader buffer. Now I can transfer data from the ARM to the AC in the PDP-8/e. I need to wire data[4..9] so I can test the remaining data bits.

Another option in the test software lets me send a paper tape image file to the PDP-8/e. This worked great with the Posibus Peripheral Emulator, but here it is not waiting for the 8/e to read a character before sending another. I will debug this after I test the rest of the data bits.


I forgot to wire the C1 signal. Adding that and fixing a logic issue in the IOT decoding in the FPGA fixed the problem with the emulated paper tape reader.

The BIN loader loaded the 5,449 byte MAINDEC-8E-D0CC Adder test in about 2 seconds. I put a 'scope on the INTERNAL IO signal and the C1 signal so I could see the ratio of RSF to RRB-RFC instructions. It is a little embarrassing to see lots of RSF instructions and only see the RRB-RFC instruction once every 150 us. The 'scope says that the frequency of the RSF instructions is 416 kHz, and the frequency of the RRB-RFC instructions is 4,762 kHz. I really need to clean up the device driver code, and improve the app that reads a paper tape image from flash and writes it to the Linux paper tape reader device.


I started wiring the signals to transfer data from the PDP-8/e Accumulator to the FPGA. The first four bits work OK, so I am wiring the rest. I need to add more interrupt in the FPGA to the ARM processor so that it knows when a new character has been written to the paper tape punch. That means I need to update the device driver initialization logic to claim another interrupt, and to add another interrupt handler to get the new character from the paper tape punch data latch.

I will rewrite the device driver so that it has large buffers for the reader and punch data. When the Linux application reads a paper tape image from flash and writes it to the paper tape reader device, it will all go into a RAM buffer in the device driver. That should be much faster than handling a character at a time. The paper tape punch will write all of its data into a buffer. Then a Linux application will read the data from the RAM buffer and then empty the buffer. I was thinking that 32kB buffers should work OK.

I can do the same for the diskettes and disk drives. The RX02 diskette only holds 256kB, and the RK05 holds 2.4MB, so I could buffer that in RAM too. The RX8E diskette controller does not use data-break (DMA) so that should no be difficult to emulate. The RK8E disk controller does use DMA. That will require another 20 or so signals, and LOTS of logic in the FPGA. It might be easiest to create the data-break controller as a logic block written in Verilog.


I finished wiring the signals to transfer data from the PDP-8/e Accumulator to the FPGA. All of the bits work OK. Time to go back to writing device driver and utility firmware.


It's about time that I updated the progress. I can reliably transfer data between the AC and the FPGA. I have been pondering the way that the Linux device driver and Linux drive emulation application work. My current plan is to rewrite the Linux driver to include a memory buffer for each device. For the paper tape reader, the Linux application would empty the buffer in the driver and then fill the buffer with the paper tape image from flash memory. The driver would send one character for each IOT and stop when it is out of data. For the punch, the driver would receive a character per IOT and save it in the buffer. The Linux application would empty the punch buffer and write it to flash memory. This would also work nicely for the diskette, disk, and tape emulation.

I will also implement an Omnibus serial port with a configurable bus address. This would let me have the console, or one of the secondary serial ports emulated by the FPGA. I will modify a Linux serial device driver to use the FPGA logic. Then I can Telnet into the Linux processor from the network, and run minicom to connect to the Omnibus serial port. That will let me have Internet access to the PDP-8/e console.