Close
0%
0%

6809/6309 Eurocard CPU System

A retrosystem based on the elegant 8/16 bit 6809 processor capable of running UniFLEX and OS9 level II multiuser/multitasking OS

Similar projects worth following
For those that would like to play with an nice 8-bit CPU from the late 1970's featuring a rich environment with memory management unit, DMA (memory-IO and memory-memory), Realtime Clock, IDE interface, CompactFlash and SD card interface. RAM disk, 4-port serial, video, ethernet.

Although some of the components used are no longer manufactured there seems to be plenty of 'old new stock' available through the various marketplaces online.

The system design philosophy was to create an eurocard based system with DIN41612 connectors which was very popular in the 1980s in Europe to create systems. Commercial systems at the time where Gespac, PEP Modular Computers, EuroCUBE Celeste and Eltec. The Elektor magazine also published an Eurocard system running FLEX (EC68). There were also many systems developed by hobbyists and I got inspired by the nice UniFLEX system developed by Kees Schoenmakers (https://github.com/kees1948/UniFLEX).

I focused on using only 5V logic but avoided the usual forest of TTL chips and a PAL/GAL solution for the glue logic. Instead I used two 5V CPLD devices which are fast, cheap and can hold a lot of logic allowing one to add some nice features to the system such as fast memory to memory DMA but also esoteric ones like a hardware CRC calculation of OS9 modules. In the File Section I have placed Python code that highlights how to create the CRC calculation in hardware.  I used it during testing of the Verilog code. With in-circuit (re)programming system development & testing is quick without having to remove devices from the PCB.

Source code for both UniFLEX and OS9 level II is available, something we could only dream about having in the 1980s since both hardware and software were rather expensive. Full details will be made available through my Codeberg GIT.

The system closely matches the CMS9639 from the 1980s which was similar to the GIMIX III board. Thanks to the SARDIS technology website (https://sardis-technologies.com/oth6809/cms.htm) there is a lot of information on these nice systems.

The addition of a dedicated ethernet interface offers opportunities not available in the 1980s.

The CPU board is the heart of the system and combines CPU with 1Mbyte memory, (EP)(EE)ROM, console port, ethernet, MMU. Thanks to a EPF10k20 CPLD which is positioned between the CPU and the rest of the system many functions can be integrated. For example, the MMU can hold 128 tasks simultaneous and each task will have the full 64k address space. Tasks are autoswitching and the dual channel DMA controller addresses memory through dedicated tasks. The detailed MMU maps are kept in a 2kbyte dual-port RAM memory which is also on the CPU board. Block (page) size chosen is 4kbyte. To have the full 64kbyte for each task requires automatic switching of tasks on interrupts and returning from interrupts. The dedicated Motorola MMU (MC6829) uses a fuse register to switch tasks. Using the 6809E we can easily work out when the first byte of an opcode is present on the database using the LIC pin and by looking for the opcode for RTI, we know when to switch when returning to a user task. Switching to a system task is easier since one can detect the occurrence of an interrupt by encoding the CPU BA & BS signals.

For a working system, however, the addition of the IDE board is advised as it allows connecting 2 SD cards, CF cards and upto 4 hard disks. All transactions can be done through either software IO or DMA. Since the 6809 is HALTed during the DMA operation (burst DMA) we can conduct transfers much faster than the 1 or 2MHz of the 6809 clocks (during DMA the E and Q clock continue as normal). The DMA controller uses a 16MHz clock (8Mbytes/s) such as to not exceed the speed of the CF cards that I have.  The above shown logic analyser traces show the onset of a DMA read of a IDE device. 

Extra serial ports are added through inclusion of a 4-port 6850 board that provides integrated serial to USB C converters with an option for mini USB.

No retro system is complete without a RAM disk and this system has one that is upto 4Mbytes large using a very small 4-byte memory interface  using high-speed DMA transfers or programmed IO.

A video board with VGA output and USB keyboard & mouse is...

Read more »

RTCdriver.asm

Software interface DS1302 through 3 PIA lines. The code is provided ONLY for info in case someone would like to experiment. It is not very efficient and not the way the interface was finally done! Note that the code uses a couple of UniBUG routines to deal with user interface. These routines are exposed with a couple of 'jump' words at the start of UniBUG.

plain - 6.67 kB - 04/16/2026 at 09:42

Download

my_ds1302.v

This Verilog module provides the serial interface between CPU and DS1302.

v - 7.78 kB - 04/16/2026 at 09:38

Download

CS09_CPU_ Schematic.pdf

PDF version of CS09_CPU schematics updated memory map 12/03/2026

Adobe Portable Document Format - 1.44 MB - 03/12/2026 at 11:28

Preview

CS09-CPU-III-v2.kicad_pro.zip

JLCPCB production files for CS09_CPU_III_v2

x-zip-compressed - 1.49 MB - 03/13/2026 at 15:16

Download

ibom.zip

Interactive Bill of Materials and board population overview (zipped) html file.

x-zip-compressed - 444.42 kB - 03/08/2026 at 15:15

Download

View all 13 files

  • Command line parameters OS-9

    roelof4a day ago 0 comments

    In OS-9 for the 6809, command line parameters are passed to a program through a specific convention using the process's data area and registers at startup.

    At Program Entry, the CPU Registers Contain:

    • X — points to the start of the parameter string in memory
    • Y — points to the top of the data area (the program's allocated memory)
    • U — points to the bottom of the data area (start of the stack/data)
    • D (A:B) — contains the size of the parameter string

    The Parameter String

    The parameter string is a raw text buffer containing everything typed after the command name on the shell line. For example, typing:

    myprogram foo bar -x
    

    ...results in X pointing to foo bar -x, with D holding its byte length.

    Key characteristics of the parameter string:

    • It is not null-terminated — you must use the length in D to know where it ends
    • It ends with a carriage return (0x0D), which counts as part of the string
    • It may be empty (D = 1, pointing to just the CR) if no arguments were given
    • The string lives in the system's I/O buffer area, not in your program's data area, so you should copy it if you need to keep it

    Memory Layout at Entry

    Low address
    ┌─────────────────────┐  ← U (data area base / stack bottom)
    │   Program Stack     │
    │         ↓           │
    │    (grows down)     │
    │                     │
    │   Static Data       │
    └─────────────────────┘  ← Y (top of data area)
    High address
    
    Separately, in system buffer:
    ┌─────────────────────┐  ← X
    │  "foo bar -x\r"     │  (D bytes long)
    └─────────────────────┘
    

    Parsing Responsibility

    OS-9 does no parsing for you. Unlike Unix which gives you argc/argv, OS-9 hands you the raw string and leaves tokenization entirely to the program (or to a library like the one in the C runtime). You walk the string byte by byte, using the length in D as your bounds, splitting on spaces or other delimiters as needed.

    Standard I/O

    At entry, the program's standard I/O paths are already open:

    • Path 0 — standard input
    • Path 1 — standard output
    • Path 2 — standard error

    These are inherited from the shell and ready to use via OS-9 I$Read / I$Write system calls.

    This convention is quite minimal and low-level compared to later systems, which is typical of OS-9's design philosophy of keeping the kernel small and fast on 8/16-bit hardware.

  • Realtime Clock

    roelof4a day ago 0 comments

    OS-9 uses a 100Hz oscillator driven signal to keep track of time. As mentioned this signal is connected through the PIA (MC68B21/HD63B21) and generates interrupts every 10ms. Upon calling the 'setime' command the PIA is initialised and valid time information becomes available to the system. Often the setime call is included in the 'startup' file which is automatically run at boot time.

    Because there is a battery backed Realtime Clock (DS1302) available there is no need to manually enter date and time information (once the Realtime Clock is setup) every time the system boots.

    In order to include the reading of the Realtime Clock at boot time changes are made to the Clock module and the setime command. Before discussing these changes it would be good to discuss the Realtime Clock itself and how it is interfaced to the CPU.

    Unfortunately the use of the same Realtime clock chip (MSM5832) as used on the CMS9639 was not an option since this obsolete chip is difficult to source. Since there was little board space available it was decided to go for a chip with a small footprint and a serial interface. The DS1302 provides date, time and a small number of non-volatile RAM locations. Its interface is bespoke and shown below.

    There are only three pins for exchanging data. A ChipEnable selects the device and data (IO) is shifted in/out using a SerialCLocK. Only the IO pin is bidirectional. 

    Originally I hooked the DS1302 to a couple of unused PIA lines and implemented a software interface to read/write date & time information. That resulted in quite a bit of code (provided) and since there was some space left over in the CPLD chip, it was decided to create a bespoke interface using a Verilog module. 

    For fun I tried to use one of the AI agents to write a module for me. This turned into a disappointing result that didn't work because the agent misinterpreted the asymmetry between reading & writing and was unable to generate the right code even when this issue was pointed out.  After testing about ten versions I gave up :(

    Thinking someone would have tackled this already I searched online and found a github repository (link in the code) that implemented burst reading/writing (many registers in one go without transmitting the address info for every register). I modified this code to include single register read/write which I needed to change the trickle charge settings. This code is provided in the file section. I will discuss the detailed instantiation of this module within the top level Verilog code in the near future. Since the actual code is rather large I will try to do this in sections.

    From a software perspective this interface takes 8 memory locations ($FFB0..$FFB7) that provide date&time and command/status register ($FFB7). In the command register the user selects the type of operation (burst read/write or single register read/write). The status register shows when the serial interface is busy/ready with any operation.

    With this interface tested it was decided to modify the 'year 2000 compliant version' (source available online: y2k upgrade) of the setime command (setime edition version 12) slightly to add an option to read the Realtime clock date & time information and copy this to the OS-9 time rather than typing it in. Setting of the Realtime Clock is done automatically if the 'setime' command is provided with user date&time information in the usual way. Thus by adding 'setime -' in the startup file the copying of the date&time info is automatic.

    In the modified Clock module care is taken that the Realtime Clock is present and not in a 'halted' state before initialising.

    At this point no use is made of the DS1302 RAM memory but the provided Verilog module and interface is fully prepared for it simply by reading/writing to different addresses within the DS1302 use can be made of these battery backed memory locations for storing data.

  • OS-9 DMA disk driver details 2

    roelof404/08/2026 at 09:52 0 comments

    As mentioned in the earlier log on the DMA disk driver, I have now written a RBF driver that sleeps during the phase after issuing a read/write command to the IDE disk controller and uses interrupts to wake up for the DMA transfer phase releasing the intervening time for other processes. There is no clash with other processes that want to use the DMA controller because it is only setup for data transfer during the actual data transfer phase, not when the IDE command is issued.

    During the debugging I noticed an error stemming from the original driver (which is also updated) in that I tried to check the type of disk before it was defined... The verilog code for the IDE interface board was updated to provide the required interrupt signal and its associated status bit.

    Both versions of this RBF driver are uploaded in source form.

    Whilst going through the motions of updating the driver I noticed that the Programmer's Manual hints that since OS-9 level 2 version 1.2 (which is covered by the rev. H of the manual) a new SUSPEND state would improve the RBF even further since it does away with the wake up signalling ( section 5.3.2 page 5-11). For an electronic copy of the manual look at my CodeBerg repository under OS-9 documents.

    So I have revised my IDE RBF driver using this new feature. So now there are three versions of the IDE RBF driver available. Obviously the latest: myIDEdrv_IRQ_Suspend.asm is the one to go for since it has all the features available that were discussed. The other two work and have been provided for those that would like to see the changes between them.

  • OS9 Clock Module

    roelof404/02/2026 at 12:00 0 comments

    The OS9 Clock module is an interesting one. In the OS9 hierachy diagram it sits together with Init at the same level as the OS9 kernel (OS9p1 & OS9p2).

    The Clock module takes care of initialising the clock which is a 100Hz oscillator driven signal which, in our case, is connected to the onboard MC6821 (PIA). The PIA also provides a TimerEnable signal which is used to stop the 100Hz clock if it is logical '1'.

    Also the Clock module provides seconds,minutes, hours, etc. registration based on the 'ticks' coming in from the 100Hz clock. This is done through generating interrupts by the PIA.

    There is no direct start of the clock by the operating system. In fact the F$Time system call is only available when the Clock module is called using the Setime command which also starts the Clock.

    Below a snippet showing how the PIA is setup and the clock is started by setting the TimerEnable signal low '0'. By default the TimerEnable is '1' due to a pullup resistor.

    *****
    *
    *  CLOCK INITIALIZATION ENTRY
    *
    ClkEnt pshs cc
     lda #TickSec get ticks per second
     sta D.Tick
     lda #TickSec/10 set ticks/time slice
     sta D.TSlice
     sta D.Slice
     leax CLKSRV,pcr GET SERVICE ROUTINE
     stx D.IRQ SET INTERRUPT VECTOR
     
    * PIA initialisation goes here
     ldx CLKPRT,pcr get PIA address
     orcc #IntMasks set interrupt masks
     clra
     sta 1,x clr control register
     lda #%00000001 PIA port A bit0 output, rest input
     sta ,x set data direction register
     lda #5 select pheripheral register & CRA1 interrupt enable, high to low
     sta 1,x set control register
     clra
     sta ,x clear bit 0 which enables 100Hz clock
     lda ,x clear any current interrupts
     
     puls cc restore interrupt masks
     leay TIMSVC,PCR
     OS9 F$SSvc SET TIME SERVICE ROUTINE
     
    ClkEnt3 rts

    Full Clock source code is attached.

    Note: it is assumed that PIA A-side pins other than 'pin 0' are inputs. That is true (see schematic) for 'pin 4' or PA4 which is connected to the clock but not necessarily for the other pins. Currently these pins have no meaningfull purpose but one could consider using these and then the above PIA A-side initialisation needs to change.

  • CMS9639 specific changes OS9p1

    roelof404/02/2026 at 11:29 0 comments

    This first part of the OS-9 level 2 kernel (OS9p1) provides essential system calls that make up the operating system allowing proper task administration, memory management, etc.

    Comparing the OS9p1 used for the CMS9639 with standard OS9p1 code it is clear that there are three low-level functions that have changed. All three are involved with moving data between tasks and in the case of the CMS9639 the memory-to-memory DMA facility is used even if there is only one byte to be moved.

    Here, we don't consider changes in setting up/checking memory and the Data Address Translator (DAT, key part of the MMU) initialisation since these would be different for any system.

    The changes are found in the code for Mover(00)/MoveRegs, PutRegs and STABX/LDABX (using source code labels). Below the difference between standard and CMS9639 is shown for PutRegs, which copies registers between tasks.

    Below we compare PutRegs:

    CMS9639:

    ************************************************************
    *
    * Subroutine PutRegs
    *
    * Copy User interrupt register stack
    *
    * Input: X = Process Descriptor ptr
    * U = local stack ptr
    *
    * Output: none
    *
    * Data: none
    *
    * Calls: uses DMA to copy register stack
    *
    PutRegs ldb P$Task,X get process task
     andb #^SysTask
     clra
     pshs u,x,cc
     ldx P$SP,X get process stack ptr
     exg x,u switch source & destination
    PutReg.A equ *
     orcc #IntMasks
     sta >Tsk.Src Task to copy from
     stx >$FFC0 DMAC source address register
     stu >$FFC4 DMAC destination address register
     ldx #R$Size
     stx >$FFC2 DMAC Source byte count register
     stx >$FFC6 DMAC Destination byte count register
     stb >Tsk.Dst Task to copy to
     ldb #$03
     stb >ContrlSW send command
     nop
     puls pc,u,x,cc

    Standard: 

    ************************************************************
    *
    *     Subroutine PutRegs
    *
    *   Copy User interrupt register stack
    *
    * Input: X = Process Descriptor ptr
    *        U = local stack ptr
    *
    * Output: none
    *
    * Data: none
    *
    * Calls: MoveRegs
    *
    PutRegs ldb P$Task,x get process task
     lda D.SysTsk get system stack
     pshs u,y,x,DP,D,CC save registers
     ldx P$SP,x get process stack ptr
     exg x,u switch source & destination
    PutReg.A equ *
     ldy #R$Size/2 get double byte count
     tfr B,DP copy process task
     orcc #IntMasks set interrupt masks
     lbra MoveRegs 
    Mover10 lda 1,s get source task number
     orcc #IntMasks set interrupt masks
    MoveRegs sta DAT.Task set source task
     ldd ,x++ get data double byte
     exg b,dp switch data & task
     stb DAT.Task
     exg b,dp switch back
     std ,u++
    Mover30 lda #SysTask get system task
     sta DAT.Task set system task
     lda 0,s get previous masks
     tfr a,cc reset interrupt masks
     leay -1,y count double byte
     bne Mover10 branch if more
     puls pc,u,y,x,dp,d,cc

    The DMA version essentially uploads source and destination information and moves bytes during DMA just after 3 is written to the ControlSwitch (ARM DMA). Task switching is automatic between source and destination.

    For the standard case there is changing of task needed for every (double)byte. R$Size is the number of bytes to move.

    Apart from the data moving routines there is one further CMS9639 specific change that is at the heart of system calls. System calls use a SWI2 software interrupt followed by a PostByte which indicates what system call is to be performed. Normally software collects the PostByte from user space and increments the program counter to skip the PostByte upon return. The CMS9639 has a dedicated circuit that captures the PostByte and places it in memory location $FFFA0. It also increments the program counter before placing it on the stack.

    In the snippet from OS9p1 this process can be found in detail for both cases using conditional assembly:

    ************************************************************
    *
    * System Service Request Routine
    *
    * Process system service requests
    *
    * Input: S = value of stack after interrupt
    *
    * Output: none
    *
    * Data: D.SysDis, D.SysPrc
    *
    * Calls: Dispatch, SysRet
    *
    SysSvc leau 0,s get registers ptr
     ifeq CPUType-CMS9639
     ldb Postbyte...
    Read more »

  • RAM disk

    roelof403/29/2026 at 15:37 0 comments

    With available (and affordable) memory quickly passing the 64kbyte mark many people employed extra RAM in their system during the 1980s in order to create quick access disk storage. Within OS-9 it is very simple to define extra drives with bespoke drivers to integrate these into the operating system.

    Often the access would be memory mapped access through a window of varying size with 1-4kbytes as a common option. Using bank switching this window would cover the full extent of the available RAM disk size.

    I have designed the RAM disk for the CS09 system in a different way because I would like to keep the number of memory locations for I/O to a minimum. This method is much like normal disk access via a dedicated controller. There are only four bytes mapped into the CPU's address space through which all data transfer happens. Besides a data register there are 2 registers (16-bits) that set the Logical Sector Number of the sector to be accessed and a further command/status register. That's it.

    Internally, the RAM disk logic has an 8-bit counter which auto increments whenever a read or write to the data register is performed. Together with the 16-bit LSN there is room for 2^24 bytes (16Mbyte) on the RAM disk. There is an option for using a 9-bit internal counter for use with UniFLEX which uses sectors of 512-bytes.

    Access to the disk would require uploading of the LSN number of the sector followed by 256 reads/writes from/to the data register. The internal 8-bit counter get cleared automatically after any change of the LSN registers. Through the command register the disk can be write-protected.

    Using one of the two DMA engines on the CPU board all data transfers are really fast.

    RAM disk memory is low-power CMOS and the memory chips have backup batteries so that the RAM disk contents is non-volatile.

  • Floppy disk controllers

    roelof403/27/2026 at 12:35 0 comments

    During the 1980's the Western Digital floppy controllers were abundant. Starting with the 179x series and 279x ones after that. There were also more compact solutions like the 177x series which were popular due to the low supporting chip count. Like many I used all of these and learned to live with them. Especially the requirement to not poll their status too quickly was a nuisance. 

    With that in mind I made two different designs of the IDE interface. One with a WD2793 and one with a newer WD37C65 device. The latter one is a NEC uP765 like interface plus some extra support so that it is a one chip solution. Both should allow reading of both 8" and 5.25" disks but the WD37C65 goes further (3" extra density) so an interesting option to explore. A 3D KiCAD representation of the WD37C65 version is uploaded to the picture gallery.

    I have an old Siemens 8" drive which is well preserved and some original TSC FLEX OS 8" floppies (!) and it will be fun to see if I can read these eventually.

    OS-9 drivers for the WD279x are around and should be easy to adapt. However, for a multi-tasking system these can be a drag since byte don't come out as a stream of bytes that can be transferred as a burst DMA. Instead people have used 'cycle stealing' DMA something which requires some overhead in managing.

    So during design time I thought of a way to buffer the bytes from/to floppy drives sector by sector. Hence by keeping a 256-byte buffer between the CPU and the floppy drive, the sequence of writing/reading to/from floppy drives becomes much like interfacing to IDE disks and we can employ burst DMA transfer of data.

    There is still the issue of how to deal with disk formatting which requires more than 256-bytes but it should be simple to create a bypass to the sector buffer and handle these the 'old way'.

  • OS-9 DMA disk driver details

    roelof403/26/2026 at 10:37 0 comments

    As mentioned I use an IDE (PATA) type interface to connect to storage devices like hard disks or Compact Flash cards. There are several adapters for CompactFlash cards that plug into IDE connectors to make that easy.

    Currently the Boot loader module that resides in EPROM reads the disk using Programmed Input/Ouput or in other words data is transferred not using DMA but simply by programmatically reading byte for byte. This allows the code to be very compact and since that is the only task running has little downside.

    The IDEdrv RBF driver is using DMA to quickly load sectors of data to memory. Since we are using burst DMA (during which the processor is HALTed) no other task is running. However, there is a significant delay between issuing a read sector by DMA command and the onset of the DMA transfer. The delay depends on the drive used. For the CompactFlash card that I use (Scandisk Ultra II) this delay is 0.28ms much longer than the actual DMA transfer of 256bytes (which is several tens of microseconds). Currently the driver simply polls the DataReady bit during these 0.28ms then the CPU is HALTed once data is ready. So no interrupts are involved at this stage.

    It would be better to issue the read sector command go to sleep so other tasks can run and use an interrupt when done. But it is a bit more complicated than that. Because the DMA controller needs to be setup before the transfer we can't do this at the time of issuing the read sector command. That is because the same DMA controller is used for other tasks (such as moving data between tasks by OS-9 system calls). So one would have to issue the sector read command without setting up the DMA registers, go to sleep and wake up when data is ready as signalled by the IDE disk. Then load the DMA registers and acknowledge the DMA transfer. That way there is no clash between DMA users and other tasks can use the 0.28ms of waiting for data from the disk for useful operations.

    Although IDE devices have a dedicated Interrupt request line, this line is toggled only at the end of the DMA transfer which is not what we want because the driver will release the CPU directly after the DMA transfer. In our case we would like an interrupt signal directly before the IDE disk is ready to do the DMA transfer so we can quickly upload the DMA registers and allow the transfer to happen. Plan is to use the DMA request signal to trigger the interrupt request and toggle the DMA acknowledge line to the IDE disk once the DMA registers are loaded and the DMA is armed. Just like the CPU board, the IDE interface is built around a complex logic circuit and details of signalling can be adjusted easily through changes in the verilog code.

    Details of putting read/write disk to sleep and how to wake them up are described in the OS-9 programmers manual (pages 6-15 and 6-16) and the interrupt service routine on page 6-19. I have revision H (January 1984) of the manual.

    I had a look around to see how legacy drivers handle this and unfortuately I haven't found many such disk drivers around. There is the GIMIX G68 driver but that is centred on doing 'cycle stealing' DMA as far as I can see. It does show how the Sleep and Busy and Wakeup signalling is done. It also introduces a system variable that indicates if the DMA device is 'in use' or 'free'.

    For those interested in the code I have attached the source code for the Boot module and the current IDEdrv RBF device driver (still working out how to setup the CodeBerg repository ...).

  • Development System

    roelof403/15/2026 at 19:19 0 comments

    During the development stage there is a requirement to convert 6809/6309 assembly into binary OS9 modules. Thankfully OS9 is well structured and the number of modules needing changes is relatively small. Apart from the bootloader and kernel modules there are also driver modules for serial ports and disks that need changing or writing from scratch. To do so I use the Virtual Color Computer (VCC) emulator on a Windows system (https://github.com/VCCE/VCC).  It is provided in both source form and binaries. It can also be run on Linux platforms.

    The emulator allows you to hook up 4 virtual floppy disks and 2 virtual hard disks. I've installed the NitrOS9 operating system which has lots of nice code with it including a modified assembler that will generate 6309 code. Just what I needed to create a set of adapted OS9 modules from existing source code.

    VCC works with disk files (.dsk) for floppy or (.vhd) for hard disks. Files can be extracted or inserted into these virtual disks by using Toolshed (https://github.com/nitros9project/toolshed). You can also create blank virtual disk files using this tool. Alternatively there is a  Windows tool called Floppymaintenance (http://flexusergroup.com/swtpc/Downloads.htm). The latter option uses a nice looking GUI but I have had issues using it.

    If you are looking for a crosscompiler that can create OS9 modules from source then LWTOOLS is recommended (https://www.lwtools.ca/).

    Details of setting up  NitrOS9 can be found online (https://lcurtisboyle.com/nitros9/nitros9_docs.html). A quick online search will feature some guided youTube videos as well.

    In fact NitrOS9 is a further development of OS9 developed and maintained by the Color Computer community and has many upgrades. It would be a logical next step to adapt it.

  • Booting OS9 level 2

    roelof403/15/2026 at 18:53 0 comments

    Source code for the first part of the OS9 kernel (OS9p1) adapted for the CMS9639 is published on GitHUB (https://github.com/sorenroug/osnine-java/tree/master/os9software/cms9639). The binary file is available at https://www.sardis-technologies.com/oth6809/cms9639.htm.

    I took the binary file as is and removed the Boot loader part at the beginning of this file and added my own Boot module. (The CMS9639 Boot module is not well documented but seems to use a SCSI controller as a disk interface to a Winchester hard disk which I don't have). In order to manipulate binary files I use ImHex (https://imhex.werwolv.net/) which includes a 6809/6309 disassembler (amongst many).

    The CMS9639 part 1 code is different than the 'stock' OS9p1 code. This not only has to do with the details of the MMU but also because the CMS9639 has a nice way of capturing the postbyte which follows the SWI2 system calls. The postbyte indicates which system call is requested. Other systems have to capture this byte from user space and adjust the program counter so that upon return the location with the postbyte is skipped. The CMS9639 does this in hardware and makes the postbyte available in a dedicated memory location accessible only in the system state (see memory map on page 1 of the schematics).

    Secondly there are a few memory copy routines between tasks and since this has to work between tasks there is a significant overhead of switching. The CMS9639 removes the instructions for copying and uses the memory-to-memory functionality of the DMA controller with different tasks for source and destination.

    It seems I have implemented these hardware ideas correctly because I can see (with the use of a Agilent 16802A logic analyser) the system calling the Boot module which loads the so-called OS9boot file from disk (well CompactFlash in my case). Afterwards I can see the processor starts to execute the OS9p2 code which is the second part of the OS9 kernel. There is no dedicated CMS9639 version of OS9p2 so I have used a standard one at this stage (https://github.com/sorenroug/osnine-java/tree/master/os9software/dragon128).

    I do get an error upon changing directories to the default /H0 disk as indicated on the Init module which is loaded during Boot time. I suspect there is an issue with my bespoke disk driver module which has not been tested too well.

    OS9 is hard coded to use 256 byte sectors which is half of what IDE/PATA/CompactFlash filesystems have. I tried to be clever to put two 256-byte sectors into one 512 byte sector using a cache. For now I will just use one half of a 512 byte sector which makes things fast and simple.

    After updating the disk drive to use every other byte of a 512-byte sector and ironing out several bugs OS-9 booted on the system console as shown below. The hardest error to find was an indexed store of the B register which turned out to be unindexed (I forgot the 0,U) which corrupted the least significant byte of the D.POLL variable. As a consequence the system would go haywire after receiving interrupts ...

    Great to see this!

    In he Init file I have set 0x0FBFFF as the Top of RAM.

    There are no floppy disks specified yet, I still have to write the driver.

    The modules needed for booting are listed above and have standard names. Exception is IDEdrv which is the RBF type driver for the IDE board that was hooked up to a 512Mbyte ComplactFlash card.

    All these modules (minus the MDir one) are part of the OS9boot file that is loaded by the low level boot loader that together with OS9p1 resides in EPROM.

    For creating the boot disk I made a full system disk using VCC and used a small python programme to bulk up the 256byte OS9 sectors that make up the virtual hard disk file (.vhd) to 512-bytes simply by inserting a 00 byte every other byte in the disk effectively doubling the disk size. This programme code is attached for info.

    Virtual hard disk files are just binary files that contain sector data starting with Logical...

    Read more »

View all 10 project logs

  • 1
    PCB

    The provided zipped PCB file contains all Gerber files for production of the 4-layer PCB by JLCPCB. It was created within KiCAD with the JLCPCB toolkit extension.

    To get an idea of the costs you simply upload this zip file to the JLCPCB web site and it works out all the details needed from it. JLCPBC make it simple to order a solderpaste stencil from the same files, so all in one stop shopping.

    The uploaded version 2 has small changes from version 1 which I am using for testing. So I should add a note of caution:  I haven't tested PCB version 2 yet. Although the changes are small the probability of errors is not zero.

View all instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates