; ******************************************
; Ooze64 V0.01 Tech Demo Update - 12/3/2010
; Written for the Commodore 64/128 by Ooze64
; http://ooze64.co.cc
; Open Source GPL v3 License
;
; Ooze is a game of reflexes and strategy. You
; control the bat with your joystick. Move the
; bat left and right and try to prevent the ball
; from hitting the ooze by reflecting it off your
; bat. For every second the ball remains in play
; you will get points. Once the ball hits the ooze
; it's game over. Try again to get a better score.
;
; Compiles with C64ASM V. 1.1
; c64asm ooze64.asm ooze64.t64
;
; Type RUN or SYS 12288 to start
;
; Memory Map
; $0000 - $00ff Unused
; $0100 - $03ff	Unused
; $0400 - $07e7 Screen Memory
; $0801 - $08xx BASIC Loader
; $1000 - $1xxx Music
; $2000 - $2xxx Sprite
; $3000 - $3xxx Code
; ******************************************

; Constants
BKGCOLOR2 = $d022		; register for second background color in extend color mode
CHARCSET2 = $43			; character C of character set 2
CHARCOLONSET2 = $7a		; character : of character set 2
CHARESET2 = $45			; character E of character set 2
CHAROSET2 = $4f			; character O of character set 2
CHARRSET2 = $52			; character R of character set 2
CHARSSET2 = $53			; character S of character set 2
CHARSPACE = $20			; character   of character set 1
COLORBLUE = $06			; blue color constant
COLORGREEN = $05		; green color constant
COLORGREY = $0f			; grey color constant
JOYPORT = $dc00			; joystick port 2
JOYPDDR = $dc02			; joystick port data direction register
SCOREDIGIT1 = $07c7		; screen memory to where first score digit is displayed
SCOREDIGIT2 = $07c8		; screen memory to where second score digit is displayed
SCOREDIGIT3 = $07c9		; screen memory to where third score digit is displayed
SCOREDIGIT4 = $07ca		; screen memory to where forth score digit is displayed
SCOREDIGIT5 = $07cb		; screen memory to where fifth score digit is displayed
SCOREDIGIT6 = $07cc		; screen memory to where sixth score digit is displayed
SCORETXTSTART = $07c0		; screen memory where score text starts
SPRITE0COLOR = $d027		; sprite 0's color register
SPRITE0PTR = $07f8		; pointer to sprite 0's bitmap
SPRITE0X = $d000		; sprite 0's x position
SPRITE0Y = $d001		; sprite 0's y position
SPRITE1COLOR = $d028		; sprite 1's color register
SPRITE1LEFTEDGE = $18		; left boundry for sprite 1
SPRITE1PTR = $07f9		; pointer to sprite 1's bitmap
SPRITE1RIGHTEDGE = $fd		; right boundry for sprite 1
SPRITE1X = $d002		; sprite 1's x position
SPRITE1Y = $d003		; sprite 1's y position
SPRITEENABLE = $d015		; sprite enable register
VICBORDER = $d020		; border color register
VICSCREEN = $d021		; screen color register

	* = $0801

	.byte $0c,$08,$0a,$00,$9e,$31,$32,$32,$38,$38,$00,$00,$00,$00,$00
	; Data table to form the SYS start address to $3000 

	* = $2000

	; Sprite 0 is the ball

	.byte $00,$00,$00 	; row 1
	.byte $00,$00,$00 	; row 2
	.byte $00,$00,$00 	; row 3
	.byte $00,$00,$00	; row 4
	.byte $00,$00,$00	; row 5
	.byte $00,$00,$00	; row 6
	.byte $00,$00,$00	; row 7
	.byte $00,$ff,$00	; row 8
	.byte $00,$ff,$00	; row 9
	.byte $00,$ff,$00	; row 10
	.byte $00,$ff,$00	; row 11
	.byte $00,$ff,$00	; row 12
	.byte $00,$ff,$00	; row 13
	.byte $00,$ff,$00	; row 14
	.byte $00,$00,$00	; row 15
	.byte $00,$00,$00	; row 16
	.byte $00,$00,$00	; row 17
	.byte $00,$00,$00	; row 18
	.byte $00,$00,$00	; row 19
	.byte $00,$00,$00	; row 20
	.byte $00,$00,$00	; row 21

	*= $2040

	; Sprite 1 is the paddle

	.byte $00,$00,$00 	; row 1
	.byte $00,$00,$00 	; row 2
	.byte $00,$00,$00 	; row 3
	.byte $00,$00,$00	; row 4
	.byte $00,$00,$00	; row 5
	.byte $00,$00,$00	; row 6
	.byte $00,$00,$00	; row 7
	.byte $00,$00,$00	; row 8
	.byte $00,$00,$00	; row 9
	.byte $00,$00,$00	; row 10
	.byte $00,$00,$00	; row 11
	.byte $00,$00,$00	; row 12
	.byte $00,$00,$00	; row 13
	.byte $00,$00,$00	; row 14
	.byte $00,$00,$00	; row 15
	.byte $00,$00,$00	; row 16
	.byte $00,$00,$00	; row 17
	.byte $00,$00,$00	; row 18
	.byte $ff,$ff,$ff	; row 19
	.byte $ff,$ff,$ff	; row 20
	.byte $ff,$ff,$ff	; row 21

	* = $3000

	sei			; Turn off interrupts

	lda #CHARSPACE		; space character

	ldx #$00

clearScreen

	sta $0400,x		; clear the screen by putting the space

	sta $0500,x		; character in every character space

	sta $0600,x

	sta $0700,x

	dex			; deincrement x

	bne ClearScreen		; if were not done clearing the screen loop

	lda #01			; white color

	sta $d01a		; Turn on Raster interrupts

	ldx #$0d

SetUpStatusBox

	sta $dbbf,x		; setup the statusbox text by setting the text color to white

	dex			; increment x

	bne SetUpStatusBox	; if were not done setting up the statusbox text loop

	lda #$60

	ldx #$27

SetUpStatusBox2

	sta $07c0,x		; setup the statusbox by setting the background color to green

	dex			; increment x

	bne SetUpStatusBox2	; if were not done setting up the statusbox loop

	stx $d01b		; sprites have priority over bitmaps

	stx $d01c		; no multicolor mode

	stx $d01d		; no x-expansion of sprite

	stx $d017		; no y-expansion of sprite 

	stx $d010		; set x-coordinates MSBs

	stx JOYPDDR		; set joyport to input 

	stx VICBORDER		; set the border color to black

	lda #CHARSSET2		; character s

	sta SCORETXTSTART	; score text start location

	lda #CHARCSET2		; character c

	sta SCORETXTSTART+1	; score text start location + 1

	lda #CHAROSET2		; caharacter o

	sta SCORETXTSTART+2	; score text start location + 2

	lda #CHARRSET2		; character r

	sta SCORETXTSTART+3	; score text start location + 3

	lda #CHARESET2		; character e

	sta SCORETXTSTART+4	; score text start location + 4

	lda #CHARCOLONSET2	; character :

	sta SCORETXTSTART+5	; score text start location + 5

	lda #$70		; character 0

	sta SCOREDIGIT1		; set first score digit to 0

	sta SCOREDIGIT2		; set second score digit to 0 

	sta SCOREDIGIT3		; set third score digit to 0

	sta SCOREDIGIT4		; set forth score digit to 0

	sta SCOREDIGIT5		; set fifth score digit to 0

	sta SCOREDIGIT6		; set sixth score digit to 0

	lda #$b0

	sta SPRITE0X		; set x coordinate of sprite 0 to 48

	sta SPRITE1X		; set x coordinate of sprite 1 to 48

	lda #$32

	sta SPRITE0Y		; set y coordinate of sprite 0 to 50

	lda #$dd

	sta SPRITE1Y		; set y coordinate of sprite 1 to 221

	lda #$80		; Line to trigger interrupt

	sta $312

	sta SPRITE0PTR		; sprite 0 pointer at $2000

	lda #$81

	sta SPRITE1PTR		; sprite 1 pointer at $2100

	lda #$03

	sta SPRITEENABLE	; turn on sprite 0 and sprite 1

	lda #COLORGREY

	sta VICSCREEN		; set the screen color to light grey

	lda #COLORGREEN

	sta BKGCOLOR2		; set the text's background color to
				; the second background color (green)

	lda #COLORBLUE

	sta SPRITE0COLOR	; set sprite 0 color to blue

	sta SPRITE1COLOR	; set sprite 1 color to blue

	lda #$7f

	sta $dc0d		; Turn off CIA 1 interrupts

	sta $dd0d		; Turn off CIA 2 interrupts

	lda #$5b		; enable extended color mode

	ldx #$08

	ldy #$14

	sta $d011		; Clear high bit of d012, set text mode

	stx $d016		; Single color

	sty $d018		; Screen at #$0400, charset at $2000

	lda #<int		; Low part of address of interrupt handler code

	ldx #>int		; High part of address of interrupt handler code

	sta $0314		; Store in interrupt vector

	stx $0315

	lda $dc0d		; ACK CIA 1 interrupts

	lda $dd0d		; ACK CIA 2 interrupts

	asl $d019		; ACK VIC interrupts

	cli

loop

	jmp loop		; Infinite loop

int

	lda JOYPORT		; read port 2

	lsr a			; Joystick in port 2 up

	lsr a			; Joystick in port 2 down

	lsr a			; Joystick in port 2 left

	bcs SkipSprite1Left	; don't move sprite 1 if the joystick in port 2
				; isn't pushed left

	ldx SPRITE1X		; load sprite 1's x position into the x register

	dex			; increment it

	dex			; two times

	cpx #SPRITE1LEFTEDGE	; is it past the left boundry?

	bcs SetSprite1Left	; if not set it's x position

	ldx #SPRITE1LEFTEDGE	; otherwise set the sprite 1's x position at its
				; left boundry

SetSprite1Left

	stx SPRITE1X		; and store it

SkipSprite1Left

	lsr a			; Joystick Right

	bcs SkipSprite1Right	; don't move sprite 1 if the joystick in port 2
				; isn't pushed right

	ldx SPRITE1X		; load sprite 1's x position into the x register

	inx			; increment it

	inx			; two times

	cpx #SPRITE1RIGHTEDGE	; is it past the right boundry?

	bcc SetSprite1Right	; if not set it's x position

	ldx #SPRITE1RIGHTEDGE	; otherwise set the sprite 1's x position at its
				; right boundry

SetSprite1Right

	stx SPRITE1X		; and store it

SkipSprite1Right

	asl $d019		; ACK interrupt (to re-enable it)

	pla

	tay

	pla

	tax

	pla

	rti			; return from interrupt