A hybrid BASIC + 6502 assembly Mandelbrot set renderer for the Oric Atmos (1983), demonstrating the classic 1980s technique of replacing a performance-critical inner loop with hand-crafted machine code.
Pure BASIC: ~5-6 hours. Hybrid BASIC + assembly: ~35 minutes. A 10x speedup from 269 bytes of machine code.
BASIC handles the outer pixel loops, floating-point coordinate conversion, and screen plotting. The 269-byte 6502 assembly routine handles the inner z = z² + c iteration loop using signed 8.8 fixed-point arithmetic and a 16x16 shift-and-add multiply — all on a CPU with no multiply instruction and no floating-point hardware.
BASIC and assembly communicate through 6 bytes of shared memory: BASIC writes the complex coordinate and max iterations, calls the routine, and reads back the iteration count.
For the full technical write-up, see doc/article.md.
Load mandel_asm.tap in Oricutron (or a real Oric Atmos). The program auto-runs and begins rendering immediately.
Requires Python 3. No external dependencies.
python build_mandel_asm.py
This assembles mandel_asm.s, generates mandel_asm.bas with embedded DATA statements, and converts it to mandel_asm.tap.
| File | Description |
|---|---|
mandel_asm.s |
6502 assembly source for the Mandelbrot iteration routine. Implements signed 8.8 fixed-point arithmetic, 16x16 shift-and-add multiply, and the escape-time iteration loop. Well-commented. |
mandel.bas |
Pure BASIC Mandelbrot renderer with comments. The unoptimised baseline — correct but takes ~5-6 hours. |
mandel_fast.bas |
Streamlined pure BASIC version (no comments, tighter line numbering). Same algorithm as mandel.bas. |
| File | Description |
|---|---|
build_mandel_asm.py |
Build pipeline. Assembles the .s file, generates a BASIC program with the machine code embedded as DATA statements, and produces a .tap tape image. |
asm6502.py |
Minimal two-pass 6502 assembler in Python. Supports labels, constants, ~50 opcodes, and the addressing modes needed for the project. |
bas2tap.py |
Converts .bas text files to the Oric's tokenised .tap tape format. Handles all Oric BASIC keywords and the tape header/trailer structure. |
| File | Description |
|---|---|
mandel_asm.bas |
The hybrid BASIC + assembly program, generated by the build script. Human-readable — contains the BASIC wrapper and the machine code as DATA statements. |
mandel_asm.tap |
Tape image ready to load in Oricutron or transfer to a real Oric. Auto-runs on load. |
| File | Description |
|---|---|
doc/article.md |
Full technical article covering the hybrid technique, fixed-point arithmetic, the shift-and-add multiply, BASIC-assembly communication, performance analysis, and historical context. |
doc/social_posts.md |
Suggested social media posts for X and LinkedIn. |
| File | Description |
|---|---|
screenshots/mandel_asm_final.png |
The completed Mandelbrot set render (240x200, monochrome, ~35 minutes). |
- CPU: 6502 @ 1 MHz
- Display: 240x200 monochrome HIRES
- Number format: Signed 8.8 fixed-point (precision: 1/256 ≈ 0.004)
- Multiply: 16x16 → 32-bit unsigned shift-and-add, with sign handling
- Assembly size: 269 bytes at $9800-$990C
- Parameter block: 6 bytes at $9A00-$9A05
- Zero page workspace: $50-$5F (saved/restored to avoid corrupting BASIC)
- Max iterations: 20
