Difference between revisions of "6502 Emulator Example Code"

From CDOT Wiki
Jump to: navigation, search
(Place a Graphic on the Screen)
(Place a Graphic on the Screen)
Line 121: Line 121:
 
   dcb 07,00,00,07
 
   dcb 07,00,00,07
 
   dcb 00,03,03,00
 
   dcb 00,03,03,00
 +
 +
== Etch-a-Sketch<sup>tm</sup> 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
 +
 
 +
  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 on 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

Revision as of 10:03, 10 January 2020

This is a collection of simple examples of 6502 code which will run in the emulator.

Fill the Bitmapped Display

      lda #$00     ; set pointer at $10 to $0200
      sta $10
      lda #$02
      sta $11
      
      ldx #$06     ; max value for $11
      
      ldy #$00     ; index

loop: sta ($10),y  ; store colour
      iny          ; increment index
      bne loop     ; branch until overflow
      
      inc $11      ; increment hi byte of pointer
      lda $11      ; load page number as colour
      cpx $11      ; compare with max value
      bne loop     ; continue if not done 
      
      rts          ; return

Place a Message on the Character Display

 define SCREEN $f000
           ldy #$00
 
 char:     lda text,y
           beq done
           sta SCREEN,y
           iny
           bne char
 
 con e:    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!
; 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:
 dcb 00,03,03,00
 dcb 07,00,00,07
 dcb 07,00,00,07
 dcb 00,03,03,00

Etch-a-Sketchtm 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
 
 	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 on 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