Skip to content

johnkattenhorn/oricmandlebrot

Repository files navigation

Mandelbrot Set on the Oric Atmos

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.

Mandelbrot set rendered on the Oric Atmos

Pure BASIC: ~5-6 hours. Hybrid BASIC + assembly: ~35 minutes. A 10x speedup from 269 bytes of machine code.

How It Works

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.

Running It

Load mandel_asm.tap in Oricutron (or a real Oric Atmos). The program auto-runs and begins rendering immediately.

Building from Source

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 Guide

Source Code

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.

Build Tools

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.

Generated Output

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.

Documentation

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.

Screenshots

File Description
screenshots/mandel_asm_final.png The completed Mandelbrot set render (240x200, monochrome, ~35 minutes).

Technical Details

  • 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

About

Hybrid BASIC + 6502 assembly Mandelbrot set renderer for the Oric Atmos

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors