	.ORIG x3000

	BR MAIN

; ------------------------------------------------------
; Trap Relays

DRAW_POINT_TR
	STR R7, R6, #0
	ADD R6, R6, #-1
	TRAP x40
	ADD R6, R6, #1
	LDR R7, R6, #0
	RET

DRAW_BALL_TR
	STR R7, R6, #0
	ADD R6, R6, #-1
	TRAP x41
	ADD R6, R6, #1
	LDR R7, R6, #0
	RET

DRAW_RECTANGLE_TR
	STR R7, R6, #0
	ADD R6, R6, #-1
	TRAP x42
	ADD R6, R6, #1
	LDR R7, R6, #0
	RET

CHECK_POINT_TR
	STR R7, R6, #0
	ADD R6, R6, #-1
	TRAP x43
	ADD R6, R6, #1
	LDR R7, R6, #0
	RET

GET_EVENT_TR
	STR R7, R6, #0
	ADD R6, R6, #-1
	TRAP x44
	ADD R6, R6, #1
	LDR R7, R6, #0
	RET

; ------------------------------------------------------

; Main Function

; Register Assignments:
;	R5 - Return Value
;	R6 - Stack Pointer
;	R7 - Return Address
MAIN

	; Initialize globals
	LD R0, BALL_START_ROW
	ST R0, BALL_ROW_POS
	LD R0, BALL_START_COL
	ST R0, BALL_COL_POS
	LD R0, BALL_START_VEL_ROW
	ST R0, BALL_ROW_VEL
	LD R0, BALL_START_VEL_COL
	ST R0, BALL_COL_VEL
	LD R0, PADDLE_START_COL
	ST R0, PADDLE_COL_POS

	; Initialize video memory
	JSR INIT_VIDEO_MEMORY

	;;;; Part 5: Put your code here!!!

GAME_OVER
	HALT

; ------------------------------------------------------

; Initial Constants Section

; Paddle Stats

PADDLE_ROW_POS		.FILL #116
PADDLE_START_COL	.FILL #58
PADDLE_HEIGHT		.FILL #2
PADDLE_WIDTH		.FILL #12
PADDLE_VEL		.FILL #2

; Ball Stats

BALL_START_ROW		.FILL #114
BALL_START_COL		.FILL #63
BALL_SIZE		.FILL #2

BALL_START_VEL_ROW	.FILL #-1
BALL_START_VEL_COL	.FILL #1

; Field Stats

FIELD_ROW		.FILL #3
FIELD_COL		.FILL #8
FIELD_HEIGHT		.FILL #116
FIELD_WIDTH		.FILL #112

; ------------------------------------------------------

; Init Video Memory Subroutine - initializes video memory
INIT_VIDEO_MEMORY
; Arguments: None
; Return: void

	; Register Saving
	STR R0, R6, #0
	STR R1, R6, #-1
	STR R2, R6, #-2
	STR R3, R6, #-3
	STR R4, R6, #-4
	STR R5, R6, #-5
	STR R7, R6, #-6
	ADD R6, R6, #-7

	; Draw walls
	LD R4, COLOR_WALL

	; Left wall
	LD R0, FIELD_ROW
	LD R1, FIELD_COL
	LD R2, FIELD_HEIGHT
	AND R3, R3, #0
	ADD R3, R3, #1			; width = 1
	JSR DRAW_RECTANGLE_TR

	; Right wall
	LD R5, FIELD_WIDTH
	ADD R1, R1, R5			; col = field_col + field_width
	JSR DRAW_RECTANGLE_TR

	; Top wall
	LD R1, FIELD_COL
	ADD R2, R3, #0			; height = 1	
	LD R3, FIELD_WIDTH
	JSR DRAW_RECTANGLE_TR
	
	; Floor
	LD R4, COLOR_FLOOR

	LD R5, FIELD_HEIGHT
	ADD R0, R0, R5			; row = field_row + field_height
	JSR DRAW_RECTANGLE_TR

	; Draw paddle
	LD R4, COLOR_PADDLE

	LD R0, PADDLE_ROW_POS
	LD R1, PADDLE_START_COL
	LD R2, PADDLE_HEIGHT
	LD R3, PADDLE_WIDTH
	JSR DRAW_RECTANGLE_TR

	; Draw Ball
	LD R0, BALL_START_ROW
	LD R1, BALL_START_COL
	LD R2, COLOR_BALL
	JSR DRAW_BALL_TR

        ; Register Restoring
        ADD R6, R6, #7
	LDR R0, R6, #0
        LDR R1, R6, #-1
        LDR R2, R6, #-2
        LDR R3, R6, #-3
        LDR R4, R6, #-4
	LDR R5, R6, #-5
        LDR R7, R6, #-6
        
	RET

; ------------------------------------------------------

; Move Paddle subroutine - moves the paddle one frame
MOVE_PADDLE
; Arguments: R0 - left (0), right (1)
; Return: void

	; Register Saving
	STR R0, R6, #0
	STR R1, R6, #-1
	STR R2, R6, #-2
	STR R3, R6, #-3
	STR R4, R6, #-4
	STR R5, R6, #-5
	STR R7, R6, #-6
	ADD R6, R6, #-7

	;;;; Part 4: Put your code here!!!

        ; Register Restoring
        ADD R6, R6, #7
	LDR R0, R6, #0
        LDR R1, R6, #-1
        LDR R2, R6, #-2
        LDR R3, R6, #-3
        LDR R4, R6, #-4
	LDR R5, R6, #-5
        LDR R7, R6, #-6

	RET

