(Updated January 20, 2025)
Table of Contents
What is an IDE?
An Integrated Development Environment, or IDE, is typically a graphical user interface with an editor, compiler, debugger, and much more at your fingertips.
During the 6502 era, the idea of having a full-featured development environment was unheard of. Tools like graphical interfaces, source debuggers, context-based editors, and the ability to search documentation weren’t generally available.
Thankfully, we do not have to endure those times to start appreciating the 6502 assembly language. When assembling the components for this book, we needed a toolchain to help develop software. Toolchains are programs used in a particular sequence to produce running software. Since the world of 6502 is rather large, there are many options. Some are under active development, while others are still historically available.
In the first half of this textbook, we will not use a toolchain for general instruction. However, we will mention a general set of tools at the end with some links and general examples of how to cross-compile code if you want to build some code to put on an EEPROM for something like a Ben Eater project.
We will use a modified form of the IDE originally created by Nick Morgan and further enhanced by Chris Tyler. Our modifications to the Tyler version are specifically for use with this textbook.
The IDE is both an emulator and simulator. It is an emulator in the sense that all of the general hardware features of the 6502 are provided within the software. This means the operations and behaviors of the instructions, addressing modes, registers, flags, stack, and program counter are provided in software. This includes how long each instruction takes to run in clock cycles. It’s not a perfectly cycle-accurate design, but it’s darn close.
It’s a simulator in the sense that a small computer is provided, both textual and graphical, in which the program can run and produce output which can be used to validate the program’s operation.
It is all self-contained, provided in a web interface, and tightly coupled with this book. When example code is provided, a button will also be available that will launch the IDE in another window, then load the code. If the IDE is already open, it will find the window on your computer and replace whatever is there with the code in the selected example.
Also, be aware that selecting to load code from another example will replace whatever you’re working on without confirmation.
Hello World
Now that we’ve defined the IDE and its capabilities, let’s examine the workspace we will use for our 6502 assembly language development.
The idea behind assembly language is to provide the programmer with instructions (opcodes) and various addressing models to move data and perform various operations. However, as mentioned earlier, it is primitive.
Assembly language source lines are generally made up of the following:
label: instruction operand(s) ; comment
You may also see them as
label: instruction operand(s) ; comment
Consider this simple assembly language program that prints the obligatory "Hello, World!"
. By selecting the Load Workspace
button, another window will launch, and the project code will be loaded.
define CHROUT $ffd2
ldx #0 ; set index to zero
print:
lda words,x ; load a letter from words
beq done ; if it's the zero, we're done
jsr CHROUT ; print the character
inx ; increment the index
bne print ; keep printing
done:
brk ; end!
; data below this line
words:
txt "Hello World!\n"
dcb 0
Once the example code is loaded into the IDE, you select the Assemble
button to turn the source code into a program in the simulated memory. Selecting the Run
button will cause the program to be executed in the simulated computer.
All of this happens within your browser. Later chapters will discuss the other buttons in the IDE. Now, we’re ready to dive deep into the 6502!
Let’s quickly discuss what’s happening in this code. The table below helps to break down the details of the program’s text. Thankfully, it is also colorized, so identifying certain pieces is more effortless.
Name | Example | Purpose |
---|---|---|
Labels | print: , done: , words: |
A named location in the program. These are used instead of explicit addresses to represent positions in the code or data. This allows the programmer to not worry too much about memory locations. Note that labels alone on a line need a colon. |
Instructions | ldx , jsr , inx , brk |
Assembly language instructions. These are the named actions the CPU is to perform with any provided operands. |
Operands | words, x and CHROUT |
Provides the instruction with the information to work with, where appropriate. (Not all instructions have operands, while some have 1 or 2.) |
Directives | define , txt , dcb |
Help to inform the assembler about some of the labels, data types, and external entities. |
A Bigger Example
The example provided below demonstrates the majority of the features we will use.
define bmaplo $10
define bmaphi $11
define scolor $13
define temp $14
lda #$00 ; set bitmap address to $0200
sta bmaplo
sta scolor ; starting color (black)
lda #$02
sta bmaphi
ldx #$06 ; max value for bmaphi
ldy #$00 ; index - this value is added to the pointer
lda #$00 ; colour code to be used to fill the display
loop: sta (bmaplo),y ; store color at bmaplo + y
clc
adc #$01 ; add one to the color
sta temp ; safely store
tya ; test y
and #31 ; cheap mod 32
cmp #31 ; 32 blocks filled?
bne no ; nope
inc scolor ; yup, increment start color
lda scolor ; get new color
sta temp ; ready for next row
no:
lda temp ; restore or new
iny ; increment index
bne loop ; branch until page done - stops when Y==0
inc bmaphi ; increment high byte of pointer
cpx bmaphi ; compare with max value
bne loop ; continue if not done
brk ; done - return to debugger