Monday, February 10, 2020

Lab3 - Bouncing Grapic final version.



This is the final version of the Lab3.


Guide Line of Lab3
  1. Create a simple graphic in a square that is 5x5 or 7x7 pixels in size. Use the colours available in the emulator's bitmapped display. The graphic could be a ball, a happy face, a logo, an emoji, or anything else (appropriate!) that you want to use.
  2. Encode that graphic in bytes using DCB (declare constant byte) instructions.
  3. Write code to make the graphic bounce around the screen, reflecting off the edges when it hits. Note: for simplicity, it is OK if the object always bounces at 45-degree angles.
  4. Make the speed keyboard-adjustable (faster/slower) and perturb the object's path once in a while.
Challenge: randomize the starting position, and make the object bounce at angles other than 45 degrees.

This is Lab3 final code.

; define
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

; variables for key
define UP $80 
define DOWN $82
define RIGHT $81
define LEFT $83

; variable for last line check
define LASTLINE $23

; variables for graph
define  WIDTH   7
define  HEIGHT   7

; ======= base initialize ======
   lda    #$00 ; Set a row value
   sta   ROW
   lda   #$00  ; Set a column value
   sta   COLUMN

lda  #$00 
  sta  ROWFLIP_FLAG
  sta  COLFLIP_FLAG 

; last line check calculation
lda #$20
sec
sbc #WIDTH
sta LASTLINE

; ====== 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   #UP   ; check key == up
   bne   rightKey_check

   jsr rowPointCheck_dec   ; ... if yes, decrement ROW
   jmp   getkey_done

 rightKey_check: 
  cmp   #RIGHT   ; check key == right
   bne   downKey_check

   jsr colPointCheck_inc  ; ... if yes, increment COL
   jmp   getkey_done

 downKey_check: 
  cmp   #DOWN   ; check if key == down 
   bne   leftKey_check

   jsr rowPointCheck_inc   ; ... if yes, increment ROW
   jmp   getkey_done
  
 leftKey_check: 
  cmp   #LEFT   ; check if key == left
   bne   getkey_done

   jsr colPointCheck_dec ; ... 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  LASTLINE
  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  LASTLINE
  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  rowPointCheck_dec
  bne  rowPointCheck_inc

col_check:
  lda  COLFLIP_FLAG
  cmp  #$01 
  beq  colPointCheck_dec
  bne  colPointCheck_inc

rowPointCheck_inc:
lda ROW
cmp LASTLINE
bne inc_row 
  rts

inc_row:
inc ROW
rts

rowPointCheck_dec:
lda ROW
cmp #$00
bne dec_row
  rts

dec_row:
dec ROW
rts

colPointCheck_inc:
lda COLUMN
cmp LASTLINE
bne inc_col
rts

inc_col:
  inc  COLUMN
  rts

colPointCheck_dec:
  lda  COLUMN 
cmp #$00 
bne dec_col
  rts

dec_col:
dec COLUMN
rts

; ======= 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,03,03,00
  dcb 03,06,07,07,07,06,03
  dcb 03,06,07,07,07,06,03
  dcb 03,07,07,07,07,07,03
dcb 03,07,06,07,06,07,03
dcb 03,07,07,06,07,07,03
  dcb 00,03,03,03,03,03,00

No comments:

Post a Comment