Table of Contents

6502 Emulator

A simple web-based 6502 emulator is available at https://6502.cdot.systems. This emulator is used in the SPO600 course to teach 8-bit assembly language before transitioning to more complex 64-bit x86_64 and AArch64 assembly language.

In most 6502 documentation, including this page, the $ prefix indicates hexadecimal notation. On other systems, this may be designated by a 0x prefix.

Basic Controls

The emulator has a text area for entering and editing code, a small bit-mapped graphics screen (32×32 pixels), a character screen (80×25 characters), a debug area, a memory monitor, and a message area.

These controls are available at the top of the screen:

The Speed slider lets you adjust the speed of the emulator from about 1% of native 6502 performance (left) to roughly full native speed of a 1MHz CPU (right; this is not fully accurate to the CPU speed since the emulator is not cycle-accurate). Setting the speed slider to a lower setting can be useful for debugging and for viewing the progress of operations on the displays.

There are also controls to Save and Load the text area to/from local storage on the computer on which it is running (as a download/upload); this works nicely with a local git repository (or clone).

Assembler Capabilities

The assembler accepts these inputs:

Instructions

Directives

High and Low Label Bytes

 *=$f000
 DISPLAY:

You could then create a pointer to that address at $0027 with this code:

 LDA #<DISPLAY
 STA $27
 LDA #>DISPLAY
 STA $28

Comments

Using the Debugger

The debugger will constantly show the value of the emulated 6502's registers. If you select the Debugger checkbox, you will be able to single-step through memory or jump to an address or label using the associated pushbuttons.

Using the Monitor

Selecting the Monitor checkbox will display the specified region of memory as code is executed. For example, specifying a start of $00 and a length of $100 will display the entire zero page. Once enabled, the monitor may not display until the code is executed (via Run button).

Turning the Text Screen On/Off

The checkbox labeled “Text Screen” can be used to hide the character display to free up more screen space for editing code. Note also that the character display can be used for additional program memory (whether the display is enabled or not) when it's not required for output.

Peripherals and Memory Map

The entire 64K address space is available and is populated with RAM except for peripherals and a small ROM area.

The memory map contains these regions:

There are four peripherals available:

The Reset button clears the zero page, bitmap display, and character display, and resets the stack pointer (SP=$ff), program counter (PC=$0600), status register (P=$30), and the general purpose registers (A=X=Y=$00).

Code is assembled starting at $0600 (unless the code changes the location with a *=address directive). Memory following the program is reset to $00. A BRK instruction ($00) will cause the program to stop and return control to the debugger.

For more details, press the Notes button in the emulator.

ROM Routines

Many 6502 personal/home computers had the operating system installed in read-only memory (ROM) chips. The emulator has a small ROM chip with these simple input/output (I/O) routines defined:

    If C=0: X,Y registers set the cursor position
            Y:A is returned as a pointer to the current screen position 
                (i.e., Y is the high byte and A is the low byte of a pointer
                to the memory address of the current cursor position)
    If C=1: X,Y registers return the current cursor position
            A contains the character at the current cursor location

Registers which are not used for input/output are not affected by the ROM routines. The ROM routines use $f0-fd in the zero page for variable storage.

To use the ROM routines, these define directives may be pasted into your code:

 define		SCINIT		$ff81 ; initialize/clear screen
 define		CHRIN		$ffcf ; input character from keyboard
 define		CHROUT		$ffd2 ; output character to screen
 define		SCREEN		$ffed ; get screen size
 define		PLOT		$fff0 ; get/set cursor coordinates

You can then access the routines by name using the JSR instruction:

 LDA #$41        ; ASCII code for the letter "A"
 JSR CHROUT      ; execute the CHROUT routine (print the character on the screen)

The ROM routine names and locations pay homage to a famous 6502-based family of computers. Discovering which one is left as an exercise for the reader!

Example Code

See the 6502 Emulator Example Code page.

Source Code

The emulator's source code can be found at https://github.com/ctyler/6502js … Pull Requests are welcome.