Lab3 Bouncing Graphic (Part I)
Tags: assembly, spo600, 6502emulator, math
Published: 2021-10-31 03:06:22

## Lab3 Overview 
This lab is to prepare for learning more complex x86_64 and AArch64 assembly language, by writing code with arithmetic/math in **6502 assembly language**.

The option I chose is bouncing graphic. It requires several techniques, including placing a graphic on the screen, bouncing an object around the screen and detecting when the object has collided with the edge of the screen or other objects. 

The instructions and requirements of this lab are:
- 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.
- Encode that graphic in bytes using DCB (declare constant byte) instructions.
- 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.
- Make the speed keyboard-adjustable (faster/slower) and perturb the object's path once in a while (add a glitch - adjust the angle or nudge the obect by a pixel at random intervals).

Challenge: randomize the starting position, and make the object bounce at angles other than 45 degrees.

Initially, the program should begin with a start position (pointer) and using x & y variable (columns and rows) to direct the graphic. To simplify the process and focus on the main process, the graphic I chose for this lab is a ball. 

However, in this part, let's focus on variables declaration and pointer location calculation. Therefore, it can be decided the pointer is located on which page.

The code can be found here:

```6502Assembly
define POINTER      $10
define POINTER_H    $11
define ROW          $14
define ROW_COUNT    $13
define ROW_STORE    $16

define COLUMN       $15

lda #$00  
sta POINTER
lda #$02
sta POINTER_H

lda  #$1f ; initialize row, col
sta ROW
lda #$00  
sta COLUMN

;calcualte pointer, detect on which page, branch by page

calculatePtr:
 cmp #$03  ; compare POINTER_H value with #$03. If it is equal, then it is on the 2nd page
 beq page2  ; If POINTER_H is #$03, go to subroutine page2, using branch on equal

 cmp #$04  ; compare POINTER_H value with #$04. If it is equal, then it is on the 3rd page
 beq page3  ; If POINTER_H is #$04, go to page3 subroutine
 
 cmp #$05  ; compare POINTER_H value with #$05. If it is equal, it means it is on the 4th page
 beq page4  ; If POINTER_H is #$05, go to page4 subroutine

 bne count_initialize ; not equal, then set row count and col count

;page 2 
; Subtract #$08 to ROW value to count the location in the second page
page2: lda ROW
 sec
 sbc #$08
 cmp ROW
 beq count_initialize ; on this page, start initialize

; page 3 
; Subtract #$10 to ROW value to count the location in the third page
page3: lda ROW
 sec
 sbc #$10
 cmp ROW
 beq count_initialize

; page 4 
; Subtract #$18 to ROW value to count the location in the fourth page
page4: lda ROW
 sec
 sbc #$18
 cmp ROW
 beq count_initialize


;count_initialize 
; initialize ROW_COUNT for row count
count_initialize:
 lda #$00
 sta ROW_COUNT
 pha        ; push accumulator

 cmp #$00
 beq row_count


;row_count 
; Add #$20 until ROW value and ROW_COUNT value is equal
row_count:    
 lda ROW
 cmp ROW_COUNT
 beq column_count   ; once row count is set, define col

 pla
 clc
 adc #$20
 pha
 inc ROW_COUNT
 lda ROW
 cmp ROW_COUNT
 bne row_count

;column_count
column_count:
 pla  
 clc
 adc COLUMN

;store the value to pointer (calculation done)
 sta POINTER

; reset the original ROW value from ROW_STORE
 lda ROW_STORE
 sta ROW

; draw a dot on the pointer location 
 lda #$07

 ldy #$00

 sta (POINTER), y ;
```

Through this lab, I have learned more instructions and code examples, the idea of branching and stack (pull and push stack), and using `clc` (clear carry flag) together with `adc` .

Learning low-level assembly language is very challenging and the overall experience is very different from learning high-level language. With more instructions and techniques learnt, the big picture can be confusing when I am focusing on the details.

This part is more like an experimental and explorative part to get myself more familiar with the functions, branches, instructions and memory locations in 6502 assembly language.