Table of Contents

6502 Emulator Example Code

This is a collection of simple examples of 6502 assembly language code which will run in the 6502 Emulator. To use this code, copy and paste one of these programs into the text box of the emulator.

This code is Copyright©2020-2024 Seneca College of Applied Arts and Technology. Each of these programs is free software; you can redistribute them and/or modify them under the terms of the GNU|General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

Fill the Bitmapped Display

       lda #$00     ; set pointer at $10 to $0200
       sta $10
       lda #$02
       sta $11
       ldx #$06     ; max value for $11, the high byte of the pointer
       ldy #$00     ; index - this value is added to the pointer
       lda #$07     ; colour code to be used to fill the display
 loop: sta ($10),y  ; store colour to the value of the pointer + Y
       iny          ; increment index - prepare to fill next pixel
       bne loop     ; branch until page done - stops when Y==0
       inc $11      ; increment high byte of pointer
       cpx $11      ; compare with max value
       bne loop     ; continue if not done 
       brk          ; done - return to debugger

Place a Message on the Character Display

Without using the ROM routines

  define SCREEN $f000     ; location of screen memory
            ldy #$00      ; index value (character we're currently processing)
  char:     lda text,y    ; get a character from address (text + Y)
            beq done      ; if the character is NULL, branch to done
            sta SCREEN,y  ; store character at (SCREEN + Y)
            iny           ; increment Y (go to next character)
            bne char      ; repeat loop
  done:     brk           ; when we're done, break (stop the program)
  text:                   ; this is the text message
  dcb "6","5","0","2",32,"w","a","s",32,"h","e","r","e",".",00

Using the ROM routines

 ; ROM routines
 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
           jsr SCINIT  ; initialize and clear the screen
           ldy #$00
 char:     lda text,y
           beq done
           jsr CHROUT  ; put the character in A on to the screen
           iny
           bne char
 done:     brk
 text:
 dcb "6","5","0","2",32,"w","a","s",32,"h","e","r","e",".",00

Type on the Screen

 ; let the user type on the first page of character screen
 ; has blinking cursor!
 ; does not use ROM routines
 ; backspace works (non-destructive), arrows/ENTER don't
 next:     ldx #$00
 idle:     inx
           cpx #$10
           bne check
           lda $f000,y
           eor #$80
           sta $f000,y
 check:    lda $ff
           beq idle
           ldx #$00
           stx $ff
           cmp #$08 ; bs
           bne print
           lda $f000,y
           and #$7f
           sta $f000,y
           dey
           jmp next
 print:    sta $f000,y
           iny
           jmp next

Place a Graphic on the Screen

  define WIDTH 	4 ; width of graphic
  define HEIGHT 	4 ; height of graphic

  	lda #$25	; create a pointer at $10
  	sta $10		;   which points to where
  	lda #$02	;   the graphic should be drawn
  	sta $11
  	lda #$00	; number of rows we've drawn
  	sta $12		;   is stored in $12
  	ldx #$00	; index for data
  	ldy #$00	; index for screen column
  draw:	lda data,x
  	sta ($10),y
  	inx
  	iny
  	cpy #WIDTH
  	bne draw
  	inc $12		; increment row counter
  	lda #HEIGHT	; are we done yet?
  	cmp $12
  	beq done	; ...exit if we are
  	lda $10		; load pointer
  	clc
  	adc #$20	; add 32 to drop one row
  	sta $10
  	lda $11         ; carry to high byte if needed
  	adc #$00
  	sta $11
  	ldy #$00
  	beq draw
  done:	brk		; stop when finished
  data:                 ; graphic to be displayed
  dcb 00,03,03,00
  dcb 07,00,00,07
  dcb 07,00,00,07
  dcb 00,03,03,00

Etch-a-Sketch™ Style Drawing

 ; zero-page variable locations
 define	ROW		$20	; current row
 define	COL		$21	; current column
 define	POINTER		$10	; ptr: start of row
 define	POINTER_H	$11
 ; constants
 define	DOT		$01	; dot colour
 define	CURSOR		$04	; black colour

 	 	ldy #$00	; put help text on screen
 print:		lda help,y
 		beq setup
 		sta $f000,y
 		iny
 		bne print
 setup:		lda #$0f	; set initial ROW,COL
 		sta ROW
 		sta COL
 draw:		lda ROW		; ensure ROW is in range 0:31
 		and #$1f
 		sta ROW
 		lda COL		; ensure COL is in range 0:31
 		and #$1f
 		sta COL
 		ldy ROW		; load POINTER with start-of-row
 		lda table_low,y
 		sta POINTER
 		lda table_high,y
 		sta POINTER_H
 		ldy COL		; store CURSOR at POINTER plus COL
 		lda #CURSOR
 		sta (POINTER),y
 getkey:		lda $ff		; get a keystroke
 		beq getkey
 		ldx #$00	; clear out the key buffer
 		stx $ff
 		cmp #$43	; handle C or c
 		beq clear
 		cmp #$63
 		beq clear
 		cmp #$80	; if not a cursor key, ignore
 		bmi getkey
 		cmp #$84
 		bpl getkey
 		pha		; save A
 		lda #DOT	; set current position to DOT
 		sta (POINTER),y
 		pla		; restore A
 		cmp #$80	; check key == up
 		bne check1
 		dec ROW		; ... if yes, decrement ROW
 		jmp done
 check1:		cmp #$81	; check key == right
 		bne check2
 		inc COL		; ... if yes, increment COL
 		jmp done
 check2:		cmp #$82	; check if key == down
 		bne check3
 		inc ROW		; ... if yes, increment ROW
 		jmp done
 check3:		cmp #$83	; check if key == left
 		bne done
 		dec COL		; ... if yes, decrement COL
 		clc
 		bcc done
 clear:		lda table_low	; clear the screen
 		sta POINTER
 		lda table_high
 		sta POINTER_H
 		ldy #$00
 		tya
 c_loop:		sta (POINTER),y
 		iny
 		bne c_loop
 		inc POINTER_H
 		ldx POINTER_H
 		cpx #$06
 		bne c_loop
 done:		clc		; repeat
 		bcc draw

 ; these two tables contain the high and low bytes
 ; of the addresses of the start of each row
 table_high:
   dcb $02,$02,$02,$02,$02,$02,$02,$02
   dcb $03,$03,$03,$03,$03,$03,$03,$03
   dcb $04,$04,$04,$04,$04,$04,$04,$04
   dcb $05,$05,$05,$05,$05,$05,$05,$05,
 table_low:
   dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
   dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
   dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
   dcb $00,$20,$40,$60,$80,$a0,$c0,$e0

 ; help message for the character screen
 help:
   dcb "A","r","r","o","w",32,"k","e","y","s"
   dcb 32,"d","r","a","w",32,"/",32,"'","C","'"
   dcb 32,"k","e","y",32,"c","l","e","a","r","s"
   dcb 00

Additional Examples

Additional examples, as well as the source code for the emulator's ROM routines, are in a repository at https://github.com/ctyler/6502js-code