Lab 4 (6502 Assembly Language String Lab) - Option 4: Screen Colour Selector

Introduction
For lab 4, I can choose two options among four options. My team chose the first and fourth options which are adding calculator and screen colour selector. This post is for the fourth option "Screen Colour Selector". The instruction of option 4 is written below.

Option 4: Screen Colour Selector Instruction
  1. 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 names of the colours highlighted in reverse video (white on 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 (A) register when they press Enter.
  2. 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.

1. Design
1.1. Pseudo Code
  1. Initialize values
  2. get the key (up/down key)
  3. check whether the colour needs to be increased or decreased (compare the colour to #$00 (the first value) or #$0a (the last value))
  4. print the characters on the screen
  5. compare the value and check what option needs to be highlighted
  6. paint the bit-mapped screen with the selected colour
  7. go back to step 2 and repeat it
1.2. variables
SCINIT                   $ff81
CHROUT               $ffd2
COLOUR               $10
COLOUR_INDEX  $11
POINTER              $40
POINTER_H         $41
UP_KEY                $80
DOWN_KEY          $82

1.3. Subroutines
  • getKey: get the up/down key. When the user presses up/down key, it starts decrement_key or increment_key subroutine
  • decrement_key: compare the previous selected colour value with #$01. When the previous selected colour is #$00, nothing happens and go back to the getKey subroutine. When it is not #$00, go to the decrement_colour subroutine
  • decrement_colour: decrement colour value and go to the initialize_print subroutine
  • increment_key: compare the previous selected colour value with #$0f. When the previous selected colour is #$0f, nothing happens and go back to the getKey subroutine. When it is not #$00, go to the increment_colour subroutine
  • increment_colour: increment colour value and go to the initialize_print subroutine
  • initialize_print: use SCINIT and initialize y value to 0
  • title_write: write the title (Colours)
  • title_done: initialize COLOUR_INDEX to #$00
  • write_colourStart: turn off the highlight and set the y index to #$00
  • write_colourName: print characters on the screen (title and select menus option)
  • write_done: increment COLOUR_INDEX and load COLOUR_INDEX value to the accumulator. When COLUR_INDEX is not #$10, go to the subroutine write_colourStart
  • select_colour
  • toggle_highlight: when the value of COLOUR and COLOUR_INDEX are same, highlight it
  • highlight: ora #$80
2. Implementation
Whole Code
; ======= ROM routines ======
define SCINIT $ff81 ; initialize/clear screen
define CHROUT $ffd2 ; output character to screen

; ======= 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 initialize_print

; ======== get key input =====
getKey:
lda $ff
sty $ff

cmp #UP_KEY
beq decrement_key

cmp #DOWN_KEY 
beq increment_key

jmp getKey

decrement_key:
lda COLOUR
cmp #$01
bpl decrement_colour

jmp getKey

decrement_colour:
dec COLOUR

jsr initialize_print
jsr initialize_paint
jmp getKey

increment_key:
lda COLOUR
cmp #$0f
bmi increment_colour

jmp getKey

increment_colour:
inc COLOUR
jsr initialize_print
jsr initialize_paint
jmp getKey

; ======= print screen =====
initialize_print:
jsr SCINIT
        ldy #$00

title_write:
lda title,y
        beq title_done
        jsr CHROUT
        iny
        bne title_write

title_done:
lda #$00
sta COLOUR_INDEX

write_colourStart:
ora #$00
ldy #$00

write_colourName:
jsr select_colour
beq write_done
jsr toggle_highlight

jsr CHROUT

iny
bne write_colourName

write_done:
inc COLOUR_INDEX
lda COLOUR_INDEX
cmp #$10
bne write_colourStart

select_colour:
lda COLOUR_INDEX

cmp #$00
beq print_colour0

cmp #$01
beq print_colour1

cmp #$02
beq print_colour2

cmp #$03
beq print_colour3

cmp #$04
beq print_colour4

cmp #$05
beq print_colour5

cmp #$06
beq print_colour6

cmp #$07
beq print_colour7

cmp #$08
beq print_colour8

cmp #$09
beq print_colour9

cmp #$0a
beq print_colour10

cmp #$0b
beq print_colour11

cmp #$0c
beq print_colour12

cmp #$0d
beq print_colour13

cmp #$0e
beq print_colour14

cmp #$0f
beq print_colour15

rts

print_colour0:
lda colour0,y
rts

print_colour1:
lda colour1,y
rts

print_colour2:
lda colour2,y
rts

print_colour3:
lda colour3,y
rts

print_colour4:
lda colour4,y
rts

print_colour5:
lda colour5,y
rts

print_colour6:
lda colour6,y
rts

print_colour7:
lda colour7,y
rts

print_colour8:
lda colour8,y
rts

print_colour9:
lda colour9,y
rts

print_colour10:
lda colour10,y
rts

print_colour11:
lda colour11,y
rts

print_colour12:
lda colour12,y
rts

print_colour13:
lda colour13,y
rts

print_colour14:
lda colour14,y
rts

print_colour15: 
lda colour15,y
rts

toggle_highlight:
ldx COLOUR_INDEX
cpx COLOUR
beq highlight

ora #$00
rts

highlight:
ora #$80
rts

; ======= Screen Paint =====
; ======= Initialize =====
initialize_paint:
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

; ========= for screen printing =========
title:
dcb "C","o","l","o","u","r","s",13,00

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

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

colour2:
dcb "2",".",32,"R","e","d",13,00

colour3:
dcb "3",".",32,"C","y","a","n",13,00

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

colour5:
dcb "5",".",32","G","r","e","e","n",13,00

colour6:
dcb "6",".",32,"B","l","u","e",13,00

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

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

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

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

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

colour12:
dcb "1","2",".",32,"G","r","e","y",13,00

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

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

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

3. What I have learned from this lab
It was hard to figure out how should I treat the string in assembly language. Thinking about the logic for this lab was simple but figuring out the way of using ROM, input and output key, and highlight the characters took a long time. It was fun but also overwhelming.

Comments

Popular posts from this blog

Open Source Project: Lab2 (Pull Request)

Release 4.0 - Part 3: Release

Lab 8: Automated Testing and Continuous Integration