1

Neon Nexus: Your First Game World

Commodore 64 • Phase 1 • Tier 1

Create your first game world in assembly! Learn to set up the C64 screen, create a colorful neon arena, and understand the fundamentals of 6502 assembly programming through hands-on game development.

easy
⏱️ 45-60 minutes
💻 Code Examples
🛠️ Exercise
🎯

Learning Objectives

  • Write your first C64 assembly program that actually runs
  • Understand basic 6502 assembly syntax and structure
  • Learn to control screen colors and create visual environments
  • Set up the foundation for your Neon Nexus game
  • Master the development cycle: write, assemble, and test
🧠

Key Concepts

6502 assembly basics: instructions, addresses, and hex numbers C64 memory map: where screen and color data live Program structure: how assembly programs are organized Hardware registers: directly controlling the C64's video chip Development workflow: from source code to running program

Lesson 1: Neon Nexus - Your First Game World

Welcome to assembly programming on the Commodore 64! Today, you’ll create the foundation of Neon Nexus, a fast-paced action game set in a glowing electronic arena. But we’ll start small - just getting something on screen.

Setting Up Your Development Environment

Before we can write any code, we need to install ACME, a straightforward 6502 assembler designed specifically for machines like the C64.

macOS Setup

brew install acme

Windows Setup

  1. Download ACME from: https://github.com/meonwax/acme/releases
  2. Extract to C:\acme
  3. Add C:\acme to your PATH:
    • Right-click “This PC” → Properties → Advanced system settings
    • Click “Environment Variables”
    • Under System Variables, find “Path” and click Edit
    • Add new entry: C:\acme
    • Click OK to save

Linux Setup

# Ubuntu/Debian
sudo apt install acme

# Arch/Manjaro
yay -S acme

# Or build from source
git clone https://github.com/meonwax/acme.git
cd acme/src
make
sudo make install

Create Your Project Folder

  1. Create a folder for your C64 projects:

    • Windows: C:\Users\YourName\C64Projects
    • macOS/Linux: ~/C64Projects
  2. Create a subfolder for this lesson: lesson1

  3. Open your favorite text editor (VS Code, Notepad++, vim, etc.)

Your First Assembly Program

Let’s build a C64 program step by step, testing each stage as we go.

Step 1: The Minimal Program

Create a new file called neon1.s with just the absolute basics:

; Neon Nexus - Lesson 1
; Our first C64 program

*= $c000               ; Tell C64 to load at $c000 (49152)

start:
        rts             ; Return to BASIC

What’s happening:

  • *= $c000 sets where our program loads in memory (address 49152)
  • start: is a label marking where our code begins
  • rts (Return from Subroutine) returns control to BASIC

Build and test:

acme -f cbm -o neon1.prg neon1.s

To run in VICE:

  1. Start VICE: x64sc neon1.prg (or use the Windows GUI)
  2. The program auto-loads but doesn’t run
  3. Type SYS 49152 and press Enter
  4. You won’t see anything happen - that’s correct! The cursor should just move to the next line

Verify it loaded: Type PRINT PEEK(49152) - you should see 96 (the RTS instruction).

Step 2: Change the Border Color

Now let’s make something visible happen. Replace the contents of your start: section:

start:
        lda #$02        ; Load red color value
        sta $d020       ; Store to border color register
        rts             ; Return to BASIC

Build and test again:

acme -f cbm -o neon1.prg neon1.s
x64sc neon1.prg

Type SYS 49152 - this time the border should turn red!

New concepts:

  • lda (Load Accumulator) puts a value into the A register
  • sta (Store Accumulator) saves that value to a memory address
  • $d020 is the C64’s border color register

Step 3: Set Multiple Colors

Let’s expand to set both border and background. Add these lines after the border color code but before rts:

        ; Set background color to black
        lda #$00        ; Black color value
        sta $d021       ; Background color register

Your start: section should now look like:

start:
        lda #$02        ; Load red color value
        sta $d020       ; Store to border color register
        
        ; Set background color to black
        lda #$00        ; Black color value
        sta $d021       ; Background color register
        
        rts             ; Return to BASIC

Build and test - you should see a red border with black background.

Step 4: Create the Neon Arena Look

Red border isn’t very “neon”. Let’s change to our game’s color scheme. Modify the border color value:

start:
        lda #$06        ; Dark blue (was #$02)
        sta $d020       ; Store to border color register
        
        ; Set background color to black
        lda #$00        ; Black color value
        sta $d021       ; Background color register
        
        rts             ; Return to BASIC

Build and test - now you have a dark blue border that’s more fitting for our neon theme!

Step 5: Clear the Screen

Now let’s clear any text on screen. Add this after setting colors but before rts:

        ; Clear the screen
        lda #$93        ; Clear screen character (147 decimal)
        jsr $ffd2       ; Call KERNAL CHROUT routine

New concepts:

  • jsr (Jump to Subroutine) calls built-in C64 routines
  • $ffd2 is CHROUT - it prints the character in the A register
  • Character 147 ($93) clears the screen

