Skip to content

Repository files navigation

Tiny8

PyPI versionLicensePython versionsCIcodecov

An educational 8-bit CPU simulator with interactive visualization

Tiny8 is a lightweight and educational toolkit for exploring the fundamentals of computer architecture through hands-on assembly programming and real-time visualization. Designed for learning and experimentation, it features an AVR-inspired 8-bit CPU with 32 registers, a rich instruction set, and powerful debugging tools — all with zero heavy dependencies.

Animated bubble sort visualization

Real-time visualization of a bubble sort algorithm executing on Tiny8

✨ Features

🎯 Interactive Terminal Debugger

CLI visualizer screenshot
  • Vim-style navigation: Step through execution with intuitive keyboard controls
  • Change highlighting: See exactly what changed at each step (registers, flags, memory)
  • Advanced search: Find instructions, track register/memory changes, locate PC addresses
  • Marks and bookmarks: Set and jump to important execution points
  • Vertical scrolling: Handle programs with large memory footprints

🎬 Graphical Animation

  • Generate high-quality GIF/MP4 videos of program execution
  • Visualize register evolution, memory access patterns, and flag changes
  • Perfect for presentations, documentation, and learning materials

🏗️ Complete 8-bit Architecture

  • 32 general-purpose registers (R0-R31)
  • 8-bit ALU with arithmetic, logical, and bit manipulation operations
  • Status register (SREG) with 8 condition flags
  • 2KB address space for unified memory and I/O
  • Stack operations with dedicated stack pointer
  • AVR-inspired instruction set with 60+ instructions

📚 Educational Focus

  • Clean, readable Python implementation
  • Comprehensive examples (Fibonacci, bubble sort, factorial, and more)
  • Step-by-step execution traces for debugging
  • Full API documentation and instruction set reference

🚀 Quick Start

Installation

pip install tiny8

Your First Program

Create fibonacci.asm:

; Fibonacci Sequence Calculator; Calculates the 10th Fibonacci number (F(10) = 55); F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2);; Results stored in registers:; R16 and R17 hold the two most recent Fibonacci numbers ldi r16,0 ; F(0) = 0 ldi r17,1 ; F(1) = 1 ldi r18,9 ; Counter: 9 more iterations to reach F(10)loop:add r16, r17 ; F(n) = F(n-1) + F(n-2)mov r19, r16 ; Save result temporarilymov r16, r17 ; Shift: previous = currentmov r17, r19 ; Shift: current = new resultdec r18 ; Decrement counter brne loop ; Continue if counter != 0done:jmp done ; Infinite loop at end

Run it:

tiny8 fibonacci.asm # Interactive debugger
tiny8 fibonacci.asm -m ani -o fibonacci.gif # Generate animation

Python API

fromtiny8importCPU, assemble_fileasm=assemble_file("fibonacci.asm")
cpu=CPU()
cpu.load_program(asm)
cpu.run(max_steps=1000)
print(f"Result: R17 = {cpu.read_reg(17)}") # Final Fibonacci number

💡 Why Tiny8?

For Students — Write assembly, see immediate results with visual feedback. Understand how each instruction affects CPU state without abstractions.

For Educators — Interactive demonstrations, easy assignment creation, and generate animations for lectures.

For Hobbyists — Rapid algorithm prototyping at the hardware level with minimal overhead and an extensible, readable codebase.

📖 Documentation

🎮 Interactive CLI Controls

The terminal-based debugger provides powerful navigation and inspection capabilities.

Navigation & Playback

  • l / h or / — Step forward/backward
  • w / b — Jump ±10 steps
  • 0 / $ — Jump to first/last step
  • Space — Play/pause auto-execution
  • [ / ] — Decrease/increase playback speed

Display & Inspection

  • r — Toggle register display (all/changed only)
  • M — Toggle memory display (all/non-zero only)
  • = — Show detailed step information
  • j / k — Scroll memory view up/down

Search & Navigation Commands (press :)

  • :123 — Jump to step 123
  • :+50 / :-20 — Relative jumps
  • :/ldi — Search forward for instruction "ldi"
  • :?add — Search backward for "add"
  • :@0x100 — Jump to PC address 0x100
  • :r10 — Find next change to register R10
  • :r10=42 — Find where R10 equals 42
  • :m100 — Find next change to memory[100]
  • :fZ — Find next change to flag Z

