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