Step 6: Move to BASIC Memory Area

So far we’ve loaded at $C000, but most C64 programs live in the BASIC area. Let’s restructure properly. Replace your entire program with:

; Neon Nexus - Lesson 1
; Creating our neon arena

*= $0801

; BASIC stub: 10 SYS 2061
!word next_line
!word 10
!byte $9e
!text "2061"
!byte 0
next_line:
!word 0

; Start of our program
start:
        ; Set border color to dark blue
        lda #$06     
        sta $d020
        
        ; Set background color to black
        lda #$00
        sta $d021
        
        ; Clear the screen
        lda #$93
        jsr $ffd2
        
        rts

What’s new:

  • *= $0801 loads in BASIC memory area
  • The BASIC stub creates a line “10 SYS 2061”
  • This lets us use RUN instead of remembering SYS addresses
  • !word, !byte, !text are ACME directives for data

Build and test:

acme -f cbm -o neon1.prg neon1.s
x64sc neon1.prg

Now you can just type RUN after loading!

Making It Better with Subroutines

Let’s organize our code better using subroutines. This will be important as our game grows.

Step 7: Create Setup Subroutine

Replace your start: section with this:

start:
        jsr setup_arena
        rts

Then add this subroutine after the start section:

setup_arena:
        ; Set border color to dark blue
        lda #$06     
        sta $d020
        
        ; Set background color to black
        lda #$00
        sta $d021
        
        ; Clear the screen
        lda #$93
        jsr $ffd2
        
        rts

The code does exactly the same thing, but now it’s organized into a reusable subroutine!

Step 8: Add Visual Confirmation

Let’s add something to show our program ran successfully. Add this new subroutine after setup_arena::

show_ready:
        ; Put a star in the top-left corner
        lda #$2a        ; Star character
        sta $0400       ; Screen memory start
        
        ; Make it white
        lda #$01        ; White color
        sta $d800       ; Color RAM start
        
        rts

Then update start: to call it:

start:
        jsr setup_arena
        jsr show_ready    ; ADD THIS LINE
        rts

Build and test - you should see a white star in the top-left corner!

Complete Working Examples

The complete working code for this lesson is available in our code samples repository:

📁 Lesson 1 Code Examples

All examples are tested and ready to assemble with ACME:

acme -f cbm -o neon1.prg complete.s
x64sc neon1.prg

Type RUN to see your neon arena with dark blue border, black background, and white star indicator!

Understanding What We Built

Memory Map Basics

The C64 has memory-mapped hardware. Instead of special commands, we control hardware by writing to specific memory addresses:

AddressPurpose
$D020Border color
$D021Background color
$0400-$07E7Screen memory (characters)
$D800-$DBE7Color memory

Color Values

The C64 has 16 colors:

ValueColor
$00Black
$01White
$02Red
$03Cyan
$04Purple
$05Green
$06Blue
$07Yellow

ACME Syntax Summary

DirectivePurposeExample
*=Set memory address*= $0801
!word16-bit value!word $080b
!byte8-bit value!byte $9e
!textText string!text "2061"

What You’ve Accomplished

In this lesson, you’ve:

Written your first C64 assembly program
Learned basic 6502 instructions (LDA, STA, JSR, RTS)
Controlled hardware directly through memory-mapped registers
Used KERNAL routines to clear the screen
Organized code with subroutines for better structure

More importantly, you’ve seen how assembly gives you complete control over the hardware - every pixel, every color, every byte of memory is yours to command.

Experiment and Learn

Try these modifications to deepen your understanding:

  1. Different border colors:

    lda #$02        ; Red
    lda #$05        ; Green
    lda #$07        ; Yellow
    lda #$0e        ; Light blue
    
  2. Different characters:

    lda #$51        ; Circle
    lda #$5a        ; Diamond
    lda #$58        ; X
    lda #$53        ; Heart
    
  3. Different screen positions:

    sta $0400 + 40  ; Second row
    sta $0400 + 80  ; Third row
    sta $0400 + 500 ; Near center
    
  4. Multiple characters:

    lda #$2a
    sta $0400       ; Top-left
    sta $0427       ; Top-right
    sta $07c0       ; Bottom-left
    sta $07e7       ; Bottom-right
    

Coming Next

In Lesson 2, you’ll create your game entity - a player character that you can position anywhere on screen. You’ll learn about:

  • X and Y coordinates for positioning
  • Screen memory calculations
  • Creating and coloring game objects
  • Building reusable entity systems

Your neon arena is ready - time to add a player!

Quick Reference

6502 Instructions Used:

  • LDA #value - Load value into A register
  • STA address - Store A register to memory
  • JSR address - Jump to subroutine
  • RTS - Return from subroutine

C64 Registers:

  • $D020 - Border color
  • $D021 - Background color
  • $FFD2 - CHROUT (print character)

Build Command:

acme -f cbm -o filename.prg filename.s

Ready to continue? Your journey into C64 game programming has just begun!