Spartan 3 - System 09 - VHDL 6809

System09 is instruction set compatible with the 6809. It includes a 2KByte KBug9s monitor program along with a 6850 compatible ACIA/UART, PS/2 Keyboard Interface and 80 x 25 Character VDU. It's designed to run on the Xilinx / Digilent Spartan 3 starter board. A version for the BurchED B5-X300 board is also available HERE

30th December 2006

A discussion mailing has been set up for System09 users to exchange ideas. 

The web site for the mailing list is:

Many thanks go to Hans for setting it up for me.


Latest Release 11 July 2006

27th November 2006

Note about Synthesizing the design using Webpack 8.1 and 8.2 was originally synthesized with Xilinx Webpack There are a few gotchas with synthesizing under Webpack 8.1 and 8.2. 

The problem with Webpack 8.2 and 8.1 is that it's default state is to auto map block RAM and for some crazy reason it allocates block RAM without regard to what has been used in the the design and over maps block RAM. To over come this problem you need to change some of the "Synthesize - XST" properties.

With the project open right click on "Synthesize - XST" in the process window on the left under the "source for:" window and select "properties". The "process properties" window will be displayed.

In the "category" panel select "HDL Options". In the "HDL Options" panel make sure "RAM Extraction" is checked and for "RAM Style" select "Distributed" rather than "auto" from the drop down menu. Similarly make sure "ROM Extraction" is checked and "ROM Style" is set to "Distributed" rather than "auto".

Note also that there appear to be problems synthesizing miniUART using Webpack 8.1 and 8.2. In some cases the receiver works but not the transmitter, in other cases it appears to be the reverse. It may have something to do with skews in cpu_clk, but this needs further investigation. - Don Coates Motorola 6809 assembler - SWTP 6809 monitor program - 6809 Monitor with basic VDU driver

(Last Updated 10 Sept 1:00PM AEST) - 'C' Binary File Converter Program - RAMDisk version of Flex 9 - 19 Oct 2004

These instructions help you run Flex9 with a RAM Disk using System09 on the Spartan 3 starter board. Note that it assumes you have downloaded the configuration file to the Spartan 3 starter board and that System09 is running correctly. Note also that the current version of Flex9 is not patched correctly for KBug9 and only uses the RS232 output for commands. For some reason the VDU and keyboard does not work under this version of Flex9.

1). Unzip "" into a working folder on your PC.
2). Connect an RS232 cable from the COM port on your PC to the serial port of Spartan 3 starter board and start up Hyperterm.
3). Under  the "File -> Properties" menu select the "Connect To" tab and set Hyperterm to "Connect Using" the desired COM port and "Configure" the COM port for 57.6 Kbd, 8 data, 2 stop, no parity, no flow control.
4). Under  the "File -> Properties" menu select the "Settings" tab and set  Hyperterm to "Emulate" the VT52.
5). Reset System09 by pressing BTN3 on the Spartan3 Starter Board, and check that you get the KBug9 start up message and ">" prompt in the Hyperterm window..
6). Place KBug9 into Load mode by using the "L" command key.
7). Load the Flex9 operating system file "Flex.s19" into System09 using "Transfer-> Send Text File" on the Hyperterm tool bar.
8). When the load is finished, a few spurious "end of file" characters may be omitted and KBug9 prompts with ">".
9). Enter "G CD00" at the KBug9 prompt to enter Flex at the Cold start entry point and check that you get the prompt for the date.
10). Enter the date in MM,DD,YY format followed by the <Enter> key. Note that this version of Flex9 is not Y2K compliant.
11). At this point, Flex9 will attempt to load a "STARTUP.BAT" script from the disk, but will hang because the RAM disk has not been loaded yet. You will need to reset the board by pressing BTN3 to return to the KBug9 monitor program.
12). Enter the Flex9 warm start entry point using the "G CD03" command to confirm that Flex has loaded correctly. You should get the Flex command prompt "+++".
13). Return to the Kbug9 monitor by typing "MON<Enter>".
14). Place KBug9 into the Load mode again using the "L" command.
15). Load the RAM disk download program "ramdskdl.s19" using the Hyperterm "Transfer"-> "Send Text File" menu.
16). Run the "ramdskdl" program from location $1000 by entering "G 1000" at the KBug9 prompt.
17). The RAM Disk download program will indicate it is ready to download a disk image. Do not press any keys in the Hyperterm window at this time.
18). Go directly to the Hyperterm tool bar menu and use "Transfer" -> "Send Text File" to download the "Flex9sys.hex" file. This will take a few minutes to download. When done, the Flex "+++" prompt will appear. It is then possible execute Flex commands.
19). To examine the TTY settings under Flex9, enter "TTYSET<Enter>"
20). If you want to pause the screen after 24 lines, enter "TTYSET PS=Y,DP=24<Enter>".
21). Enter "DIR<Enter>" to get a listing of the files on the RAM disk. The <ESC> key will resumes the screen dump after 24 lines.
22). To run XBASIC enter "XBASIC<Enter>" at the Flex Prompt
23). To load a BASIC program under XBASIC, enter "LOAD "STREK.BAS" <Enter>"
24). To list the BASIC program enter "LIST<Enter>".
25). To execute the BASIC program enter "RUN<Enter>".
26). To exit XBASIC try "FLEX" or "QUIT" or "EXIT" (I can't remember the exact command). "SYSTEM" returns directly to the KBug9 monitor.
27). Assuming the Flex9 RAM image has not been corrupted you should always be able to re-enter Flex9 at the warm start entry point by entering "G CD03" from the KBug9 prompt.

