Open main menu

CDOT Wiki β

6502 Emulator

Revision as of 00:04, 31 January 2020 by Chris Tyler (talk | contribs)
A screen shot of the 6502 Emulator running the drawing example code.

A simple web-based 6502 emulator is available at http://6502.cdot.systems

Basic Controls

The emulator has a text area for data entry, a small bit-mapped screen (32x32 pixels), a character screen (80x25 characters), a debug area, a memory monitor, and a message area.

These controls are available at the top of the screen:

  • Assemble - assembles the code in the text area, placing the resulting binary machine language code at $0600 and outputting any error messasges to the message area.
  • Run - runs the assembled code, if it assembled correctly. While the code is running, this button becomes a Stop button.
  • Reset - resets the state of the emulator (see the Memory Map section below).
  • Hexdump - shows, in hexadecimal, the values stored in memory starting at $0600
  • Disassemble - shows a combined hexdump and disassembly of code at $0600
  • Notes - displays notes about the emulator in the message area.

The Speed slider lets you adjust the speed of the emulator from about 1% of native 6502 performance (left) to roughly full native speed (right). Setting the speed slider to a lower setting can be useful for debugging and for viewing the progress of operations on the displays.

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 $ff will display the entire zero page.

Turning the Text Screen On/Off

The checkbox labeled "Text Screen" can be used to hide the character display to free up more space for editing code.

Peripherals and Memory Map

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

There are four peripherals available:

  • a one-byte pseudo-random number generator (PRNG) at $fe.
  • a single-key buffer at $ff - if you write to this address, it will remain unchanged until a new keypress is received. Printable characters plus Return/Enter and Backspace are reported as ASCII codes; cursor keys are reported as $80=up, $81=right, $82=down, $83=left.
  • a 32x32 pixel bitmapped display at $0200-$05ff, with one byte per pixel. The lowest four bits of each byte select one of 16 colours.
  • an 80x25 character display at $f000-$7cff, with one byte per pixel. Printable ASCII characters will be displayed. If the high-order bit is set, the character will be shown in  reverse video .
  • a read-only ROM chip is present at $fe00-$ffff; see below for details.

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

These routines are defined in ROM:

  • SCINIT $ff81 - Initialize and clear the character display
  • CHRIN $ffcf - Input one character from keyboard (returns A)
  • CHROUT $ffdw - Outputs one character (A) to the screen at the current cursor position. Screen will wrap/scroll appropriately. Printable characters and cursor codes ($80/$81/$82/$83 for up/right/left/down) as well as RETURN ($0d) are accepted. Printable ASCII codes with the high bit set will be printed in reverse video.
  • SCREEN $ffed - Returns the character screen size in the X and Y registers.
  • PLOT $fff0 - gets (CARRY=1) or sets (CARRY=0) the cursor position
   If C=0: X,Y registers set the cursor position
           Y:X is returned as a pointer to the current screen 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.

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:

jsr CHROUT
ROM Routine Names
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

Source Code

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