; ------------------------------------------------------

; Move Ball subroutine - moves the ball one frame based on velocity
MOVE_BALL
; Arguments: None
; Return: R5 - game over (-1), no game over (0)

	; Register Saving
	STR R0, R6, #0
	STR R1, R6, #-1
	STR R2, R6, #-2
	STR R3, R6, #-3
	STR R4, R6, #-4
	STR R7, R6, #-5
	ADD R6, R6, #-6

	;;;; Part 3: Put your code here!!!

        ; Register Restoring
        ADD R6, R6, #6
	LDR R0, R6, #0
        LDR R1, R6, #-1
        LDR R2, R6, #-2
        LDR R3, R6, #-3
        LDR R4, R6, #-4
        LDR R7, R6, #-5

	RET

; ------------------------------------------------------

; global variables
BALL_ROW_POS		.BLKW #1
BALL_COL_POS		.BLKW #1
BALL_ROW_VEL		.BLKW #1
BALL_COL_VEL		.BLKW #1
PADDLE_COL_POS		.BLKW #1

; Colors

COLOR_BALL		.FILL xFFFF	; White
COLOR_PADDLE		.FILL xFFFE	; Almost White
COLOR_WALL		.FILL x4210	; Gray
COLOR_FLOOR		.FILL x0001	; Almost Black

; ------------------------------------------------------

; Handle Collision subroutine - checks for and handles a ball collision
HANDLE_COLLISION
; Arguments: None
; Return: R5 - game over (-1), no game over (0)

	; Register Saving
	STR R0, R6, #0
	STR R1, R6, #-1
	STR R2, R6, #-2
	STR R3, R6, #-3
	STR R4, R6, #-4
	STR R7, R6, #-5
	ADD R6, R6, #-6

	;;;; Part 2: Put your code here!!!

        ; Register Restoring
        ADD R6, R6, #6
	LDR R0, R6, #0
        LDR R1, R6, #-1
        LDR R2, R6, #-2
        LDR R3, R6, #-3
        LDR R4, R6, #-4
        LDR R7, R6, #-5

	RET

; ------------------------------------------------------

; Get Pixel Type subroutine - returns the object type at a given pixel
GET_PIXEL_TYPE
; Arguments: R0 - row, R1 - col
; Return: R5 - game over (-1), no collision (0), wall collision (1), paddle collision (2), brick collision (3)

	; Register Saving
	STR R0, R6, #0
	STR R1, R6, #-1
	STR R2, R6, #-2
	STR R3, R6, #-3
	STR R4, R6, #-4
	STR R7, R6, #-5
	ADD R6, R6, #-6

	;;;; Part 1: Put your code here!!!

        ; Register Restoring
        ADD R6, R6, #6
	LDR R0, R6, #0
        LDR R1, R6, #-1
        LDR R2, R6, #-2
        LDR R3, R6, #-3
        LDR R4, R6, #-4
        LDR R7, R6, #-5

	RET

; ------------------------------------------------------

; Handle Paddle Collision subroutine - changes ball's col velocity based on where it hits the paddle
HANDLE_PADDLE_COLL
; Arguments: R0 - col
; Return: None

	; Register Saving
	STR R0, R6, #0
	STR R1, R6, #-1
	STR R2, R6, #-2
	STR R3, R6, #-3
	STR R4, R6, #-4
	STR R5, R6, #-5
	STR R7, R6, #-6
	ADD R6, R6, #-7

	;;;; Part 7: Put your code here!!!

        ; Register Restoring
        ADD R6, R6, #7
	LDR R0, R6, #0
        LDR R1, R6, #-1
        LDR R2, R6, #-2
        LDR R3, R6, #-3
        LDR R4, R6, #-4
	LDR R5, R6, #-5
        LDR R7, R6, #-6

	RET

; ------------------------------------------------------

; Clear Brick At Point subroutine - clears a brick at a given point
CLEAR_BRICK
; Arguments: R0 - row, R1 - col
; Return: None

	; Register Saving
	STR R0, R6, #0
	STR R1, R6, #-1
	STR R2, R6, #-2
	STR R3, R6, #-3
	STR R4, R6, #-4
	STR R5, R6, #-5
	STR R7, R6, #-6
	ADD R6, R6, #-7

	;;;; Part 6-a: Put your code here!!!

        ; Register Restoring
        ADD R6, R6, #7
	LDR R0, R6, #0
        LDR R1, R6, #-1
        LDR R2, R6, #-2
        LDR R3, R6, #-3
        LDR R4, R6, #-4
	LDR R5, R6, #-5
        LDR R7, R6, #-6

	RET

; ------------------------------------------------------

; Clear Brick subroutine - recursively clears a brick
CLEAR_BRICK_RECURSE
; Arguments: R0 - row, R1 - col, R2 - color
; Return: None

	; Register Saving
	STR R0, R6, #0
	STR R1, R6, #-1
	STR R2, R6, #-2
	STR R3, R6, #-3
	STR R4, R6, #-4
	STR R5, R6, #-5
	STR R7, R6, #-6
	ADD R6, R6, #-7

	;;;; Part 6-b: Put your code here!!!

        ; Register Restoring
        ADD R6, R6, #7
	LDR R0, R6, #0
        LDR R1, R6, #-1
        LDR R2, R6, #-2
        LDR R3, R6, #-3
        LDR R4, R6, #-4
	LDR R5, R6, #-5
        LDR R7, R6, #-6

	RET