Note that the RAM disk is only 192KBytes long. The download program and disk image must be modified if you want to use more RAM disk space. There is 1MByte of RAM available for RAM disk images although 64K bytes of this must be reserved for the CPU working RAM. Disk images may be generated using the SWTPc Emulator from Evenson Consulting Services : - With 80 x 25 VDU, RS232 Serial Port and PS/2 Keyboard Interface.

** Note ... if you are in the US you will be 10 hours or so behind Australia. If you down load the zip file withinn 10 hours or so of the posted time and date the auto make procedure in Web Pack ISE 7.1i may not make binaries correctly because it will think the source code will be more recent than the binaries it synthesises. It may be necesaary to edit and save each of the VHDL files in web pack to make sure the time / date stamp is correct.

11th July 2006

Fixed bugs in MUL, RTI, SYNC, DAA and Interrupt Processing of CPU09.

CPU09.vhd Version 1.14 - 11th July 2006

NB: I have not attempted to synthesise System09 for the Spartan3 Starter board using the updated version of CPU09.

1. Added new state to RTI called rti_entire_state. This state tests the CC register after it has been loaded from the stack. Previously the current CC was tested which was incorrect. The Entire Flag should be set before the interrupt stacks the CC.

2. On bogus Interrupts, int_cc_state went to rti_state, which was an enumerated state, but not implemented anywhere. rti_state has been changed to rti_cc_state so that bogus interrupt will perform an RTI after entering that state.

3. Sync should generate an interrupt if the interrupt masks are cleared. If the interrupt masks are set, then an interrupt will cause the the PC to advance to the next instruction. Note that I don't wait for an interrupt to be asserted for three clock cycles.

4. Added new ALU control state "alu_mul". "alu_mul" is used in the Multiply instruction replacing "alu_add16". This is similar to "alu_add16" except it sets the Carry bit to B7 of the result in ACCB, sets the Zero bit if the 16 bit result is zero, but does not affect The Half carry (H), Negative (N) or Overflow (V) flags. The logic was re-arranged so that it adds the MD register or zero so  that the Carry condition code is set on zero multiplicands.

5. DAA (Decimal Adjust Accumulator) should set the Negative (N) and Zero Flags. It will also affect the Overflow (V) flag although the operation is undefined in the M6809 Programming Reference Manual. It's anyone's guess what DAA does to V although I found Exclusive ORing Bit 7 of the original ACCA value with B7 of the Decimal Adjusted value and Exclusive ORing that with the pre Decimal Adjust Carry input resulting in something approximating what you find on an EF68A09P.  

7th July 2006

Fixed bugs in NMI.

CPU09 Version 1.13
Disable NMI on reset until S Stack pointer has been loaded. Added nmi_enable signal in sp_reg process and nmi_handler process.

12th June 2006

Bugs were found in the ASR, LSR and ROR instructions. They should not have changed the Overflow (V) Flag. The CLR instruction should have reset the Overflow (V) Flag. CPU09 has been updated to correct these mistakes.

17th September 2005

Two more bugs were brought to my attention. 

