In Part 1 we looked at making an adder in 6502 assembly, this was one of the two tasks we chose for this lab, the other was a screen colour selector. The screen colour selector I personally found was a lot easier to code than the adder and took far lass code to implement. So without any delay here is the whole source code before we dive in to how it works.
; 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:
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:
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
This code, similar to the code in pt. 1 uses a main loop as the body of the program, though this one is a bit different and also isn't named main. Though this is getting ahead of ourselves the first thing the program does is initialize the screen, it does this by going through the colour names which are stored in memory and printing them to the screen, which was fairly easy to do considering the ROM routine CHROUT can read newline properly allowing the whole thing to be one block of memory.
The main loop for this program is called checkIn, this loop is checking for an input and when it receives it updates the screen accordingly, both up and down inputs work about the same so let's just look at up. When the up arrow in pressed checkIn calls the subroutine up. This subroutine will then check if up is valid (ie: not the top of the screen) and if so it will remove the selection, then select the proper line before changing the screen colour then returning to the checkIn loop.
Now of course up and down both call their own subroutines which I will explain now. flipSelect is a pretty interesting subroutine, it simply flips the high bit of every character in whatever line is in y. which will be the currently selected line. So the first time it is called it flips it off to deselect the line, then the second time it is called it flips it on selecting the new line. The drawScreen subroutine is one we have used a lot in the course so far. It simply takes what is currently in y, as established this will be the current selected element, and it will fill the screen with that colour. We made sure to align the colours on the screen with their places in memory so their y values line up with their colour values. This results in the correct colour being displayed
putting these few simple subroutines together along with the Rom routines and we have a very compact and easy to understand bit of code which can allow you to select a colour and display it on the screen.
No comments:
Post a Comment