System68 - VHDL 6800

Please note that the URL of this web site may soon be changing

Please bookmark

System68 is a 6800 system on a chip based loosely on the SWTPc 6800. System01 is a 6801 derivative of the 6800 with additional 16 bit instructions and an eight bit multiply instruction. System01 has it's own page here.

Latest Version: - System68 for the Burch ED B5-X300 board.


SWTBUG ROM - on Michael Holley's SWTPc Website - Relocatable Macro Assembler and Linker by Michael L. Hasenfratz 

6800/6801/6802/6803 Assembler for DOS

Diagnostic routine for software tracing

TSC Klingon Space Game - S19 record format

Screen dump of Kingon Game on Hyperterm (Proof :-))

Swtbas22.S19 - South West Technical BASIC V2.2 - Compact Flash sector read/write - ROM Utility Program

29th June 2003

Epedit is a utility for loading, editing and saving binary eprom images. I have featured it elsewhere on this web site, but I have added an extra feature for generating initialisation strings for blockram. "Type Hex" selects the save mode to generate INIT_0x strings for blockram. These strings are generated so the Most Significant Byte comes first. ie:

$001F - $0000
$003F - $0020
$005F - $0040

The initialisation strings are 256 bits long, or 64 x 4 bit hexadecimal digits.

Example of using epedit:
/* specify motorola S1 format load */
Type Motorola
/* load file with <offset> being in hexadecimal */
Load <filename.s19> <offset>
/* set save mode to VHDL Block RAM format */
Type Hex
/* save file where <start address> and <end address> are in hexadecimal */
Save <filename.txt> <start address> <end address>
/* exit */

Epedit was compiled under cygwin and gcc, and uses generic C. It should compile under just about any C for the PC or other 32 bit machine. It uses a 64 Kbyte buffer so is too big for 8 bit machines. The executable probably needs a cygwin DLL to run.

ICST525-01 PLL Clock divider:

Check out the web site for a frequency calculator for ICST525-01 PLL chip. Given a 20 MHz Xtal oscillator, the ICST525-01 PLL should use the following dividers to generate a 4.915254 MHz clock:
0 = link in (grounded)
1 = link out (pulled high)



Revision Log:

17 January 2004 - CLR bug fix / UART update.

There was a bug reported in System01 which is repeated in System68 and possibly System11 and System09. Such is the peril of replicating a design. Basically the CLR instruction does not affect the carry. it should clear it. The reason is that state sequence used the "alu_ld8" (8 bit load) to load zero into the register or memory, but does not clear the carry. The carry is not affected. This is now fixed.

I have also updated the UART. It now supports a synchronous X1 clock. The Uart has separate baud clock inputs for TX and RX, just like the 6850. I've also implemented CTS so that it disables the TXbuffer empty when High (not CTS is active low) and I've also implemented DCD which reset the Receiver when high and can generate an interrupt if the RX interrupt enable bit is set. It has not been thoroughly tested, but should work.

I've revamped the start bit synchroniser. It now works much more reliably than before. I can now reliably download an S1 tape at 38.4 Kbaud, where as before it did not even work reliably at 4800 baud.

6th September 2003 12:48am - Ported for the B5-X300

This is a version has the clock phases reversed so that it clocks in the negative clock edge. The problem before was that RAM acceses were performed on the first clock pahse rather than the second. incorporates a 1K byte Slice ROM at $E000 - $FFFF and 1K Block RAM ROM at $C000-$DFFF. There are no cpu wait states. you can read RAMB4_S8 with the memory examine utility in the monitor ROM. The CPU remains much the same with the exception of inverting the clock. There are a number of test benches to exercise the UART, Block RAM and system as a whole. I've also added some address and data bus trigger logic to generate an NMI to the processor when various address, data and control signal conditions are met.

Revised 5 September 2003

It has been reported to me that the miniUART2.vhd file is missing from the 29 June 2003 release. I've added the file, updated the test bench for the miniUART. Swtbug_rom.vhd now includes the unisim library. The release is It compiles ok, but I have not tested it because it is for the B3-Spartan2 board, and I am now using the B5-X300 board (on loan) to get my 6809 design running. I will release a version shortly, although the cpu core cpu68.vhd should not have changed much (if at all). I put handshaking on the 29 June 2003 release so I could slow down accesses to block RAM, although I will probably remove it in the next release. There are major issues with the clock polarity on System68's which explains why they are so finicky interfacing to SRAM. I will correct that in the next release.