The first was that EXG and TFR instructions did not work on the condition code register. Extra cases had to be assigned to the ALU to set the Condition Code output register to the Left ALU input for the ALU TFR operation. 

The second problem was to do with JSR [0,S]. The indexed jump to subroutine pre-decremented the stack pointer ready to push the return address before the indexed addressing mode was calculated. This had the effect that JSR instructions indexed to the stack would get the wrong vector address. The solution was to defer the S Stack pointer decrement until after the indexed addressing mode microcode and add an extra cycle to the JSR microcode state. this required minimal effort. Note also that the JSR extended instruction gained an extra cycle as it shared the JSR microcode state. 

20th August 2005

A problem was discovered with the single operand LSR instruction. The 8 bit LSR instruction was treated like a 16 bit LSR instruction.
This was fine for the dual operand instructions as the high byte of the left input to the ALU is set to zero for ACCA and ACCB inputs. A problem arose on the single operand instructions where the Memory Data (MD) register used to hold the byte fetched from memory was sign extended in the high byte for single byte fetches. This meant that the LSR instruction would look like an ASR instruction for single operand instructions.

19th October 2004

New improved character generator ROM courtacy of  Flex User Group member Brian { Hamilton Kelly } gives 7 pixels x 11 rows x 128 characters. Caps lock on the keyboard now toggles on and off. (No  Caps Lock LED indicator though. That has to be done in software.) There are still a few bugs in the Keyboard map, with <Caps lock> M working as <Carriage Return>.

29th Sept 2004

Finally fixed the Keyboard release code problem on the keyboard.

10 Sept 2004

I finally got the VDU to behave sensibly. I updated the row counter logic so it was modulo 25 (the number of character rows) but it still had problems.  It occured to me that the row address counter needed to be one bit longer as I was adding the 5 bit Row register to the 5 bit Scroll offset register, so the wrap around was wrong. I also updated KBug so that it used a modulo 25 count on the scroll offset register.

 The LED displays and switch inputs are not used. They should really be tied in the idle state. It only just fits in the 200KGate Spartan 3. I've had to prune all but the basic functionality out of it to make it fit.

The Serial Port is a 6850 work alike serial port . Note that the Spartan3 Starter board only has RXD and TXD lines so the control lines RTS, CTS, CD etc are idle. The Baud rate is set to 57.6Kbaud. I am not sure if the video drivers will support uploading an S1 file via the serial port at that rate ... It might... I have not tried it.

Command / Status (Bit 0 = RXrdy, Bit1=TXEmpty)
TXdata / RXdata

PS2 keyboard is from open cores (I think) and has been translated from Verilog to VHDL. I have set it up to look like a receive only 6850 ACIA, with a few extra bits. It outputs ASCII coded characters. Key scan codes can be implemented by removing the comments and adding an extra register.

Command / Status (Bit 0 = RXrdy, Bit1=TXEmpty)
TXdata / RXdata

The VDU runs at 80 characters across x 25 rows down. It uses a pixel clock of 25MHz.
It is formatted at 640 pixels across x 400 pixels down. Total pixels across = 800, Total pixels down = 450

Write Character (at cursor)
Write Attribute (colour - RGB forground & background)
Cursor column position (0-79)
Cursor row position (0-24)
Row Display Offset (0-24)


BG Blue
BG Green
BG Red
FG Blue
FG Green

I'm not sure this is 100% accurate but you get the idea. In graphics mode, characters represent a 8 pixel graphics characters and are displayed as follows:

Bit 0
Bit 1
Bit 2
Bit 3
Bit 4
Bit 5
Bit 6
Bit 7

KBug9s includes basic video drivers. There is as problem when the offset Register exceeds 24. The Character columns get messed up. 2048 Byte buffer != 80 x 25 characters. Also It does not yet emulate the ADM-3A completely ... it is missing some of the control codes.

Some of the KBug9 commands are:

I [S/K] Enable Input device (Serial/Keyboard)
O [S/V/P] Enable Output device (Serial/VDU/Printer)
P [start]-[end]  Punch S1 Tape
L Load S1 Tape
E [start]-[end] Dump Memory
M [addr] Memory Examine & change
R Dump registers
G [addr] Execute Program
S display S stack pointer & Dump registers on stack
^A AccA examine & change
^B AccB examine and Change
^C Condition Codes
^U Ustack pointer
^X X Index register
^Y Y index register
^P Program counter

Back to FPGA Page