pico]OS for 6502

This port is for all 6502 compatible processors that are supported by the CC65 compiler from Ullrich von Bassewitz. The timer interrupt handling and nano-layer console-I/O is especially for the Commodore 64, so if you want to use this port on an other machine than the C64, you need to modify the assembly file port_a.s.

This port supports console I/O for the nano layer.


This port is compileable with the CC65 compiler from Ullrich von Bassewitz, version 2.10.5. Note that the release version 2.10.0 is broken so you need the new one from the snapshot tree. Newer compiler versions should work also as long as the compiler does not use more than the zeropage registers $02 - $1b and the data stack pointer (sp) is stored at $02 / $03.

For testing and debugging purpose I recommend the VICE emulator. This program can emulate a lot of Commodore machines, most of them are based on a 6502 compatible CPU. Symbolic debugging is not yet supported by VICE, but the built-in monitor is very useful in conjunction with the label file generated by CC65. Please see the CC65 manual for details on how to debug CC65 programs with VICE.

Port Details

The CC65 cross compiler is a bit tricky: It uses some space in the zero page to store runtime variables, also the CPU stack is expanded by an additional data stack.

To switch the task context, this port must swap the zero page environment, change the data stack pointer and swap the processor call stack, so a context switch is very expensive.

To speed up the context switches, the processors call stack is divided into four task call stacks with 64 bytes each. If only four tasks are used (POSCFG_MAX_TASKS = 4), the stack must not be copied. If more than four tasks are used, the first three tasks are fast, and the other tasks are slow, since the stack must be copied.

With a call stack of 64 bytes the user can do function calls with a depth of 17. 14 bytes of the stack are needed by the OS, 16 bytes are needed by the interrupt service routine, 34 bytes remain for the user.

The data stack is limited to 1024 bytes (4 tasks), 768 bytes (5 to 8 tasks) or 512 bytes (more than 8 tasks). The idle task uses the default stack the CC65 main program would use. Keep in mind not to waste memory in a multitasking environment!

The OS timer interrupt handler is called 30 times per second on a C64. This is done by dividing the standard 60Hz timer interrupt by two, so only each second timer interrupt is taken to initiate a context switch.


This is an example of pico]OS running on a good old Commodore 64. The meaning of the cryptical output is described in the file testinfo.txt.

This is a multitasking demo for the Commodore 64. Each snake that moves over the screen is a single task.