Skip to content

Extension Modules

Boisy Gene Pitre, PhD edited this page May 13, 2026 · 3 revisions

Author: Boisy Pitre

The technical information in the OS-9 manuals is packed with details that can unlock a much deeper understanding of how OS-9 works. The trouble is that some of those details can be hard to digest without a little background and a guided walk-through.

This article takes a close look at one of the more rarely explored parts of OS-9/6809 internals: system extensions, also known as P2 modules.

If you want to follow along closely, it helps to have your OS-9 technical manuals nearby, plus a printout of the appropriate os9defs file for the system you are studying.

Recommended References

For best results, have these on hand:

  • OS-9 Level Two Technical Reference Manual, or
  • OS-9 Level One Technical Information Manual together with the OS-9 Addendum Upgrade to Version 02.00.00 Manual
  • a printout of the os9defs file for the target operating system

Boisy specifically recommends keeping separate OS-9 definition files for Level One and Level Two, such as os9defs.l1 and os9defs.l2, so it is always clear which operating system a given source file targets.

What Is a System Extension?

If you run mdir on an OS-9 system, you have probably seen modules such as:

  • OS9 and OS9p2 on Level One
  • OS9p1 and OS9p2 on Level Two

These modules are effectively the OS-9 operating system itself. They contain the code that implements the system calls documented in the technical reference manuals.

Even IOMan is a form of system extension, since it implements the I/O call layer.

Drivers and file managers are the most common way to extend OS-9, but those are mostly confined to I/O-related behavior. System extensions are more fundamental: they can add new system calls or replace existing ones.

That power comes with risk. Replacing the behavior of an existing system call in a way that breaks compatibility is usually a bad idea. The safer and more useful pattern is to add a new call.

That is the path this article follows.

The System Call Mechanism

OS-9 provides operating-system services to applications through system calls.

On the 6809, those calls are built on the SWI2 instruction, which is a software interrupt. When the processor executes SWI2, control passes to the OS-9 kernel, which looks at the byte immediately following the instruction and interprets it as the system call code.

For example, assembly source like this:

    lda   #1
    leax  mess,pcr
    ldy   #5
    os9   I$Write
    rts

mess fcc "Hello"

is assembled into something equivalent to:

    lda   #1
    leax  mess,pcr
    ldy   #5
    swi2
    fcb   $8A
    rts

mess fcc "Hello"

The $8A is the encoded value for I$Write. The kernel sees that code and dispatches execution to the appropriate system routine.

Since the system call code is only one byte, a total of 256 possible call codes exist in theory. In practice, OS-9 Level One and Level Two divide those ranges up differently.

System Call Ranges

OS-9 Level Two

  • $00-$27 — user mode system call codes
  • $29-$34 — privileged system mode call codes
  • $80-$8F — I/O system call codes

OS-9 Level One

  • $00-$7F — user mode system call codes
  • $80-$8F — I/O system call codes
  • $90-$FF — privileged mode system call codes

The distinction between user mode and system mode matters because OS-9 maintains separate system call tables for each.

  • If a call is available to user mode, it is installed in both the user and system tables.
  • If a call is privileged only, it is installed only in the system table.

For example:

  • F$Load is callable from both user and system state, so it appears in both tables.
  • F$AProc is privileged, so a user-state caller gets an error.

The range $80-$8F is reserved for I/O calls. Those are handled by IOMan, so they are not available for custom extension work.

Installing a New System Call

Installing a new system call means:

  1. choosing a free system call code
  2. deciding whether it will be callable from user state, system state, or both
  3. building a small assembly table that describes the new service
  4. passing that table to the F$SSvc system call

So, interestingly enough, installing a system call is itself done by using a system call.

OS-9 Level Two Approach

The example discussed in the article is a module named OS9p3. It installs a new system call named F$SAYHI.

F$SAYHI behaves like this:

  • if register X points to a caller-supplied string, that string is printed
  • if X is zero, a default message is printed instead
  • output goes to the caller’s standard error path

The service table for the module contains three-byte entries:

  • one byte for the system call code
  • two bytes for the address of the handler routine

The table is terminated by $80.

At startup, the module points Y at that table and calls F$SSvc, which installs the new call into the kernel’s system call tables.

Why Level Two Is More Complicated

Under Level Two, the system and user processes do not share the same address space in the simple way they do under Level One. That means the default message cannot just be referenced directly from user context.

Instead:

  • the handler checks whether X points to a caller string
  • if not, it allocates space on the caller’s stack
  • it then uses F$Move to copy the default message from system space into the caller’s address space
  • finally it calls I$WritLn using the caller’s standard error path

Because this is a true system extension module under Level Two, it must be included in the bootfile. After reboot, OS9p2 finds OS9p3, enters at the module execution offset, and the new system call becomes available.

OS-9 Level One Approach

Level One handles system extensions differently.

Because system and process address spaces are much less isolated, the code can be simpler:

  • no F$Move is required just to access a default message
  • the extension does not need to be a Systm module
  • instead, it is typically built as a Prog module that installs the call when executed

That means the extension is installed at runtime by simply running the installer module from the command line.

Boisy points out Printerr as a useful example. It installs a replacement F$PErr system call when you run it.

The Main Tradeoff

Level One has one major advantage:

  • you can install a system extension without building a new bootfile and rebooting

But it also has one important hazard:

  • if the module that contains the installed system call code is unlinked from memory, the call table still points to code that no longer safely exists

At that point, a crash is only a matter of time.

Testing the New Call

The article also describes a small assembly test program named tsayhi.

It works on both Level One and Level Two:

  • if called with no parameters, it sets register X to zero and triggers the default greeting
  • if called with a command-line parameter, it passes the parameter string to F$SAYHI
  • up to 40 characters are printed to standard error

This makes it a simple and effective way to verify that the extension was installed correctly.

Key Takeaways

System extensions are one of the most powerful ways to modify OS-9 because they operate at the system-call level.

They let you:

  • add new system calls
  • replace or extend existing kernel behavior
  • fundamentally change how OS-9 behaves

But they also require deep knowledge of OS-9 internals, especially:

  • system call dispatch
  • privilege levels
  • memory layout
  • process versus system address space
  • module lifetime and linkage behavior

The exact implementation differs significantly between Level One and Level Two, mainly because Level Two has stricter address-space separation.

Practical Advice

If you want to experiment with extension modules:

  • start by adding a new call rather than replacing an existing one
  • keep separate definition files for Level One and Level Two
  • be especially careful on Level One not to unlink a module that contains installed extension code
  • remember that Level Two generally requires bootfile integration and rebooting

Notes on Source Listings

The original article includes full source listings for:

  • os9p3.a for OS-9 Level Two
  • sayhi.a for OS-9 Level One
  • tsayhi as a test program

Those listings are useful if you want to build the example exactly as described, but the key architectural ideas are the system-call table, F$SSvc, and the different installation models used by Level One and Level Two.

Clone this wiki locally