Lab 2 Adventures in 6502 Assembly

 

Bouncing Pixels and Going Solo: Lab 2 Adventures in 6502 Assembly

Introduction

Lab 2 was originally meant to be a mob programming session, think pair programming, but with a full group, all sharing one screen and collaborating on every line of code. Unfortunately, I couldn’t make it to the in-class session, so I ended up taking on the lab solo. While I missed out on the live collaboration part, I still got a chance to dive deep into the code, experiment with the animation logic, and get creative with bouncing a graphic around the screen using 6502 Assembly.

This post walks through my solo journey with Lab 2: animating a graphic diagonally, making it bounce off the edges of the screen, and exploring some fun optional challenges along the way.

Setting Up the Animation

We were given a base program that moves a 5×5 pixel graphic diagonally across the emulator screen. The starting point was a neat little subroutine called DRAW, which takes an image, its position, and then places it onto the screen. The main loop handles updating the position and re-drawing the image in each frame.

To get started, I ran the provided code in the 6502 emulator. The animation worked perfectly, the graphic moved smoothly in a diagonal line from the top-left to the bottom-right corner. It was cool seeing Assembly logic turn into actual movement on screen.

Adding the Bounce

The real task was to make the graphic bounce off the edges of the screen. That meant updating the X and Y position on every frame, but also reversing direction whenever the image hit a boundary. Here’s how I tackled it:

1. Tracking the Direction

I introduced two new zero-page variables to store the direction of movement—let’s call them XDELTA and YDELTA. These held either #01 or #$FF (which is -1 in two’s complement), depending on the current direction of movement.

define XDELTA $22

define YDELTA $23


2. Updating the Position

Instead of simply incrementing XPOS and YPOS, I used these delta values:

CLC

LDA XPOS

ADC XDELTA

STA XPOS


CLC

LDA YPOS

ADC YDELTA

STA YPOS


This allowed me to switch direction just by changing the delta value from 01 to FF, and vice versa.

3. Bouncing Off the Walls

To handle the bouncing, I added checks after each position update:

; Horizontal bounds (0 to 31)

LDA XPOS

CMP #$00

BEQ FLIP_X

CMP #$1F

BEQ FLIP_X


; Vertical bounds (0 to 31)

LDA YPOS

CMP #$00

BEQ FLIP_Y

CMP #$1F

BEQ FLIP_Y


When the graphic hit a wall, I flipped the corresponding delta:

FLIP_X:

  LDA XDELTA

  EOR #$FF

  CLC

  ADC #$01

  STA XDELTA

  JMP DONE_FLIP


FLIP_Y:

  LDA YDELTA

  EOR #$FF

  CLC

  ADC #$01

  STA YDELTA


DONE_FLIP:


This bitwise EOR + ADC trick was my way of toggling between 01 and FF without needing conditional logic.

Challenge: Changing Color on Bounce

One fun extension I added was changing the image every time it bounced. So if the image was “O” during normal movement, it would switch to “X” when it hit a wall.

To do this, I added a flag to track the current graphic and toggled it in FLIP_X and FLIP_Y. Then in the main loop, the code checked the flag and loaded either G_O or G_X.

LDA CURRENT_GRAPHIC

BEQ USE_O

LDA #<G_X

STA $10

LDA #>G_X

STA $11

JMP DRAW_GO


USE_O:

LDA #<G_O

STA $10

LDA #>G_O

STA $11


DRAW_GO:

; continue as normal


I also stored the current graphic flag in a zero-page variable so it could be flipped easily on bounce.


Reflections

Even though I didn’t get to do the group part of this lab, I actually found it kind of fun working through it on my own. Assembly is still pretty unforgiving, you really have to think step-by-step and be mindful of how values wrap around or overflow. But it also means you have full control, and that’s super satisfying once things start working.

This lab helped me get more comfortable with control flow, using two’s complement math, and thinking about graphics as raw memory data. I’m also starting to see how these small, seemingly simple programs can be built into more complex animations and interactions.

Assembly still isn’t easy, but it’s getting more intuitive the more I work with it. And watching a little square bounce around the screen in pixel-perfect harmony? That’s a win in my book.


Comments

Popular posts from this blog

Project Stage 2.A

Project Stage 3

Project Stage 2.C

Welcome to My SPO600 Journey

Lab1 6502 Assembly Language

Stage 1 Completed

Project Stage 2.B

Lab 4 Building GCC on My Linux VM

Project Stage 1 Diving In!