Marks & Help

  • ma — Set mark 'a' at current step
  • 'a — Jump to mark 'a'
  • / — Show help screen
  • q or ESC — Quit

🎓 Examples

The examples/ directory contains programs demonstrating key concepts:

ExampleDescription
fibonacci.asmFibonacci sequence using registers
bubblesort.asmSorting algorithm with memory visualization
factorial.asmRecursive factorial calculation
find_max.asmFinding maximum value in array
is_prime.asmPrime number checking algorithm
gcd.asmGreatest common divisor (Euclidean algorithm)

Bubble Sort

Sort 32 bytes in memory:

tiny8 examples/bubblesort.asm -ms 0x60 -me 0x80 # Watch live
tiny8 examples/bubblesort.asm -m ani -o sort.gif -ms 0x60 -me 0x80 # Create GIF

Using Python

fromtiny8importCPU, assemble_filecpu=CPU()
cpu.load_program(assemble_file("examples/bubblesort.asm"))
cpu.run()
print("Sorted:", [cpu.read_ram(i) foriinrange(0x60, 0x80)])

🔧 CLI Options

Command Syntax

tiny8 FILE [OPTIONS]

General Options

OptionDescription
-m, --mode {cli,ani}Visualization mode: cli for interactive debugger (default), ani for animation
-v, --versionShow version and exit
--max-steps NMaximum execution steps (default: 15000)

Memory Display Options

OptionDescription
-ms, --mem-start ADDRStarting memory address (decimal or 0xHEX, default: 0x00)
-me, --mem-end ADDREnding memory address (decimal or 0xHEX, default: 0xFF)

CLI Mode Options

OptionDescription
-d, --delay SECInitial playback delay in seconds (default: 0.15)

Animation Mode Options

OptionDescription
-o, --output FILEOutput filename (.gif, .mp4, .png)
-f, --fps FPSFrames per second (default: 60)
-i, --interval MSUpdate interval in milliseconds (default: 1)
-pe, --plot-every NUpdate plot every N steps (default: 100, higher = faster)

Windows: CLI debugger requires WSL or windows-curses. Animation works natively.

📋 Instruction Set Reference

Tiny8 implements an AVR-inspired instruction set with 62 instructions organized into logical categories. All mnemonics are case-insensitive. Registers are specified as R0-R31, immediates support decimal, hex ($FF or 0xFF), and binary (0b11111111) notation.

Data Transfer

InstructionDescriptionExample
LDI Rd, KLoad 8-bit immediate into registerldi r16, 42
MOV Rd, RrCopy register to registermov r17, r16
LD Rd, RrLoad from RAM at address in Rrld r18, r16
ST Rr, RsStore Rs to RAM at address in Rrst r16, r18
IN Rd, portRead from I/O port into registerin r16, 0x3F
OUT port, RrWrite register to I/O portout 0x3F, r16
PUSH RrPush register onto stackpush r16
POP RdPop from stack into registerpop r16

Arithmetic Operations

InstructionDescriptionExample
ADD Rd, RrAdd registersadd r16, r17
ADC Rd, RrAdd with carryadc r16, r17
SUB Rd, RrSubtract registerssub r16, r17
SUBI Rd, KSubtract immediatesubi r16, 10
SBC Rd, RrSubtract with carrysbc r16, r17
SBCI Rd, KSubtract immediate with carrysbci r16, 5
INC RdIncrement registerinc r16
DEC RdDecrement registerdec r16
MUL Rd, RrMultiply (result in Rd:Rd+1)mul r16, r17
DIV Rd, RrDivide (quotient→Rd, remainder→Rd+1)div r16, r17
NEG RdTwo's complement negationneg r16
ADIW Rd, KAdd immediate to word (16-bit)adiw r24, 1
SBIW Rd, KSubtract immediate from wordsbiw r24, 1

Logical & Bit Operations

