Lab3 Bouncing Graphic/Ball (Part II)
Tags: assembly, spo600, 6502emulator, math
Published: 2021-10-31 04:58:28

## 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. 

 
At this stage, I am getting more clear of the whole process:

- Initialize ROW and COLUMN (x, y) in a certain position on certain page of 6502 simulator.
- Calculate the pointer 
- Draw the ball on the bit-mapped output (width 5 and height 5)
- moving the ball along 45 degree angle (initially on diagonal)
- Check the keystroke. If the key is up, down, right, or left, change the value of ROW or COLUMN  (response to arrow keys on keyboard)
- Check the pointer is on the edge, if so, flip the flag for ROW or COLUMN
- Clear the screen the redraw the graphic (bouncing back)
- Restart from step 2

In the previous [part](https://dev.to/qiwenyu/lab3-bouncing-graphic-part-i-27lg), I mainly worked on the step 1 and step 2. The previous one is not working very well and more like an explorative one. 

From now on, I will try to draw a ball first and bounce the ball at 45 degree angle to simplify the process. A width and height variable should be defined to draw the ball. The "hits-edge" functionality and "arrow key response" functionality will be implemented later on.

The main idea of this code is to get the ball to move.

Code: 
```
define WIDTH   5
define HEIGHT  5

define  POINTER    $10 
define  POINTER_H  $11 
define  ROW_COUNT  $13
define  ROW        $14
define  COLUMN     $15 
define  PTR_CALCULATE $19



lda  #$04          
sta  ROW
lda  #$04 
sta  COLUMN

;Calculation 

cal_init:

  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   ; if row is done, deal with col
 bne row_count      ; if not fix row

;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:
  lda PTR_CALCULATE
  clc
  adc  COLUMN
 sta PTR_CALCULATE

; store pointer
  sta  POINTER

; draw graphic

 lda #$00
 sta ROW_COUNT

 ldx #$00  
 ldy #$00  

; draw graph
draw: lda ball,x

 sta (POINTER),y

 inx
 iny
 cpy #WIDTH
 bne draw

 inc ROW_COUNT

 lda #HEIGHT
 cmp ROW_COUNT
 beq draw

 lda POINTER 
 clc
 adc #$20
 sta POINTER
 lda POINTER_H
 adc #$00
 sta POINTER_H 

 ldy #$00
 beq draw

; 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 (dcb instruction)
ball:
 dcb 00,03,03,03,00
 dcb 03,03,03,03,03
 dcb 03,03,03,03,03
 dcb 03,03,03,03,03
 dcb 00,03,03,03,00
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wl7u0yf4ze1v4dbb85mv.png)
 

The most insteresting part of this work is that I have learnt how to draw a ball in the bit-mapped screen. The most important part is to calculate the point position using row and column, and deciding page number through carry flag. The trick here is to add with 20 and the page number is decided by carry flag.
Since the 45 degree angle was used, moving is simplified by adding 1 to row and column.
The moving functionality is not fully worked well at this stage. Mainly due to the subroutines are not properly combined together.
The learning goal here is to understand and get familiar with subroutines.