Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Building a 6502 Assembler: A Complete Tutorial

Welcome to the Byte Fantasy Console Assembler Tutorial! This comprehensive guide will walk you through building a complete 6502 assembler from scratch.

What You’ll Build

By the end of this tutorial, you’ll have a fully functional assembler that can:

  • Parse 6502 assembly source code using the ByteASM language
  • Resolve labels and forward references
  • Generate machine code binaries
  • Handle directives like .org, .db, .dw, .equ, .include
  • Evaluate expressions (e.g., label + 5)
  • Report meaningful errors with line/column information

Prerequisites

  • Basic Rust knowledge (ownership, structs, enums, pattern matching)
  • No prior knowledge of assemblers or compilers required

Tutorial Chapters

Part 1: Foundations

  1. Introduction to Assemblers and the 6502
  2. Building the Scanner (Lexer)

Part 2: Parsing

  1. Designing the Abstract Syntax Tree
  2. Building the Parser - Structure
  3. Building the Parser - Implementation

Part 3: Assembly

  1. The Symbol Table
  2. Two-Pass Assembly
  3. Code Generation
  4. Expression Evaluation

Part 4: Completion

  1. Implementing Directives
  2. Error Handling and Reporting
  3. The Command-Line Interface
  4. Testing the Assembler
  5. Complete Example - A Game

Quick Start

Once you’ve completed the tutorial, you can assemble programs like this:

cargo run -p byte_asm -- bouncing_ball.s -o game.bin
cargo run -p byte_emu -- game.bin

ByteASM Language Overview

ByteASM is a clean, modern 6502 assembly language designed for the Byte fantasy console:

; bouncing_ball.s - A simple demo for Byte console

.equ BALL_X   0x00
.equ BALL_Y   0x01
.equ VRAM     0x1000

.org 0x8000

reset:
    lda #32           ; initialize ball position
    sta BALL_X
    sta BALL_Y

main_loop:
    jsr update_ball
    jsr draw_ball
    rti               ; wait for next frame

update_ball:
    lda BALL_X
    clc
    adc #1
    sta BALL_X
    rts

draw_ball:
    ldx BALL_X
    lda #1            ; white color
    sta VRAM,x
    rts

.org 0xFFFC
.dw reset             ; reset vector
.dw main_loop         ; IRQ vector

Key Features

  • Numeric literals: Decimal (255), hexadecimal (0xFF), binary (0b11111111)
  • All lowercase mnemonics and registers
  • Local labels with . or @ prefix
  • Expressions with +, -, *, / operators
  • Byte extraction with < (low byte) and > (high byte)
  • Current address with $

Project Structure

byte_asm/
├── src/
│   ├── lib.rs              # Library exports
│   ├── main.rs             # CLI application
│   ├── ast.rs              # Abstract Syntax Tree
│   ├── error.rs            # Unified error types
│   ├── symbol.rs           # Symbol table
│   ├── scanner/            # Lexical analysis
│   ├── parser/             # Syntax analysis
│   └── assembler/          # Code generation
├── tests/                  # Integration tests
└── examples/               # Example assembly programs

Let’s begin with Chapter 1: Introduction to Assemblers and the 6502!