top of page

Lab 4 - 6502 Assembly Language String

For this lab, we had to pick 2 out of 4 options which will make us practice the ROM routines. Option 1 is a calculator, option 2 is getting data input, option 3 is hexdump and option 4 is a screen colour selector. Also, you can test all this code using our class emulator http://6502.cdot.systems/


We used some of the ROM routines that were provided for us in one of the class lecture notes:


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
Our group decided to choose Option 1 and Option 4 which you will see the following results:

We can access those routines by using jsr CHROUT


Before starting this lab we took a look into some code examples to try and understand how to begin this lab and get our hands-on. There are several examples using ROM routines on our school wiki that you can find here. We started with this simple example on how to display characters on the screen 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
          ldy #$00

char:     lda text,y
          beq done
          jsr CHROUT
          iny
          bne char

done:     brk

text:
dcb "6","5","0","2",32,"w","a","s",32,"h","e","r","e",".",00

My team decided to choose the following:


Option 1: Adding Calculator


; 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

define        NUMBERA        $10;
define        NUMBERB        $20;

        jsr SCINIT
   
mainLoop:
    ldy #$00
    jsr char1
    jsr input
    jsr storeA
    ldy #$00
    jsr char2
    jsr input
    jsr storeB
    ldy #$00
    jsr charR
    jsr printAdd
    jmp mainLoop
   

input:      ; get user input
    SEC
    jsr PLOT
    ldx #$15
    CLC
    jsr PLOT

   

inLoop:
    SEC
    jsr PLOT
    jsr CHRIN


charCheck:   
    cmp #$00
    beq inLoop

    cmp #$81
    beq right
   
    cmp #$83
    beq left

    cmp #$0d
    beq next

drawNum:
    cmp #$30
    bcc inLoop
   
    clc
    cmp #$3a
    bcs inLoop
   
    jsr CHROUT

    SEC
    jsr PLOT
    cpx #$17
    bne inLoop
    dex
    CLC
    jsr PLOT
    jmp inLoop


left:    cpx #$15
    beq inLoop
    jsr CHROUT
    jmp inLoop

right:    cpx #$16
    beq inLoop
    jsr CHROUT
    jmp inLoop

next:
    SEC
    jsr PLOT
    ldx #$15
    CLC
    jsr PLOT
    SEC
    jsr PLOT


    CLC
    SBC #$2F

    ASL
    ASL
    ASL
    ASL

    PHA
   

    ldx #$16
    CLC
    jsr PLOT
    SEC
    jsr PLOT

    CLC
    SBC #$2F
    PHA

    ldx #$00
    iny
    CLC
    jsr PLOT
    SEC
    jsr PLOT

    PLA
    TAX
    PLA


    rts

storeA:
    sta NUMBERA
    txa
    eor NUMBERA
    sta NUMBERA
    rts
   

storeB:
    sta NUMBERB
    txa
    eor NUMBERB
    sta NUMBERB
    rts

printAdd:     ; add both numbers 
    SEC
    jsr PLOT
    ldx #$15
    CLC
    jsr PLOT
    SEC
    jsr PLOT
   
    SED
    lda NUMBERA
    adc NUMBERB
    CLD
    pha

    bcc outputAddition
    ldx #$14
    CLC
    jsr PLOT
    SEC
    jsr PLOT
    lda #$31
    jsr CHROUT
   
outputAddition:
    pla
    pha
    LSR
    LSR
    LSR
    LSR
    clc
    adc #$30
    jsr CHROUT

    pla
    and #$0F
    clc
    adc #$30
    jsr CHROUT

    SEC
    jsr PLOT
    ldx #$00
    iny
    CLC
    jsr PLOT
   
    rts

char1:  lda firstDigit,y
        beq charRet
        jsr CHROUT
        iny
        bne char1

char2:  lda secondDigit,y
        beq charRet
        jsr CHROUT
        iny
        bne char2

charR:  lda result,y
        beq charRet
        jsr CHROUT
        iny
        bne charR

charRet:
    rts



firstDigit:
dcb "E","N","T","E","R",32,"F","I","R","S","T",32,"D","I","G","I","T",":",32,32,32,"0","0"
dcb 00


secondDigit:
dcb "E","N","T","E","R",32,"S","E","C","O","N","D",32,"D","I","G","I","T",":",32,32,"0","0"
dcb 00

result:
dcb "R","E","S","U","L","T",":"
dcb 00

This option gave us a lot of problems at the beginning of the program because we were stuck on how to make this to just accept only 2 numbers, at the beginning we got it working to accept just numbers but then we got stuck into getting it for 2 digits number.


The most important part of this option CHROUT, CHRIN and PLOT. With CHROUT we checking the accumulator for the value and then putting it at the current cursor location which is a compliment of the CHRIN which takes the character input. On the other hand with PLOT, these routine have two functions depending on the carry flag. One of them is getting the current cursor position and returning the value or it can set the current cursor position based on what it is on x and y.


Option 4: Screen Colour Selector


; 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
        ldy #$00

initColours:
    lda colours,y
        beq doneInit
        jsr CHROUT
        iny
        bne initColours
doneInit:
    ldy #$00
    ldx #$00
    CLC
    jsr PLOT

    SEC
    jsr PLOT
    jsr flipSelect
   


checkIn:    ;check for input and update
    SEC
    jsr PLOT
    jsr CHRIN

    cmp #$80
    beq up
    cmp #$82
    bne checkIn
down:
    cpy #$0f
    beq checkIn
    jsr flipSelect
    iny
    jsr flipSelect
    jsr drawScreen
    jmp checkIn

up:    ;check if valid
    cpy #$00
    beq checkIn
    jsr flipSelect
    dey
    jsr flipSelect
    jsr drawScreen
    jmp checkIn
   

flipSelect:
    ldx #$00
    CLC
    jsr PLOT
    SEC
    jsr PLOT
   
flipLoop:
    cmp #$20
    beq doneFlip
    eor #$80
    jsr CHROUT
    SEC
    jsr PLOT
    clc
    bcc flipLoop
   
doneFlip:
    rts

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

drawLoop:
    sta ($10),y  ; store colour
        iny          ; increment index
        bne drawLoop ; branch until page done
     
        inc $11      ; increment high byte of pointer
        cpx $11      ; compare with max value
        bne drawLoop ; continue if not done

    rts
     

colours:
dcb "B","L","A","C","K",10
dcb "W","H","I","T","E",10
dcb "R","E","D",10
dcb "C","Y","A","N",10
dcb "P","U","R","P","L","E",10
dcb "G","R","E","E","N",10
dcb "B","L","U","E",10
dcb "Y","E","L","L","O","W",10
dcb "O","R","A","N","G","E",10
dcb "B","R","O","W","N",10
dcb "L","I","G","H","T",95,"R","E","D",10
dcb "D","A","R","K",95,"G","R","E","Y",10
dcb "G","R","E","Y",10
dcb "L","I","G","H","T",95,"G","R","E","E","N",10
dcb "L","I","G","H","T",95,"B","L","U","E",10
dcb "L","I","G","H","T",95,"G","R","E","Y",00

We initialize the screen first so we can see the colour names which are sore in memory and then printing them on the screen, this was done by using the CHROUT ROM routine.


Personal Note:

This lab took time for me to upload because I was more focused on my other courses, but overall it was a fun lab to do with my other teammates and it allows us to explore more about ROM routines and how it makes the code a little bit easier to do. Also, this lab allows us to explore more about 6502 assembly language by making it put into practice what we had learned so far with the other labs which are a fun challenging experience.


bottom of page