29 June 2003 

Han Pufal suggested I use initialized Block RAM for the ROM rather than building a ROM out of Slices. He has used the block ram feature of the Spartan FPGA for memory in his PDP8 and PDP9 designs. There are 7 Kbytes of block RAM available in the XC2S200 these are arranged as 14 x 512 byte blocks that may be configured as 1 bit, 2 bit, 4 bit, 8 bit or 16 bit memory block. They can also be configured as Dual Port memories. They go under the library name of RAMB4_S1/2/4/8/16.These block can be intialised with pre-defined values turning them into ROMs. I would prefer to make my designs as generic as possible, but the use of block RAMs on the Spartan FPGA was irrisistable, as I have used up all the slices in my 6809 design. Putting the ROM in block RAM allowed me to incorporate a monitor ROM in the FPGA rather than trying to boot it out of compact flash. I am using System68 as a test bed to verify that Block RAM ROMs work.

The Spartan II block ram is synchronous. Output is clocked on the rising edge of the clock signal. The address bus must be stable before the rising edge. In theory this should not be a problem for my System68 as the address changes as a result of the negative edge of the clock signal. With a 10MHz clock, there is 50nsec to set up the address. The constraints file limits the address set up time to 35nsec and these constraints appear to have been met. Providing Block RAM has a 15nsec access time, it should work in the design.

The block ram ROM "swtbug_rom.vhd" does not work where as the asynchronous slice version "swtbug.vhd" does work. The blok ram works fine when mapped into the "memio" memory examine and change utility wich also uses a falling edge clock, but uses a hand shake system to talk to RAM.

Also featured in this release is a Hardware "Trap" which can generate an interrupt to the CPU when an 16 bit address, 8 bit data or 2 bit control match is made. There are adresss, data and control comparitor registers as well as address, data and control qualifier registers which allows you to mask out which bits you want to trap on. I've wired the Trap interrupt to the NMI input. You'll have to read the comments in the VHDL code to determine how it works, as I have not had time to document it.

31 March 2003  - Mini Uart Fixed

This version should have the miniUART working ... although I must admit that at 19K2 Baud th UART is a bit fast for the 6800 core to keep up with when downloading S1 tapes.  I have written a Compact Flash sector Read/Write routine that allows you to write the contents of RAM into the Compact Flash module, one sector (512 bytes) at a time. It was assembled with the AS02 assembler listed above. I used it to save the SWTBUG monitor program at LBA sector number $F478 - $F479 and SBUG9 for the 6809 at $F47C - $F47F

30 March 2003 - Revised Mini Uart, Added Compact Flash interface

I've been trying to get the open cores mini UART to look more like a 6850 with word formating (7/8 data bits, odd/even parity, 1/2 stop bits). It has developed a problem in that it does not echo typed characters. I don't know why. Also I have modified the design so that the execute micro cycle is hidden behind the following fetch cycle. This reduces Immediate dual operand execution time to 2 cycles rather than 3 and direct dual operand adressing from 4 cycles to 3 cycles. I've also replaced the Parallel I/O ports with a B5-CF compact Flash interface from Burch Electronic design. I'm using it in 8 bit true IDE mode.

15 December 2002 - Corrected Error in clkunit.vhd

Its taken a while for me to pick this up, but there is an error in the TX clock generator in clkunit.vhd. Basically the TXEnab signal used to drive the Transmitter should only be high for one system clock pulse, or more to the point, the Cnt16 counter should only be inremented when the RXEnab signal is high. What had happened was that when Cnt16 reached the terminal count of zero it immediately reset rather than waiting for the RXEnab pulse so the transmit baud rate was not accurate.

This explains why the design could not be replicated. I thought I tested it properly before posting but apparently I hadn't. I have update the Webpack ISE software since then from 4.2WP2.0 to 4.2WP3.0 with service pack 3, but I doubt that would account for the error.

10 November 2002 - 6800 with DAT RAM

