Qiwen Yu

Posted on

Lab3 Bouncing Graphic/Ball (Part II)

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, 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
sta PTR_CALCULATE

lda POINTER_H
sta  POINTER_H

inc ROW_COUNT

lda ROW
cmp ROW_COUNT
bne row_count
beq column_count

column_count:
lda PTR_CALCULATE
clc
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
sta POINTER
lda POINTER_H
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
``````

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.