





Utilizing CC65 as a C compiler is fantastic, but working with the BBC Micro and Master has been quite challenging. Despite the promising work by a few community members, I haven’t made significant progress yet.
I was excited to discover that the impressive VBCC compiler, which I previously used for Amiga and Atari ST development, offers excellent support for BBC, along with many other 6502-based platforms.
To get started on Windows, ensure you set your environment variables correctly. Check the end of the page for instructions on creating your BBC disk and executing your programs.
set VBCC=C:\Users\chrisg\vbcc6502\vbcc6502_win\vbcc
set PATH=%VBCC%\bin;%PATH%
Unfortunately, the pre-compiled binaries and compile instructions are only available for Windows and Linux, as the VBCC creator lacks access to a Mac.
Following the Linux/BSD instructions on my Mac proved to be cumbersome, so I first attempted Parallels, which worked but isn’t recommended for everyone. Then, I had a breakthrough.
We’ll use a lightweight Docker container via OrbStack to virtualize Linux, allowing us to run the existing binaries!
Installing and Running OrbStack via Homebrew
OrbStack is free for personal use and provides a lightweight Linux virtual machine, unlike Docker Desktop. While it’s preferable to run ARM images natively, my x86_64 images on Apple silicon will utilize emulation, which is fine for CLI toolchains with minimal performance impact.
If we later acquire an ARM64 Linux VBCC bundle or build VBCC/vasm/vlink from source for ARM64, we can switch to --platform linux/arm64 for native performance.
brew install --cask orbstack
What This Means
Homebrew casks install GUI applications to /Applications and configure their services. By installing only the CLI formula, you get binaries without the app that starts the Linux VM. Using --cask ensures we get the complete package.
Completing and Testing OrbStack
First, verify that the application/GUI installation completes:
open -a OrbStack
Now, let’s check that the CLI is functional:
docker version
To test Docker, try running the Hello World container:
docker run --rm hello-world
(You may need to enter your Mac password)
If this prints the greeting message, Docker is set up correctly.
Installing VBCC
We need to create a directory for our project:
mkdir -p ~/vbcc-6502 && cd ~/vbcc-6502
Download the 6502 zip file and move it to our new directory:
cp ~/Downloads/vbcc6502_r4p2.zip .
In the same directory, create a Dockerfile to set up our Linux container:
nano Dockerfile
Here’s the Dockerfile content:
FROM --platform=linux/amd64 debian:stable-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates unzip make gcc libc6-dev \
&& rm -rf /var/lib/apt/lists/*
# Place vbcc6502_r4p2.zip next to this Dockerfile before building
COPY vbcc6502_r4p2.zip /tmp/vbcc6502_r4p2.zip
RUN mkdir -p /opt && \
unzip -q /tmp/vbcc6502_r4p2.zip -d /opt && \
# Attempt to auto-detect layout, else use known structure
if [ -d /opt/vbcc6502/vbcc6502_linux/vbcc ]; then \
ln -s /opt/vbcc6502/vbcc6502_linux/vbcc /opt/vbcc; \
else \
VBCCDIR="$(find /opt -type d -name vbcc -print | head -n1)"; \
ln -s "$VBCCDIR" /opt/vbcc; \
fi && \
ln -s /opt/vbcc/bin/* /usr/local/bin/ && \
rm -f /tmp/vbcc6502_r4p2.zip
ENV VBCC=/opt/vbcc
ENV PATH="/opt/vbcc/bin:${PATH}"
WORKDIR /src
CMD ["/bin/bash"]
Next, we start the Docker build process:
docker buildx build --platform linux/amd64 -t vbcc-6502:amd64 .
Testing VBCC
Now, we’ll create a basic hello.c source file:
#include
int main(void) {
puts("Hello, 6502");
return 0;
}
Run the VBCC compiler through our virtual machine with the following command, targeting C64 and outputting a .prg file for use in Vice or any C64 emulator:
docker run --rm --platform linux/amd64 -v "$PWD:/src" vbcc-6502:amd64 bash -lc \ 'vc +c64 -O2 hello.c -o hello.prg'
For BBC, adjust the target and output filename as follows:
docker run --rm --platform linux/amd64 -v "$PWD:/src" vbcc-6502:amd64 bash -lc \ 'vc +bbc -O2 hello.c -o hello'
Running BBC Programs
Unfortunately, I am not aware of a BBC emulator that supports command line execution like Vice does. Luckily, BeebEm can create BBC disk images:
After creating the disk, import your new program:
Use *CAT to list the files on your disk.
Once your disk is populated with your program, you can execute it and enjoy the results!
Execute your program using *RUN FILENAME.
You will need to update the disk with new versions each time you recompile, but you can continue to use the same disk.
Additionally, my browser-based BBC emulator using JSBeeb allows you to upload your disk and execute it there. I plan to develop a utility to simplify the disk creation process or to run compiled code without needing BeebEm every time.
Optional .dockerignore
To speed up builds, we can create an ignore file:
.git
build
dist
node_modules
*.d64
*.prg
*.img
*.zip
Makefile for Compiling Convenience
Given that the compiler command becomes quite lengthy with Docker integration, let’s simplify things.
Here’s a flexible Makefile that accepts parameters for target, input, and output, designed to work seamlessly with our Docker image while providing sensible defaults.
# vbcc 6502 via Docker
IMAGE ?= vbcc-6502:amd64
PLATFORM ?= linux/amd64
# Overridable parameters
TARGET ?= c64 # e.g. c64, bbc, vic20, apple2r, nes, atari, x16
SRC ?= hello.c # one or more sources, space-separated
OUT ?= hello.prg # output filename
OPTS ?= -O2 # additional compiler options, e.g. -g -O3
VC ?= vc # vbcc driver in the bundle
.PHONY: build list-targets shell clean version
build:
@docker run --rm --platform $(PLATFORM) -v "$$(pwd):/src" $(IMAGE) bash -lc '$(VC) +$(TARGET) $(OPTS) $(SRC) -o $(OUT)'
list-targets:
@docker run --rm --platform $(PLATFORM) $(IMAGE) ls /opt/vbcc/config
shell:
@docker run --rm -it --platform $(PLATFORM) -v "$$(pwd):/src" $(IMAGE) bash
version:
@docker run --rm --platform $(PLATFORM) $(IMAGE) bash -lc '$(VC) -h || true; vbcc6502 -h || true'
clean:
@rm -f $(OUT)
This allows us to set the input, output, target, and any other options without necessitating edits to the Makefile each time.
The line .PHONY: build list-targets shell clean version marks our five targets as phony, ensuring their recipes run each time they’re called, without considering existing files in the filesystem.
How to Use the Makefile
# defaults: c64, hello.c → hello.prg
make build
change target
make build TARGET=bbc OUT=hello-bbc
multiple sources
make build TARGET=c64 SRC="main.c util.c" OUT=demo.prg
pass extra options
make build TARGET=apple2r OPTS="-O3 -g" OUT=game
More Complete Hello World .C
You’ll notice that earlier BBC examples might cause the machine to freeze post-execution.
Good news—on the BBC target, you can use +bbcr to return the user to BASIC after the program finishes.
In the example below, “Hello World!” won’t be visible after execution because we clear the screen using a BBC “VDU” command (the ASCII character 12), but you *will* see “Woot!” instead.
#include
#include
int main(void) {
printf("Hello World!");
__vdu_sequence(1);
putchar(12);
__vdu_sequence(0);
printf("woot!\n\r");
return 0;
}
There are numerous other VDU commands useful for future projects.
What’s Next?
With a functioning compiler for BBC projects, I’m ready to start porting my C Dungeon game.
First, I need to create a conio.h, the library I depend on for text output. I’ll also explore tools that simplify running compiled code directly or creating/updating BBC disks more efficiently. Stay tuned!
Original article by retrogamecoders.com