I'm not happy with my analysis of the memory problem. The output drive level on the pins of the FPGA look fine for A3, A4 and A5 and I cannot detect any shorts or opens on the FPGA or RAM Module. I have re-arranged the chip select and write control signals. I have also relaxed the timing constraints so they now pass. Relaxing the timing constraints from 80 nsec to 90 nsec on the ALU output and 30nsec to 35nsec on the address and data bus seems to make the design more stable. BASIC now runs more reliably. I've added DAT (Dynamic Address Translation). It consists of 16 write only registers mapped behind ROM at $E000 - $FFFF. Each register is 8 bits wide and selects the high order bank address of each 4Kbyte RAM segment. ie. register 0 at $FFF0 selects the bank for $0000-$0FFF, register 1 at $FFF1 selects the bank for $1000-$1FFF and so on. Only RAM is mapped through the DAT. I/O and ROM space are fixed at $8000 - $9FFF and $E000-$FFFF respectively. The value written into the register forms the physical address bits A12 - A19. Note that there is only 256Kbytes on the SRAM module. I've changed the data bus multiplexer so that D7 to D0 is used for the low bank ($00000 - $1FFFF) and D15 to D8 for the high bank ($20000 - $3FFFF). It should be possible to use the page mappping to form a RAM Disk.

5th November 2002

Seems I had a hardware fault on my board ... running memory diagnostics resulted in errors at $0052, $0050, $0150, $1050, $2050, $4050 and so on. By grounding A5 & A3 and re-assigning the RAM address pins, it fixed the memory fault (remember the address bus is shifted by one bit because the data bus is 16 bits). I must have damaged the FPGA pins when probing them with the CRO. It runs SWTBASIC V2.2 quite happily at 9.83 MHz. I've added a special ALU type for CPX so that the 16 Bit ADDD and SUBD update the carry flag as they should. CPX is a unique case on the 6800 in that it does not affect carry. I also played around with the overflow bit on the NEG instruction.

3 November 2002

There was an error in the Memory Data Register in that it was not loaded with the ALU output on Store instructions so the write cycles wrote garbage. SEV & CLV were not implemented in the ALU. The Overflow condition code on NEG may not have been quite right. I have got it running at 4.915 MHz again. Its hard to tell if the M6800 programming manual is correct or not. Multiply seems to work ... $5 x $5 = $19 = decimal 25. Decimal Adjust seems to work $8 + $9 = $11 => DAA => $17 these are not exhaustive tests by any stretch of the imagination but at least indicates its doing something right. SWT BASIC v2.2 load and runs ... I can enter a program and get it to print a character string, but it dies when I try printing or assigning numbers, so there is still something not quite right in the numerical operation. Note: that Test Bench 2 & 3 need to be updated to account for the test_alu and test_cc ouputs from the CPU.

I was having trouble with backspaces not being honoured properly by SWT BASIC V2.2.
Steve Tabler from the FUFU list kindly pointed out the following locations
$0154 = $0F = the delete / backspace character.  this should be changed to $08
$0155 = $5F = undeline character on the CT1024 and should be set to $00 for terminals with auto backspace.
These locations seem to have the same purpose on SWT BASIC V2.0 and V2.3 although the values may be different.

1 November 2002

The timing constraints indicate a clock to address and clock to cpu data set up time of within 30 nsec and a ram data to clock setup time of within 15nsec. The B3-SRAM is specified at 15 nsec access time so should be added to the address setup and ram data setup time. I've routed the ALU and Condition Code outputs to I/O pads so that Web Pack reports on the clock to ALU set up time. It reports this time is a little over 83 nsec. The clock cycle time must allow a register output to be passed through the ALU and be re-clocked into the register. This seems to indicated that the design should run at 10MHz, (100 nsec clock cycle) but when I increased the clock from 4.915 MHz to 9.83 MHz the CPU refused to work. I'm not sure if its a timeing fault or an error that has arrisen out of the modifications.

28 October 2002 10:08 pm

This is basically the 6801 core modified so that the CPX should not affect the Carry bit. It keeps some of the 6801 enhancements but the condition codes on ADDD and SUBD reflect the 6800's CPX instruction. I've reduced the serial baud rate to 9600 because sending an S1 record at 19.2Kbps is too fast for the CPU  running SWTBUG at 4.9 MHz (see above). I have a diagnostic routine which is supposed to single step instructions using SWIs. It needs a bit of work as it does not size the BSR instruction correctly. I've also gated the RAM chip select with the System Clock on write cycles, in the hope that it will make the system a little more stable. I got the TSC Klingon Space Game to work, but I'm not sure how ... the system is a bit wonky at the moment.

Back to FPGA Page