SPO600 - Lab 3
Tags: beginners, opensource
Published: 2021-11-04 16:04:17

##Instruction
Assembly language is a type of low-level programming language that is intended to communicate directly with a computer's hardware. In this lab, there are four options for us to choose: 
* Bouncing Graphic
* Numeric Display
* Pong
* Kaleidoscope

This time, I will choose Kaleidoscope because I already know this game when I was young, so I partially have the idea of how it is going to work.

The code I am creating permits user to draw pixels on one-quarter of the screen in any of several different colors. Moreover, the code also allows user to mirror the pixel to the other three quadrants. For instance, a pixel drawn at (0,0) should be mirrored to (31,31), (0,31), and (31, 0). Here is the source code I have create for this game:

```
 ; zero-page variable locations
 define ROW		$20	; current row
 define	COL		$21	; current column
 define	POINTER		$10	; ptr: start of row
 define	POINTER_H	$11
 
 ; constants
 define	DOT		$01	; dot colour location
 define	CURSOR		$04	; purple colour


 setup:	lda #$0f	; set initial ROW,COL
 	sta ROW
 	sta COL
	LDA #$01
	STA DOT
 
 draw:	jsr draw_cursor

 getkey:	lda $ff		; get a keystroke
 
 	ldx #$00	; clear out the key buffer
 	stx $ff
 
	cmp #$30
	bmi getkey
	cmp #$40
	bpl continue

	SEC
	sbc #$30
	tay
	lda color_pallete, y
	sta DOT
	jmp done
 
continue:	cmp #$43	; handle C or c
 	beq clear
 	cmp #$63
 	beq clear
 
 	cmp #$80	; if not a cursor key, ignore
 	bmi getkey
 	cmp #$84
 	bpl getkey
 
 	pha		; save A
 
	lda DOT	; set current position to DOT
 	sta (POINTER),y
	jsr draw_on_quads

 	pla		; restore A
 
 	cmp #$80	; check key == up
 	bne check1
 
 	dec ROW		; ... if yes, decrement ROW
 	jmp done
 
 check1:	cmp #$81	; check key == right
 	bne check2
 
 	inc COL		; ... if yes, increment COL
 	jmp done
 
 check2:	cmp #$82	; check if key == down
 	bne check3
 
 	inc ROW		; ... if yes, increment ROW
 	jmp done
 
 check3:	cmp #$83	; check if key == left
 	bne done
 
 	dec COL		; ... if yes, decrement COL
 	clc
 	bcc done
 
 clear:	lda table_low	; clear the screen
 	sta POINTER
 	lda table_high
 	sta POINTER_H
 
 	ldy #$00
 	tya
 
 c_loop:	sta (POINTER),y
 	iny
 	bne c_loop
 
 	inc POINTER_H
 	ldx POINTER_H
 	cpx #$06
 	bne c_loop
 
 done:	clc		; repeat
 	bcc draw
 
 
 draw_cursor:
 	lda ROW		; ensure ROW is in range 0:31
 	and #$0f
 	sta ROW
 
 	lda COL		; ensure COL is in range 0:31
 	and #$0f
 	sta COL
 
 	ldy ROW		; load POINTER with start-of-row
 	lda table_low,y
 	sta POINTER
 	lda table_high,y
 	sta POINTER_H
 
 	ldy COL		; store CURSOR at POINTER plus COL
 	lda #CURSOR
	sta (POINTER),y

	rts

 draw_on_quads:		
	LDA POINTER	;; save the pointer to the
	PHA			;; original location in top_left_quad
	LDA POINTER_H
	PHA

	LDA #$10
	CLC
	SBC COL
	CLC
	ADC #$10
	TAY
	LDA DOT
	STA (POINTER),y

	TYA
	PHA	; save the y offset
	
	lda #$10	; load POINTER with start-of-row
	CLC
	SBC ROW
	CLC
	ADC #$10
	TAY
 	lda table_low,y
 	sta POINTER
 	lda table_high,y
 	sta POINTER_H

	ldy COL		; store CURSOR at POINTER plus COL
 	lda DOT
	sta (POINTER),y

	PLA
	TAY
	lda DOT
	sta (POINTER),y

	PLA
	STA POINTER_H
	PLA
	STA POINTER

	RTS

 ; these two tables contain the high and low bytes
 ; of the addresses of the start of each row
 
 table_high:
 dcb $02,$02,$02,$02,$02,$02,$02,$02
 dcb $03,$03,$03,$03,$03,$03,$03,$03
 dcb $04,$04,$04,$04,$04,$04,$04,$04
 dcb $05,$05,$05,$05,$05,$05,$05,$05,
 
 table_low:
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0

color_pallete:
dcb $01,$02,$03,$04,$05,$06,$07,$08,$09,$0a
```

##What I have learned from this lab?
Even though the code is working, but it possibly has some errors. Before writing the code, it is better if we think about which components should be fixed or checked in order to make it work successfully. Also, giving it multiple tests to see where the errors come from.