SPO600 - Lab 4 - Option 2
Tags: beginners, opensource
Published: 2021-11-04 20:39:22

In order to continue with the [last lab](https://dev.to/tcvan0707/spo600-lab-4-option-1-2omi), this time I choose another option to implement, which is **Screen Colour Selector**.

##Instruction
* Create a subroutine which displays on the character display a list of colours available on the bitmapped display, one colour per line, with one of the colours names highlighted in reverse (white or black). The user may use the up/down arrow keys to change the highlighted row. Return the user's selection as a number in the accumulator register when they press Enter.
* Using this subroutine, get a colour from the user, then fill the bitmap display with this colour, and allow the user to select a different colour.

##Program
```
; ROM ROUTINES
define SCINIT  $ff81 ; initialize/clear screen
define CHROUT  $ffd2 ; output character to screen

; DECLARES VARIABLES
define COLOUR  $10
define COLOUR_INDEX $11
define POINTER  $40
define POINTER_H $41
define UP_KEY  $80
define DOWN_KEY $82

; BASE INITIALIZE
  lda #$00 
 sta COLOUR
 sta COLOUR_INDEX 

 jsr initializePrint

; GET INPUT BY UP/DOWN ARROW KEYS
getKey:
 lda $ff
 sty $ff

 cmp #UP_KEY
 beq decrementKey

 cmp #DOWN_KEY 
 beq incrementKey

 jmp getKey

decrementKey:
 lda COLOUR
 cmp #$01
 bpl decrementColour

 jmp getKey

decrementColour:
 dec COLOUR
 
 jsr initializePrint
 jsr initializePaint
 jmp getKey

incrementKey:
 lda COLOUR
 cmp #$0f
 bmi incrementColour

 jmp getKey

incrementColour:
 inc COLOUR
 jsr initializePrint
 jsr initializePaint
 jmp getKey

; PRINT OUT SCREEN
initializePrint:
 jsr SCINIT
        ldy #$00

writeTitle:
 lda title,y
        beq titleDone
        jsr CHROUT
        iny
        bne writeTitle

titleDone:
 lda #$00
 sta COLOUR_INDEX

startColour:
 ora #$00
 ldy #$00

colourName:
 jsr selectedColour
 beq afterWriting
 jsr highlightLine

 jsr CHROUT

 iny
 bne colourName

afterWriting:
 inc COLOUR_INDEX
 lda COLOUR_INDEX
 cmp #$10
 bne startColour

selectedColour:
 lda COLOUR_INDEX
 
 cmp #$00
 beq printColour0

 cmp #$01
 beq printColour1

 cmp #$02
 beq printColour2

 cmp #$03
 beq printColour3

 cmp #$04
 beq printColour4

 cmp #$05
 beq printColour5

 cmp #$06
 beq printColour6

 cmp #$07
 beq printColour7

 cmp #$08
 beq printColour8

 cmp #$09
 beq printColour9

 cmp #$0a
 beq printColour10

 cmp #$0b
 beq printColour11

 cmp #$0c
 beq printColour12

 cmp #$0d
 beq printColour13

 cmp #$0e
 beq printColour14

 cmp #$0f
 beq printColour15

 rts

printColour0:
 lda colour0,y
 rts

printColour1:
 lda colour1,y
 rts

printColour2:
 lda colour2,y
 rts

printColour3:
 lda colour3,y
 rts

printColour4:
 lda colour4,y
 rts

printColour5:
 lda colour5,y
 rts

printColour6:
 lda colour6,y
 rts

printColour7:
 lda colour7,y
 rts

printColour8:
 lda colour8,y
 rts

printColour9:
 lda colour9,y
 rts

printColour10:
 lda colour10,y
 rts

printColour11:
 lda colour11,y
 rts

printColour12:
 lda colour12,y
 rts

printColour13:
 lda colour13,y
 rts

printColour14:
 lda colour14,y
 rts

printColour15: 
 lda colour15,y
 rts

highlightLine:
 ldx COLOUR_INDEX
 cpx COLOUR
 beq highlight

 ora #$00
 rts

highlight:
 ora #$80
 rts

; CHANGE THE COLOUR OF THE BITMAP
initializePaint:
 lda #$00         ; set a pointer at $40 to point to $0200
        sta POINTER
        lda #$02
        sta POINTER_H
 
 ldy #$00

 lda COLOUR

draw_screen:
  sta ($40), y     ; set pixel

        iny              ; increment index
        bne draw_screen  ; continue until done the page

        inc $41          ; increment the page
        ldx $41          ; get the page
        cpx #$06         ; compare with 6
        bne draw_screen  ; continue until done all pages

 rts

; LIST OF COLOURS DIPLAYS ON SCREEN
title:
dcb "L","i","s","t",32,"o","f",32,"C","o","l","o","u","r","s",":",13
dcb 00

colour0:
dcb "B","l","a","c","k",13
dcb 00

colour1:
dcb "W","h","i","t","e",13
dcb 00

colour2:
dcb "R","e","d",13
dcb 00

colour3:
dcb "C","y","a","n",13
dcb 00

colour4:
dcb "P","u","r","p","l","e",13
dcb 00

colour5:
dcb "G","r","e","e","n",13
dcb 00

colour6:
dcb "B","l","u","e",13
dcb 00

colour7:
dcb "Y","e","l","l","o","w",13
dcb 00

colour8:
dcb "O","r","a","n","g","e",13
dcb 00

colour9:
dcb "B","r","o","w","n",13
dcb 00

colour10:
dcb "L","i","g","h","t",32,"r","e","d",13
dcb 00

colour11:
dcb "D","a","r","k",32,"g","r","e","y",13
dcb 00

colour12:
dcb "G","r","e","y",13
dcb 00

colour13:
dcb "L","i","g","h","t",32,"g","r","e","e","n",13
dcb 00

colour14:
dcb "L","i","g","h","t",32,"b","l","u","e",13
dcb 00

colour15:
dcb "L","i","g","h","t",32,"g","r","e","y",13
dcb 00

```
##What I have learned from this lab?
I realize that it is not easy to work with string in Assembly Language. I have encountered a lots of errors when working with string as well as sub routines. Finally, I have come up with my program, even though not exactly as I expected, but I am happy because it works.