InstructionDescriptionExample
AND Rd, RrLogical ANDand r16, r17
ANDI Rd, KAND with immediateandi r16, 0x0F
OR Rd, RrLogical ORor r16, r17
ORI Rd, KOR with immediateori r16, 0x80
EOR Rd, RrExclusive OReor r16, r17
EORI Rd, KXOR with immediateeori r16, 0xFF
COM RdOne's complementcom r16
CLR RdClear register (XOR with self)clr r16
SER RdSet register to 0xFFser r16
TST RdTest for zero or negativetst r16
SWAP RdSwap nibbles (high/low 4 bits)swap r16
SBI port, bitSet bit in I/O registersbi 0x18, 3
CBI port, bitClear bit in I/O registercbi 0x18, 3

Shifts & Rotates

InstructionDescriptionExample
LSL RdLogical shift leftlsl r16
LSR RdLogical shift rightlsr r16
ROL RdRotate left through carryrol r16
ROR RdRotate right through carryror r16

Control Flow

InstructionDescriptionExample
JMP labelUnconditional jumpjmp loop
RJMP offsetRelative jumprjmp -5
CALL labelCall subroutinecall function
RCALL offsetRelative callrcall -10
RETReturn from subroutineret
RETIReturn from interruptreti
BRNE labelBranch if not equal (Z=0)brne loop
BREQ labelBranch if equal (Z=1)breq done
BRCS labelBranch if carry set (C=1)brcs overflow
BRCC labelBranch if carry clear (C=0)brcc no_carry
BRGE labelBranch if greater/equalbrge positive
BRLT labelBranch if less thanbrlt negative
BRMI labelBranch if minus (N=1)brmi negative
BRPL labelBranch if plus (N=0)brpl positive

Compare Instructions

InstructionDescriptionExample
CP Rd, RrCompare registers (Rd - Rr)cp r16, r17
CPI Rd, KCompare with immediatecpi r16, 42
CPSE Rd, RrCompare, skip if equalcpse r16, r17

Skip Instructions

InstructionDescriptionExample
SBRS Rd, bitSkip if bit in register is setsbrs r16, 7
SBRC Rd, bitSkip if bit in register is clearsbrc r16, 7
SBIS port, bitSkip if bit in I/O register is setsbis 0x16, 3
SBIC port, bitSkip if bit in I/O register is clearsbic 0x16, 3

MCU Control

InstructionDescriptionExample
NOPNo operationnop
SEISet global interrupt enablesei
CLIClear global interrupt enablecli

Status Register (SREG) Flags

The 8-bit status register contains condition flags updated by instructions:

BitFlagDescription
7IGlobal interrupt enable
6TBit copy storage
5HHalf carry (BCD arithmetic)
4SSign bit (N ⊕ V)
3VTwo's complement overflow
2NNegative
1ZZero
0CCarry/borrow

Flags are used for conditional branching and tracking arithmetic results.

Assembly Syntax Notes

  • Comments: Use ; for line comments
  • Labels: Must end with : (e.g., loop:)
  • Registers: Case-insensitive R0-R31 (r16, R16 equivalent)
  • Immediates: Decimal (42), hex ($2A, 0x2A), binary (0b00101010)
  • Whitespace: Flexible indentation, spaces/tabs interchangeable

🏗️ Architecture Overview

CPU Components

  • 32 General-Purpose Registers (R0-R31) — 8-bit working registers
  • Program Counter (PC) — 16-bit, addresses up to 64KB
  • Stack Pointer (SP) — 16-bit, grows downward from high memory
  • Status Register (SREG) — 8 condition flags (I, T, H, S, V, N, Z, C)
  • 64KB Address Space — Unified memory for RAM and I/O

Memory Map

0x0000 - 0x001F Memory-mapped I/O (optional)
0x0020 - 0xFFFF Available RAM (stack grows downward from top)

🧪 Testing

pytest # Run all tests
pytest --cov=src/tiny8 --cov-report=html # With coverage
pytest tests/test_arithmetic.py # Specific test file

🤝 Contributing

Contributions welcome! See CONTRIBUTING.md for guidelines.

Areas for contribution: New instructions, example programs, documentation, visualizations, performance optimizations.

📄 License

MIT License — see LICENSE for details.

📞 Support


Made with ❤️ for learners, educators, and curious minds

Star ⭐ the repo if you find it useful!

About

A tiny CPU simulator written in Python

Topics

Resources

Contributing

Stars

1.4k stars

Watchers

5 watching

Forks

Releases

Contributors

Languages