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 an 803.

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.   



4/4/2009:
The board is as shown above.  The firmware is able to read and write words from the "core store".
5/4/2009
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 run 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 character XX 

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  result.    

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 between 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 diverge.

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 Algol programme.
FP WRDGENTEST'
BEGIN REAL A,B,C'
  ELLIOTT(7,0,0,0,2,0,A)'
  B:=A*100.0'
  C:=A/100.0'
    PRINT A,SAMELINE,B,C'
END'

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 50.000000  0.0500000"
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 point numbers.

FP WRDGENTEST'
BEGIN REAL A,B,C,D'
  ELLIOTT(7,0,0,0,2,0,A)'
  ELLIOTT(7,0,0,0,2,0,B)'
  C:=A*B'
  D:=A/B'
  PRINT A,SAMELINE,B,C,D'
END'

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 instruction....

27/4/2009 The floating point bug is dead !
FP WRDGENTEST
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
    rrcf    TBit4,W
    andlw    0x1F
    movwf    TBit4
    rrcf    TBit3,W 
    rrcf    TBit2,W
    rrcf    TBit1,W
    rrcf    TBit0,W
it now reads
    rrcf    TBit4,W
    andlw    0x1F
    movwf    TBit4
    rrcf    TBit3,F        ; OPSE BUG !  These were ,W
    rrcf    TBit2,F
    rrcf    TBit1,F
    rrcf    TBit0,F

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 (bottom left).

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 Works***  


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 correct rate).

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 packets.

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 interface.

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 VDU.

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.