A PIC BASED ELLIOTT 803 EMULATOR
I've been working on a software based emulation of the 803 for a long
time, but while over at TNMOC last
weekend we started to talk about building 803 emulators with PICs. KevinB said he had
already been thinking along these lines using a 16F877
. I've used these in the past, but I'm currently using the newer
18F series such as the 18F4520
. One advantage if these newer devices is that they can run at
twice the clock rate. Although I've only done some rough
calculations, I think an 18F device will just be fast enough to emulate
Although a PIC has enough processing power to emulate the instruction
set of the 803 it does not have enough internal data memory to hold the
contents of the 803's core store. 803s could either be supplied
with one or two core store modules. Each module held 4096 words
on memory, with each word consisting of 39 bits of data and 1 parity
check bit. So an 803 with both store modules had 8192 * 40 bits
= 8192 * 5 bytes = 40960 bytes. I decided it would be easiest to
implement this as 5 x 8K static RAM chips.
The board is as shown above. The firmware is able to read and
write words from the "core store".
I've written the main fetch-execute cycle code and implemented the "00"
no-op and "40" jump instruction. The first
program was a single "jump to 1024" instruction in location 1024.
When the emulation starts at location 0 the address
LEDs can be seen counting up as the no-op instructions are fetched from
successive locations. Once the address reaches 1024 it stops and
the loud speaker emits the "dynamic stop" frequency
(3472Hz). I'm now working on the instructions from groups 0 to 3.
Well, much debugging later it's running a slightly more complex program
that involves functions "22", "55" and "40" and B-modification.
It is getting close to the point where the initial instructions will
which means I need to arrange a method of getting paper tape read
instructions to work. I have some I2C EEPROMS somewhere, maybe
I'll try using one of those to store a paper tape image.
8/4/2009 I've added an RS-232 interface in the space just below the
PIC. Using a very simple protocol the 803 can request characters from a
paper tape file when it executes a "71" instruction.
Also for debugging the emulator can send the op code
for each instruction is obeys up the interface to be displayed on a
PC. A sample of the output is shown below.
26 73 26 26 70 03 46--- 30 20 00 22 40 22 70 03
42--- 47--- 06 42 00 42 22 01 46 22 02 42--- 41
--- 43--- 22 44 01 41 00 41 05 42 22 30 04 05 46
22 30 04 07 42 22 30 03 05 46 22 02 05 42 22 30
20 00 01 02 03 04 05 06 07 30 05 46 22 70 03 46
--- 30 10 30 11 30 12 30 13 30 14 30 15 30 16 30
17 30 05 46 22 30 20 06 10 05 42 22 30 20 11 04
42--- 74-01 74-01 74-1c 44 30 20 12 05 42 22 30
KEY: XX octal opcode
XX--- XX is a conditional jump not
taken 74-XX Function 74 punch a
The program is part of an original 803 test program called
COM240. On the last line you can see it punched the
characters 01,01,1C which indicate that the preceding
instructions produced the wrong
9/4/2009 I seem to have spent most of the last two days implementing
and debugging the Group 6 (floating point) instructions. At least
I have a known working "C" implementation to work from, otherwise it
would be much harder. I know this because I can remember how hard
it was when I was writting the "C" version ! Having a
working (virtual) 803 to use as a reference is very helpful. I've
been able to add some logging to the "C" code to dump out the values in
various registers as the instructions are executing, then I've added
similar output to the PIC code and by comparing the results I can find
the cause of any differencies. Along the way
I've discovered I have the programme sheets for a later version of X5
(Floating point test programme) than the paper tape version. So
sometime I'll have to sit and type in the "T2" version from the sheets
and create a newer version. It seems to test some potential
hardware design bugs !
I also realised that the 19200 baud serial line is much too slow to do
debugging in real time, so I've had to slug the PIC code to wait
instructions to give the USART time to empty the transmit buffer.
I've purchased some small switches to make up a real word generator.
11/4/2009 After a day out flying models I got back in the evening
and added some extra buffering to make the paper tape read function run
faster. Then with the addition of code to toggle a couple of the
word generator bits I attempted to load the Algol 60 compiler....
10 minutes later it was loaded and it actually compiled a quite complex
programme. However shortly after the programme started to run it
stopped in a dynamic stop, so there is something wrong somewhere.
I'll run the same programme on the software emulator and get a full
trace output to compare with the trace output from the pic
emulator. Hopefully I'll be able to see where the two traces
12/4/2009 A day of heavy debugging ! I was able
to compare the two trace outputs, and fix a couple of error in the pic
code. One instruction was incorrectly clearing the auxillary
register when it shouldn't, and the double length divide was only
shifting the single length accumulator. So now it is sitting here
on the bench running an Algol programme :-) Off to TNMOC
tomorrow to show it off!
13/4/2009 I showed off the emulator at TNMOC, and it seemed to
impress everyone that saw it :-) There is still a bug some where
that is causing problems with floating point numbers in Algol
programmes. I'm not sure if the problem is with the floating
point instructions (group 6 functions) themselves or if it is
with some other instructions that are used when reading and
printing floating point numbers.
14/4/2009 I've spent the evening trying to compare the
trace outputs from running an Algol programme called "SIN AND COS ON
THE TELEPRINTER". I had hoped to determine exactly where the
floating point problem first shows up but it proved a little more
difficult that I expected. I really need better control of the
PIC803 so I'm going to move my attention to building a word generator.
16/4/2009 The word generator is begun! All the switches and
resistors are mounted and the 4 PIC sockets are in place. I
finally settled on a design that will use 4 PICs to monitor the 55
switches on the console/word generator. Their USARTs will be
daisy chained (Tx to Rx) to make a ring with a 5th PIC that will have a
CAM bus interface to the CPU. I've not used CAN bus before so I'm
going to have a bit of learning to do.
17/4/2009 To start with I've wired up the "N1" row of switches to one
of the PICs which I've fitted with an ICSP connection so that I can
develop to code "in place". The aim is for all four PICs to have
identical code in them, but they will configure themselves at startup
when the find which position they are in the daisy chain. Their
position in the chain will select which row tag they use
when sending button state messages. For now the
first PIC is just sensing button presses and turning on the
appropriate LED, and turning them all off when the row clear
button is pressed.
18/4/2009 After a whole day of wiring up switches and then debugging
four PICs at the same time, I finally have a word generator that can
send messages to the CPU. However the plan is to use CAN bus to
send those messages, and CAN bus is a whole new can of worms !
First off I have to rewire the CPU board because I used PORTB as the
data bus to the RAM chips, and the CAN bus signals are on RB2 and RB3.
19/4/2009 I spent the morning debugging the CPU board with the
re-assigned ports. It took longer than I expected because
somewhere along the way all my variable got moved out off the access
bank and into bank 1, which made a lot of stuff not work any more
! Oh well...... It's going again now. So now I
can start to tackle CAN bus programming. I'll take a picture of
the word generator later on this afternoon.
The large PIC on the right is a 18F4580, which has a CAN (Controller
Area Network) interface. The four smaller PICs are 18F252, and
each one monitors a group of switches (N1,N2,F1+F2,Control). The
word generator is set to 40 7:00 0 and the READ control button is
pressed. So far all I've managed to do with the CAN module is to
send a single message to itself via its loopback connection.
24/4/2009 Lots of stuff done over the last few days. Mostly
to do with getting CAN to work. The documentation makes sense
once you know how it works, but coming at it from cold it is pretty
useless. I did find some simple examples of CAN driver code
written in C which I was able to translate into some assembler.
Here is the Word generator connected up to the CPU via CAN. You
can see the small 8 pin CAN interface chips on each board and the
two 3 pin mini-DIN sockets that I've chosen as my CAN
connectors. The plugs with no wire coming from them contain the
bus termination resistors that need to be connected to each
end of the network.
All the control buttons (except Selected Stop) work, though there are a
couple of things to sort out still. 1) Releasing the manual data
button should let the program continue without having to press the
operate bar, 2) While clearing store there is a high pitch tone from
the speaker (it should be silent).
26/4/2009 I've just written a small Algol programme to try and
track down the problem with floating point numbers... Here is the
BEGIN REAL A,B,C'
The non-standard "ELLIOTT" function allows a word of 803 machine code
to be inserted
directly into the final programme, so it's sort of like the "asm"
feature found in some C compilers.
The word inserted is "70 0:20 A" which reads the word generator into
the accumulator (Function 70) and then writes the accumulator into the
variable A (Function 20).
This allowed me to set A to a known correct floating point number, and
then to multiply it by what might be 100.0 and to divide by what might
be 100.0 It is possible that the code in the compiler that
converts the string "100.0" into a floating point number is subject to
the bug, so that's why I say "what might be 100.0"
When I ran the programme on the software emulator and set the
word generator to 0.5 it printed the expected result... ".50000000
BUT.... on the PIC emulator it printed " .50000000 43.945313
.00447035" Hmmmmmm Lets try
something that doesn't need the compiler to convert strings to floating
BEGIN REAL A,B,C,D'
Software emulator .50000000 128.00000 64.000000 .00390625
Hardware emulator .50000000 117.18750 62.500000 .00357628
The next step is to run both emulators with the instruction trace
turned on and to compare the values in the accumulator after each
27/4/2009 The floating point bug is dead !
FREE STORE= 4630- 6551
.50000000 128.00000 64.000000 .00390625
END OF PROGRAM
It was a problem with the "T" register which holds a value with only
one bit set. It indicates where each bit of the result goes as
the division proceeds. Each iteration shifts the T register one
place right, but in the PIC code I had used
it now reads
rrcf TBit3,F ; OPSE BUG ! These were ,W
As I'm typing this the emulator is working away printing out sin and
cosine tables :-)
So now I can get on with the next part of the hardware, which is
another board with a PIC and CAN interface and an IDE interface!
I have a CompactFlash to IDE adapter board so I'll be able to store
paper tape images onto a CF card and read them into the emulator.
1/5/2009 The wiring on the IDE board is finished and I've started
to test it.
Top left is the 18F4580, and below that is the address decoder.
The for chips either side of the IDE connector are all 8 bit
latches. These multiplex the 16 bit IDE bus onto the 8 bits of
PortD on the PIC. The clock and output enable signals are
arranged so that the 16bit side can be read or written in one step, and
the data presented to the 8bit side in two steps.
Top right is a latch and LED drivers which will show what is going on
(Sector read, Sector Write etc).
The sockets for the 8kx8 RAM and its address latches are empty, as it s
the CAN bus driver (8 bit socket bottom right) and the RS232 driver
So far I've only written some test code that shows the address decoder
and the latches are working. Now I have to start to write
the code to actually talk to a compact flash card which will be
connected to the IDE bus.
2/5/2009 I spent the morning checking all the connections to IDE
conector, and that the latches work as intended. Everything
seemed to be working OK. I found I had to add a few "nop"
instructions at critical points to give things time to settle before
clocking the latches.
Eventually (after a good afternoon of model flying) I plucked up
the courage to plug in the IDE interface and the CF card. I had
used a PCMCIA to CF card on my laptop to write a count into the first
sector of the CF card so it would be easy to tell if it was being read
correctly. I wrote some code to dump hex values to the
serial line so that I could see what was being read. The first problem
was that the data request bit in the status register never seemed to be
getting set, then I remembered to turn off the comparators that share
RD0-RD4 and it started to work. So far I've only read sector 0
(in LBA mode). I also realised I had forgotten to make
provision for driving the clock pins on the address latches for the RAM
chip, so an extra 74HC00 has been added to the board. Everything
is now wired up, so tomorrow I hope to get sectors being read into the
RAM, and then passed out to the CPU over the CAN bus.
3/5/2009 A marathon session today ! But... ***It
The programme in the IDE board is a bit crude (e.g. there is no error
checking on the IDE or CAN interfaces) but it works. The CF card
has been programmed with four tape image files simply concatenated
together. The four files are the Algol tapes 1 & 2, then the
"cogs" alogol programme tape and then the "cogsData" tape.
And it all runs at the right speed. Looking at the CAN bus
signals on my 'scope while the Algol compiler is loading ,
I can see a message coming from the IDE card every 16ms.
This contains the next 8 characters from the paper tape image, so the
reader is getting 8/16ms = 500 characters a second (which is the
Next step is to structure the IDE/CF card's code a bit better as it
really only the code I've written to test the IDE, CAN and RAM
interfaces all glued together. I've got a design for a simple
format to use to represent tape images on the CF card. It doesn't
need a proper file system as it only needs to be able to find the start
of each paper tape image and then read the characters sequentially
until it gets to the end of the image. Also it will need to be
able to create new images from the characters punched on the virtual
tape punches on the 803.
7/6/09 Over a month since the last update! I've been working on
two things in that time. Firstly an interface for a real paper
tape reader (more on that later) and secondly a small LCD
display. I already had this wired up to a board with an 18F458 on
it. I've upgraded the PIC to an 18F4585 and added a CAN interface
so that the various devices can display messages and output etc.
The first thing I did was to get punch output to appear on the
LCD. Currently I'm working on a higher level protocol to use
between the CAN nodes. Raw CAN can transfer only up to 8 bytes in
a frame which isn't enough for some of the messages I need to
use. So I'm working on a protocol that will allow up to 64 bytes
in a message. This has prompted some major reworking of the CAN
code and the implementation of a memory heap which can be used to store
21/6/09 As promised some details on the paper tape reader. I last
used this reader about 25 years ago on the first microprocesor system
that I built. It has sat patiently on my shelves wait for the day
when I would once again want to read some old paper tapes :-)
These are the two original
boards from the reader. On the left is the amplifier board which
produced logic levels of +/- 16 Volts! On the right is the
stepper motor drive board. The three power devices are
thyristors, one for each of the motor windings. The board has two
inputs, a "direction" signal (forwards/backwards) and a "step"
signal. Although this was working when I first turned the reader
on, it stopped working some time later.
As you can see I removed the edge connector pins from the original
boards so that I could mount my replacement boards in the chasis.
Luckily the pin spacings were 0.1".
I decided to build the actuall amplifiers on a daughter
board so that I could easily change the circuit if my first design
didn't work too well. The picture shows the Mk.II amplifer board
! The circuit is similar to the original but has values optimised
for running of a +5V supply.
The new stepper motor driver uses three power FETs to
drive the coils. This board also contains the serial interface
for communication to the 803 emulator. The ribbon cable joins the
two boards and carries the parallel signals from the amplifier board to
the PIC on the stepper board.
When a character is requested the PIC turns off the currently enabled
coil and turns on the next one to start the tape moving to the next
character. The PIC monitors the sprocket hole channel and when
the tape has moved and the next sproket hole has appeared it latches
the 5 data lines and sends the character out on the serial
24/10/09 Long time no update ! I'm about to start work on the PIC
emulator again, but this time for a different purpose. The real
803 at TNMOC occasionaly does something "odd". I'm going to try
and build a PIC 803 that can run in parrallel with the real 803 and
watch various 803 registers to detect differencies. It's quite a
challenge, but I've already goto some FIFOs to buffer the values
comming from real 803 via hardware similar to the 803 diagnositc tool.
8/12/09 I've been reworking my CANBUS networking code to support larger
messages using multiple CAN frames. The first device I've used
this new code on is a VDU.
Many years ago the first PC I built used a Herculese monochrome
graphics card. The card itself has an 8 bit ISA bus interface and
I've been meaning to interface it to a PIC for a long time. So I
recovered an 8 bit ISA socket from an old 80386 mother board and wired
it up to a PIC.
The Herculese MDA clone plaaced in the 8 bit ISA socket.
As you can see the PIC board is quite simple. A couple of latches
to provide the lower 16 bits of the address bus. The top four
bits are hard wired as "B" to give the address B0000 for the cards
memory. The top four bits are ignored for i/o port
addressing. The 8 bits of the data bus are wired directly to
PORTD on PIC. The six red LEDs are wired to PORTA for debugging
purposes. The small 8 pin i.c. is the CAN BUS tranceiver.
So far the only thing that sends messages to the VDU is
the Word generator board which sends a few simple test messages to the
13/12/09: Here is a better picture of the VDU
display. It's now able to act as the teleprinter for the PIC803
emulator. The picture shows the output from a copy
programme. The input was an ALGOL 60 programme tape.
I've also been woring on the TapeStore code. (TapeStore is the new name
for the IDE board) I can now enter an offset on the numberic
keypad and the virtual tape reader will start reading from that adderss
on the Compact Flash card. The next step is to implement an index
or directory so the wanted file can be easily selected.