#c64 #8-bit #llvm-mos #6502 #mega65

nightly no-std mos-hardware

Hardware register tables and support functions for 8-bit retro computers like the Commodore 64, MEGA65 and others

14 unstable releases (3 breaking)

0.4.0 Mar 3, 2024
0.3.1 Jul 1, 2023
0.3.0 Jun 30, 2023
0.2.0 Mar 1, 2023
0.1.7 Jul 31, 2022

#254 in Embedded development

Download history 79/week @ 2024-03-08 8/week @ 2024-03-15 41/week @ 2024-03-29 5/week @ 2024-04-05

368 downloads per month


5.5K SLoC

Rust 3.5K SLoC // 0.1% comments C 1.5K SLoC // 0.2% comments GNU Style Assembly 290 SLoC

Open in Dev Containers Crates.io docs.rs


This crate contains hardware register tables and support functions for 8-bit retro computers like the Commodore 64, Commander X16, MEGA65 and others. Please check the examples directory to see how Rust can be used to generate simple demo effects.


  • Excellent support for Rust programming on CBM (inspired) 8-bit computers
  • Labelled registers for expressive hardware programming
  • Intuitive bitflags with type checks where possible
  • Minimum resource impact


Read and write to labelled hardware registers

use mos_hardware::{c64, vic2};
let old_border_color = c64::vic2().border_color.read();
unsafe {
    c64::sid().potentiometer_x.write(3); // compile error: read-only register

Use bitflags to safely control hardware

...for example where the VIC-II chip accesses screen memory and character sets:

use mos_hardware::{c64, vic2};
let bank = vic2::ScreenBank::AT_2C00.bits() | vic2::CharsetBank::AT_2000.bits();
unsafe {

Convenience functions to perform hardware-specific tasks

...for example to generate random numbers using noise from the C64's SID chip:

use mos_hardware::c64::*;
let value = sid().random_byte();

Getting started

The project requires rust-mos and is setup to build for C64 by default. A docker image of rust-mos is available if you do not fancy compiling LLVM. If you want to start a new project which uses mos-hardware, there's a Github Template.

Docker and Visual Studio Code

The easiest way is to use the provided .devcontainer.json configuration for Visual Studio Code. Before starting up VSC, you may want to edit .devcontainer.json to point to a recent, tagged image of mrkits/rust-mos. In particular, if you're on an ARM architecture, e.g. Apple Silicon, make sure to use an image compiled for linux/arm64 as emulating x86 in Docker is painfully slow.

  1. Install and start Docker
  2. Configure Visual Studio Code with the Remote - Containers extension:
    cd mos-hardware
    code --install-extension ms-vscode-remote.remote-containers
    code .
    When asked, re-open in Dev container.
  3. Inside a VSC terminal, build with:
    cargo build --release --target mos-c64-none  --example c64-plasma
  4. Find the binary in target/ and run in an emulator or transfer to real hardware.


  • If you encounter issues with cargo/home, force older version cargo update -p home@0.5.9 --precise 0.5.5


The hardware registers are currently incomplete and the library may be subject to significant changes.

  • Commodore 64:
    • sid
    • vic2
    • cia (partially)
    • c64 memory map (particlly)
    • PSID file support for SID music
    • Random number trait (RngCore)
  • Commander X16
    • vera
    • via (partially)
    • cx16 Memory map (partially)
    • Support functions
  • MEGA65:
    • partial support for vic3, vic4 and other hardware registers.
    • mega65-libc bindings
    • Random number traits (RngCore, SeedableRng)
    • Iterator to 28-bit address space
  • Examples:
    • Plasma effect (c64, mega65)
    • Raster IRQ (c64)
    • Sprites (c64)
    • Smooth x-scrooll (c64)
    • Joystick read (c64)
    • 10print maze (c64)
    • Memory iteration and fat pointers (mega65)


~12K SLoC