After writing about building a 68020 computer I feel slightly silly for going back on my word: I have built up a 68008-based computer on breadboard.
For one thing going right to a 68020 felt a bit like I’d be missing out; the pleasure is in exploring not the end result. I’d have left out on the other MPUs in the 68K family. Secondly there’s the practical – whilst the circuit was pretty close to being a working design, working on my 68008 computer has revealed a couple of errors in the 68020 schematic. Finally I was not terribly pleased with the PCB design: It has far too many vias for my liking.
So I’ve gone back to the beginning of the 68000 family and built a micro based on the 68008, on breadboard, and it works too!
Glue logic is provided by the MAX 7000 CPLD‘s smallest family member, an EPM7032S in PLCC44. This CPLD has a mere 32 register bits, but it is sufficient for this task and fits nicely on the breadboard in a PLCC44 to DIP44 adapter. The CPLD is directly attached to a LED bar-graph to save having to use an external addressable latch, using 16 pins (8 for the MPU databus and 8 for the LED outputs) in the process, out of the available 34 or so. The CPLD is programmable via JTAG using the same USB Blaster that I used in my earlier projects which used Altera FPGAs.
Here is a picture of the breadboard layout as it currently stands, a few days after recording the video above, where only the MPU, EEPROM, CPLD (with attached bar graph) and reset circuit were connected:
It is horrifically untidy but somehow it appears to be quite reliable!
To save breadboard space a 32KB SRAM is used instead of the more typical, for my projects, 512KB part. The UART (actually a DUART) is a SCN2681 (PDF) This is very similar to the XR88C681 I’ve previously used. I originally wanted to use a DS1813 (PDF) for the /RESET generation but it has caused me issues, which I’ve yet to get to the bottom of. I may switch to the more traditional, for contemporary 68000-based micros, 555 timer to generate the power-on /RESET pulse.
The following hardware has been proven out in stages, in a very similar way to how my 6809 breadboard computer was:
- AT28C256 (PDF) 32KB EEPROM: I dusted off my old EEPROM programmer and wrote a test routine which outputted the very same test patterns used on the 6809 to the LED bar-graph. This is what’s shown in the video above.
- AS6C62256 (PDF) 32KB SRAM: RAM was added and just like before the code was modified to exercise it.
- SCN2681 (PDF) DUART: Finally I was able to “talk” to the there-slab computer. Mirroring my previous efforts, a read-text, write-text test program was written.
The VHDL written for the EPM7032 CPLD is pretty straight-forward and was written following guidance found in a mid 90s book on the 68000 MPU family, Microprocessor Systems Design: 68000 Family Hardware, Software and Interfacing by Alan Clements. This is an amazing book which covers many different topics, but mostly focusses on practical information on building 68000 systems, with a couple of chapters on assembly thrown in. The edition I have covers up to the 68040, in a limited level of detail. It also covers some of the more common peripheral ICs Motorola added to the 68K family, and the co-processor interface on the 68020 and later. But the main use I’ve had out of the book is in the description of how the MPUs should be integrated in their larger systems, ie. glue logic construction. It briefly touches on using Programmable Logic, but uses ABEL as the language so I mostly referred to the schematics presented and translated them to VHDL. It seems that FPGAs and VHDL were just becoming mainstream when the book was written.
My VHDL implementation includes a /DTACK generator. The 8MHz clock (the 68008 I have is actually rated at 10Mhz but I don’t have a 10MHz oscillator) is slow enough that the SRAM and EEPROM can run full speed but the DUART, if I have interpreted the datasheet correctly, requires wait states to run reliably. The /DTACK generator is implemented via a counter, loaded with a suitable value until such time as the DUART is selected, when it starts to count up until it overflows, which asserts /DTACK. If the DUART is not selected, /DTACK is stuck being asserted.
The rest of the glue is pretty simple stuff: an address decoder, and an addressable latch (the CPLD has only one byte-wide addressable register) for the bar-graph LED array.
The only remaining part, then, is the software side. Whilst there are a fair few 68K assemblers available, I’ve gone with the GNU tool chain for my 68K projects. This is pretty cool, as the 68K port of GCC (including an assembler) is available in the standard Debian repos – no messing around downloading source code and compiling up the tools. I have made another Git repo for random bits of 68K project work, which includes the Makefile I’m using for building my EEPROM images. There are 3 steps required to build an image:
- Assemble: self explanatory really. No special switches are needed to turn the source code (using the .s extension, following GCC standards). I probably should be forcing the assembly step to be 68000 compatible, as it lacks some advanced instructions present in the later models which I might accidentally end up including in my code, which would produce incompatible code.
- Link: this is a little more involved. A linker script is needed to push the various code sections into the correct address eg. the exception vector table starts at location 0 and the SRAM is currently mapped to 0xe0000 to 0xe7ffff, which is where the .bss section lives. Currently each image is created from a single source files, so multiple objects do not need to be linked.
- Convert to binary: the linking step produces a machine code file in ELF format. This is not suitable for burning to an EEPROM so an extra step is needed to convert the ELF format file to a raw binary image, padding it to the size of the EEPROM image which – because of the limitations in the memory space on my previous 6809 based machines – is still 16KB instead of 32KB, something which would be trivial to fix.
The second to most trivial example, the EEPROM and SRAM test, shows nicely the general code structure for a simple program runnable on the 68008 breadboard micro. Some of the more interesting elements:
This forces word alignment on the output. This is needed because the 68K requires each instruction to begin on an even address.
.section vectors, #alloc resetsp: .long 0xe0fff | not using stack yet resetpc: .long _start | the initial pc
Only two vectors are defined: the initial Stack Pointer and the initial Program Counter. The 68K exception vector table is 256 long words in length, but only the first two are needed for a basic system. Other vectors include things like a division by zero handler, interrupt handlers, bus error handlers and so on.
Runnable machine code lives in the .text section, which the linker script places at location 0x400, 256 x 4 bytes in.
Read-only data lives in this section. This does lot live in any particular location, but follows the .text section in the EEPROM.
Finally, uninitialised global variables (ie. variables not on the stack) live in the .bss section. For the SRAM-exercising bar graph test, this includes the delay value (a word) and a copy of the patterns (a series of bytes) which is in RAM so it can be inverted on each run through.
The most interesting part is of course the code itself. As I said in my previous post, I have not done any 68K assembly – prior to a few days ago – but I did have a cursory knowledge of the registers, general capabilities etc.
Coming from the 6809, the 68000 ISA is incredible. A nice illustration of the power of the instruction set is illustrated by just two instructions utilised by my ROM/RAM test program:
move.b (%a0)+,(%a1)+ | copy a byte from a0 to a1
This will copy a byte from the address referenced by A0 to the address referenced by A1, incrementing both after the copy. Very nice. The 6809 could do this in two instructions, which is pretty cool, but it would have to modify a register. Of course on the 68000 you could move whole 32 bit quantities in the same way.
dbra %d0,copyloop | more, down to -1
This will decrement the referenced register, and if it reaches -1 it will not follow the branch. The usage of -1 caught me out at first and just means your counters must be initialised by one less the loop count. Many 8 bits have this kind of instructions but with less flexibility, eg. DJNZ on the Z80, but the 6809 lacks it so to me it’s very nice.
I’m only starting out in my 68000 assembly learning, but so far – I’ve been at it a week – it’s been great fun. There are some elements which seem inconsistent, and on balance I suspect the 6809 is actually more orthogonal then the 68000, but it certainly is great to work with and the sheer number of registers makes programming in assembly on the machine feel very productive. Not to mention all its niceties like hardware divide, operations on memory without reading data into registers, bit operations, etc.
So, what next? After getting the DUART working to the point where I can talk to the computer, I think the logical thing to do is to take a two pronged approach.
First up, I need to start writing another machine code monitor. This will be useful not just for the 68008 breadboard computer, but a future 68020 (or 030) micro, which will need a monitor for usage as a debugging tool.
Secondly I’m going to make up the schematic and layout a PCB for a 68008 based Single Board Computer. I’ve not yet settled on the details, including what peripheral ICs it will have. It will use a EPM7128S CPLD in PLCC84, like my planned 68020 board. It’ll have 512KB of SRAM (directly addressable!) and 32KB of EEPROM, and a SCN2681 DUART (or possibly a SC16C654 (PDF) QUART). And of course it’ll have a large expansion connector so I can hook up breadboards for experimentation with peripheral ICs.
One of the things I’d love to look at is building a SVGA video controller with one of the FLEX 10K FPGAs I used in the MAXI09 board, and the 68008 should be the perfect host for such a video controller, and be a great little project.
Finally, as well as the work on the 68K projects, I’ve made a lot of progress with my MPCNC build. After waiting for the parts to arrive, I’ve pretty much built the machine, at least mechanically:
The MPCNC is a beautiful design. I’m amazed at how smoothly the rollers move on the steel tubes, though my choice of using stainless steel no doubt helps there. There is no noticeable play anywhere either.
There is still quite a few tasks outstanding before I can try my first little CNC job; plotting out some shapes with a pen attached in place of a spindle with a cutting tool:
- Square the frame properly. So far it’s mostly square by virtue of using the same length tubing on each side.
- Install the timing belts so the X and Y runners can move under stepper motor control.
- Wire up the motors using the half-finished cable chains.
- Print a box for the controller board.
- Screw the machine to the table.
- Configure Marlin for the MPCNC machine.
The cable chain I used was printed using a design found on Thingiverse. This is the best cable chain I’ve found and prints very easily and snaps together well. However I could not find a ready made mount to attach it to the bottom of the MPCNC rollers, so I designed and printed my own. This is a first for me. This really shows the power of the 3D printing “work flow”: it is very quick to try out ideas and physically test them. Here is a close up of the part I designed and printed attached to my MPCNC:
Though it’s unlikely anyone else will find it useful, I will upload the part to Thingiverse just incase.
I have to say it’s awesome having two really interesting projects to work on!
My next post will probably be devoted to getting the first movements out of the MPCNC, as I intend to focus on that the most for the next week or so…