Lab 3 Code:
define POINTER $10
define POINTER_H $11
define ROW_COUNT $13
define ROW $14
define COLUMN $15
define CHECK_LINE $16
define ROWFLIP_FLAG $17
define COLFLIP_FLAG $18
define PTR_CALCULATE $19
define DATA_INDEX $20
define SCREENCOL_INDEX $21
define KEY $22
define WIDTH 5
define HEIGHT 5
lda #$04 ; Set a row value 1f
sta ROW
lda #$04 ; Set a column value 5
sta COLUMN
lda #$00
sta ROWFLIP_FLAG
sta COLFLIP_FLAG
; ====== Calculation ======
; ====== Initialize for calculation ======
cal_initialize:
lda #$00 ; create a pointer at $10
sta POINTER
lda #$02
sta POINTER_H
lda #$00
sta ROW_COUNT
lda #$00
sta PTR_CALCULATE
cmp ROW
beq column_count
bne row_count
;====== row count =======
row_count:
lda PTR_CALCULATE
clc
adc #$20
sta PTR_CALCULATE
lda POINTER_H
adc #$00
sta POINTER_H
inc ROW_COUNT
lda ROW
cmp ROW_COUNT
bne row_count
beq column_count
;===== column_count =====
column_count:
lda PTR_CALCULATE
clc
adc COLUMN
sta PTR_CALCULATE
;===== store the value to pointer (calculation done) =====
sta POINTER
;===== draw graphic =====
; initializing for drawing graph
lda #$00
sta ROW_COUNT
ldx #$00 ; index for data
ldy #$00 ; index for screen column
; draw graph
draw: lda ball,x
sta (POINTER),y
inx
iny
cpy #WIDTH
bne draw
inc ROW_COUNT
lda #HEIGHT
cmp ROW_COUNT
beq getkey_initialize
lda POINTER
clc
adc #$20
sta POINTER
lda POINTER_H
adc #$00
sta POINTER_H
ldy #$00
beq draw
; ======= get key =======
getkey_initialize:
txa
sta DATA_INDEX
tya
sta SCREENCOL_INDEX
getkey: lda $ff ; get a keystroke
ldx #$00 ; clear out the key buffer
stx $ff
cmp #$80 ; if not a cursor key, ignore
bmi getkey_done
cmp #$84
bpl getkey_done
cmp #$80 ; check key == up
bne check1
dec ROW ; ... if yes, decrement ROW
jmp getkey_done
check1:
cmp #$81 ; check key == right
bne check2
inc COLUMN ; ... if yes, increment COL
jmp getkey_done
check2:
cmp #$82 ; check if key == down
bne check3
inc ROW ; ... if yes, increment ROW
jmp getkey_done
check3:
cmp #$83 ; check if key == left
bne getkey_done
dec COLUMN ; ... if yes, decrement COL
clc
bcc getkey_done
getkey_done:
ldx DATA_INDEX
ldy SCREENCOL_INDEX
jmp check_location
; ======= Check the location ======
check_location:
jsr check_top
jsr check_bottom
jsr check_right
jsr check_left
jsr move_pointer
check_initialize:
lda #$00
sta CHECK_LINE
rts
check_top:
jsr check_initialize
lda ROW
cmp #$01
lda CHECK_LINE
adc #$00
cmp #$00
beq flip_rowFlag
rts
check_bottom:
jsr check_initialize
lda ROW
cmp #$1b
lda CHECK_LINE
adc #$00
cmp #$01
beq flip_rowFlag
rts
check_left:
jsr check_initialize
lda COLUMN
cmp #$01
lda CHECK_LINE
adc #$00
cmp #$00
beq flip_colFlag
rts
check_right:
jsr check_initialize
lda COLUMN
cmp #$1b
lda CHECK_LINE
adc #$00
cmp #$01
beq flip_colFlag
rts
; ======= Flip Row Flag ======
flip_rowFlag:
lda ROWFLIP_FLAG
cmp #$00
beq inc_rowFlag
bne dec_rowFlag
rts
inc_rowFlag:
inc ROWFLIP_FLAG
rts
dec_rowFlag:
dec ROWFLIP_FLAG
rts
; ======= Flip Col Flag ======
flip_colFlag:
lda COLFLIP_FLAG
cmp #$00
beq inc_colFlag
bne dec_colFlag
rts
inc_colFlag:
inc COLFLIP_FLAG
rts
dec_colFlag:
dec COLFLIP_FLAG
rts
; ======= move the graph ========
move_pointer:
jsr row_check
jsr col_check
jmp clear
row_check:
lda ROWFLIP_FLAG
cmp #$01
beq dec_row
bne inc_row
col_check:
lda COLFLIP_FLAG
cmp #$01
beq dec_col
bne inc_col
inc_row:
inc ROW
rts
dec_row:
dec ROW
rts
inc_col:
inc COLUMN
rts
dec_col:
dec COLUMN
rts
; ======= move the graph =======
;move: inc ROW
; inc COLUMN
; ======= clear the screen before redraw the graph =====
clear: lda ball
sta POINTER
lda #$02
sta POINTER_H
ldy #$00
tya
clear_loop:
sta (POINTER),y
iny
bne clear_loop
inc POINTER_H
ldx POINTER_H
cpx #$06
bne clear_loop
jsr cal_initialize
; data constant byte
ball:
dcb 00,03,03,03,00
dcb 07,00,00,00,07
dcb 07,00,00,00,07
dcb 07,00,00,00,07
dcb 00,03,03,03,00
The lab we created a shape that will bounce around the screen.
To do this, we created a x/y coordinator location function to locate the screen using X and y:
code:
get_ptr:
lda row
sta counter
start:
lda counter
cmp #$00
beq draw_return
ldy counter
dey
sty counter
lda index
clc
adc #$20
sta index
bcs increase_page
jmp start
draw_return:
clc
lda index
adc col
sta index
lda #$00
clc
clv
sta counter
rts
increase_page:
inc page
jmp start
This function takes col and row as X and Y value. After processed, it stores the pointer that point to the address that is map to the screen pixel to index and page.
By using this function, we are able to locate a pixel on the screen using X and Y coordinator value.
After we can locate a pixel on the screen, we need to make the pixel move around the screen.
Code:
move:
jsr slower
lda x_flag
cmp #$00
bne dec_col
inc col
lda col
cmp #$1a
bne goon
jsr set_x_flag
jmp goon
dec_col:
dec col
lda col
cmp #$00
bne goon
jsr clr_x_flag
jmp goon
goon:
lda y_flag
cmp #$00
bne dec_row
inc row
lda row
cmp #$1a
bne done_mv
jsr set_y_flag
jmp done_mv
dec_row:
dec row
lda row
cmp #$00
bne done_mv
jsr clr_y_flag
jmp done_mv
done_mv:
jsr backup_ptr
jsr reset_ptr
jsr get_ptr
jsr clr_px_at_backup_ptr
lda #$00
sta row_counter
ldy #$00
ldx #$00
lda page
sta draw_page
lda index
sta draw_index
jsr draw
jmp move
brk
This function simply increase or decrease the X and Y value. We have 2 indicators to indicate if the X or Y needs to be increased or decreased. After the pixel reaches the edge of the screen, we reverse the indicators
After we got this 2 functions, we almost got the lab!
We just draw the shape from pixel, then clear the screen, and move the pixel, then draw it again. finally, we got the code that we have at the beginning of the blog