This week's lab started with us giving a quiz. We were all a bit surprised as we did not expect it but it turned out to be just fine in the end since it was just matching and there were no short or long questions to answer. Rest of the lab was given to us to figure out more about lab 3 and work on it.
We still did not have much to end the lab with so we decided and talked to professor a bit more about it and understanding it in more detail.
After much discussions finally we were able to incorporate everything we know and combined declare constant byte's knowledge to get rid of multiplication, used delay loop that would keep counting as necessary to give us necessary delay to give an effect of moving, incremented rows and columns accordingly to direct the graphic and finally filled the display with black color where the graphic is no longer there. Here is the full code for this lab:
; zero-page variable locations
define ROW $20 ; current row
define COL $21 ; current column
define POINTER $10 ; ptr: start of row - upper left corner of object
define POINTER_H $11
define WPOINTER $12 ; ptr: start of row - write pointer
define WPOINTER_H $13
define BOUNCE_X $14
define BOUNCE_Y $15
define ROW_COUNT $16
define TIMER $17 ; ptr: delay timer
define TIMER_H $18
define TIMER_CONTROL $19 ; contains the base of the high bit of the timer
; constants
define WIDTH 7 ; width of graphic
define HEIGHT 7 ; height of graphic
define GREEN $05 ; GREEN
define BLUE $03 ; BLUE
define BLACK $00 ; BLACK
define RIGHT $19 ; defining where the graphic must change direction accounting for its size
define LEFT $00 ;
define TOP $00 ;
define BOTTOM $19 ;
lda #$0 ; initialize delay loop counter
sta TIMER
sta TIMER_H
lda #$40 ; setting the initial speed of the timer
sta TIMER_CONTROL
lda #$01 ; assume that the object is moving across the screen
sta BOUNCE_Y ; contain the rate motion of the box along the Y axis
lda #$01
sta BOUNCE_X ; contain the rate motion of the box along the X axis
lda #$03 ;setting were object starts on screen
sta ROW
lda #$06
sta COL
loop:
clc
ldy ROW ; load POINTER with start-of-row
lda table_low,y
adc COL
sta WPOINTER
lda table_high,y
sta WPOINTER_H
lda #$00 ; number of rows we've drawn
sta ROW_COUNT
ldx #$00 ; index for data
ldy #$00 ; index for screen column
draw: ; draws graphic
lda data,x ; set up where graphic starts on sreen
sta (WPOINTER),y
inx
iny
cpy #WIDTH
bne draw
inc ROW_COUNT ; increment row counter
lda #HEIGHT ; end of graphic by height
cmp ROW_COUNT
beq done ; exit
lda WPOINTER ; load pointer
clc
adc #$20 ; add 32 to drop one row
sta WPOINTER
lda WPOINTER_H ; carry to high byte if needed
adc #$00
sta WPOINTER_H
ldy #$00
beq draw
done:
lda TIMER_CONTROL ; initialize timer with current speed
sta TIMER_H
delay: dec TIMER ; wait
bne delay
dec TIMER_H
bne delay
clc
ldy ROW ; load POINTER with start-of-row
lda table_low,y
adc COL
sta WPOINTER
lda table_high,y
sta WPOINTER_H
lda #$00 ; number of rows we've drawn
sta ROW_COUNT
ldx #$00 ; index for data
ldy #$00 ; index for screen column
wdraw: ; remove graphic were it has been draw
lda #BLACK
sta (WPOINTER),y
inx
iny
cpy #WIDTH
bne wdraw
inc ROW_COUNT ; increment row counter
lda #HEIGHT
cmp ROW_COUNT
beq wdone ; exit
lda WPOINTER ; load pointer
clc
adc #$20 ; add 32 to drop one row
sta WPOINTER
lda WPOINTER_H ; carry to high byte if needed
adc #$00
sta WPOINTER_H
ldy #$00
beq wdraw
wdone: ; check graphic if hitting a sides and if so change direction
clc
lda COL
adc BOUNCE_X
sta COL
cmp #RIGHT
bne no_bounce
pha
lda #$ff ; using the fact that the register overflows adding ff is the same as subtracting 1
sta BOUNCE_X
pla
no_bounce:
cmp #LEFT
bne no_bounce1
lda #$01
sta BOUNCE_X
no_bounce1:
clc
lda ROW
adc BOUNCE_Y
sta ROW
cmp #BOTTOM
bne no_bounce2
pha
lda #$ff
sta BOUNCE_Y
pla
no_bounce2:
cmp #TOP
bne no_bounce3
lda #$01
sta BOUNCE_Y
no_bounce3:
getkey:
lda $ff ; get a keystroke
ldx #$00 ; clear out the key buffer
stx $ff
cmp #$2d ; is it a minus
bne check
clc ; slow down timer
lda TIMER_CONTROL
adc #$01 ; changing speed of timer by adding to the timer
bcs ignore
sta TIMER_CONTROL
ignore:
jmp move_it
check:
cmp #$2b ; is it a plus
bne check0
sec ; speed up timer
lda TIMER_CONTROL
sbc #$01 ; changing speed of timer by subtracting from the timer
beq ignore
sta TIMER_CONTROL
jmp move_it
check0:
cmp #$80 ; check key == up
bne check1
sec
lda ROW ; ... if yes, decrement ROW
sbc #$01
beq ignore
sta ROW
jmp move_it
check1:
cmp #$81 ; check key == right
bne check2
lda COL ; ... if yes, increment COL
adc #$01
cmp #RIGHT
beq ignore
sta COL
jmp move_it
check2:
cmp #$82 ; check if key == down
bne check3
lda ROW ; ... if yes, increment ROW
adc #$01
cmp #BOTTOM
beq ignore
sta ROW
jmp move_it
check3:
cmp #$83 ; check if key == left
bne move_it
sec
lda COL ; ... if yes, decrement COL
sbc #$01
beq ignore
sta COL
bcc move_it
move_it:
jmp loop
data: ; for the graphic
dcb 00,03,03,03,03,03,00
dcb 03,02,03,03,03,02,03
dcb 03,03,03,03,03,03,03
dcb 03,03,03,03,03,03,03
dcb 03,02,03,03,03,02,03
dcb 03,03,02,02,02,03,03
dcb 00,03,03,03,03,03,00
; 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