;Photon... battle of the Chibi Photonic hunters!

UserRam Equ &C000			;System Memory


Color1 equ &1				;Color palette
Color2 equ &2
Color3 equ &3
Color4 equ &4

ScreenWidth32 equ 1			;Screen Size
ScreenWidth equ 256
ScreenHeight equ 192

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;For Cartridge	
	org &4000				;Base Cart Address
	db "AB"					;Fixed Header
	dw ProgramStart 		;Pointer to start of program
	db 00,00,00,00,00,00	;Unused
	
	;Effectively Code starts at address &400A
	
VdpOut_Data equ &98			;For Data writes
VdpOut_Control equ &99		;For Reg settings /Selecting Dest addr in VRAM
VdpOut_Palette equ &9A
VdpOut_Indirect equ &9B
VdpIn_Status 	equ &99

ProgramStart:				;Program Code Starts Here
	
	;Initialize screen
	ld c,VdpOut_Control	
	ld b,VDPScreenInitData_End-VDPScreenInitData
	ld hl,VDPScreenInitData
	otir
	
	xor a					;Start from color 0
	out (VdpOut_Control),a	;Send palette number to the VDP
	ld a,128+16				;Copy Value to Register 16 (Palette)
	out (VdpOut_Control),a

	ld hl,palette			;Address of palette
	ld c,VdpOut_Palette		;Palette port
	ld b,16*2				;16 colors - 2 bytes per color
	otir
	
	ld hl,UserRam			;Clear Game Ram
	ld de,UserRam+1
	ld bc,256
	ld (hl),0
	ldir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	call MainMenu

infloop:					;Main Loop
	ld a,(Tick)
	inc a
	and %00000001
	ld (Tick),a

	ld bc,150				;Slow Down Delay

	ld a,(boost)			;Check if boost is on
	or a
	jr nz,BoostOff
	ld bc,1		;Boost - no delay (compensate for font draw)
BoostOff:

	ld d,255				;Key buffer
PauseBC:
	push bc
		push de
			call ReadJoystick
		pop de
		cp 0
		jr z,PauseNoKey
		ld d,a				;Store any pressed joystick buttons
		jr KeysDown
PauseNoKey:
	ld a,0
	ld (KeyTimeout),a		;Released - nuke key, and relese keypress
	ld d,255
KeysDown:
	pop bc
	dec bc
	ld a,b
	or c
	jr nz,PauseBC

StartDraw:
	ld a,(KeyTimeout)		;Keytimeout 
	or a
	jr nz,JoySkip			;Yes, skip keypresses

	ld a,1
	ld (boost),a			;Boost Off
	
ProcessKeys:
	ld hl,PlayerDirection
	ld ix,PlayerXacc		;Point IX to player Accelerations 
	ld a,d		
	cp 7					;L
	jr nz,JoyNotLeft	
	dec (hl)
	call SetPlayerDirection
	ld a,1
	ld (KeyTimeout),a		;Ignore keypresses
JoyNotLeft:
	ld a,d
	cp 3					;R
	jr nz,JoyNotRight	
	inc (hl)
	call SetPlayerDirection
	ld a,1
	ld (KeyTimeout),a		;Ignore keypresses
JoyNotRight: 
	ld a,1					;Select Fire 1
	call &00D8				;Joystick Fire button firmware call
	cp 255
	jr nz,JoyNotFire
	ld a,(BoostPower)		;Check if boost power remains
	or a
	jr z,JoyNotFire
	ld a,0
	ld (boost),a			;Turn on Boost
JoyNotFire:
JoySkip:
	call HandlePlayer		;Draw and update player
	
	call HandleCPU			;Draw and update CPU
	
	jp InfLoop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ReadJoystick:
	ei
		ld a,1				;Joystick 1 (0=keyboard 1=joy1 2=joy2)
		call &00D5			;GTSTCK - Get Keypress
	ret
	
WaitForFire:
	call DoRandom
	ld a,1					;Select Fire 1
	call &00D8				;Read Trigger
	cp 255
	jr z,WaitForFire

WaitForFireB:
	call DoRandom
	ld a,1					;Select Fire 1
	call &00D8				;Read Trigger
	cp 255
	jr nz,WaitForFireB
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Wait for Status Register
VDP_Wait: 			;Get The status register - Disable interrupts, 
						;as they require status register 0 to be selected!
	call VDP_GetStatusRegister
VDP_DoWait:
	in a,(VdpIn_Status)	;Status register 2	- S#2  [TR ] [VR ] [HR ] [BD ] [ 1 ] [ 1 ] [EO ] [CE ] 
	rra
	ret nc
	jr VDP_DoWait

;Get Status Reg
VDP_GetStatusFirwareDefault:
	xor a
	jr VDP_GetStatusRegisterB
VDP_GetStatusRegister:		;Get The status register - Disable interrupts!
	ld a,2					;S#2  [TR ] [VR ] [HR ] [BD ] [ 1 ] [ 1 ] [EO ] [CE ] - Status register 2
VDP_GetStatusRegisterB:
	out (VdpOut_Control),a
	ld a,128+15				;R#15  [ 0 ] [ 0 ] [ 0 ] [ 0 ] [S3 ] [S2 ] [S1 ] [S0 ] - Set Stat Reg to read
	out (VdpOut_Control),a
	ret
	
;Set the indirect register (For setting Control regs)
SetIndirect:
	out (VdpOut_Control),a		
	ld a,128+17			;R#17 -	Indirect Register 128=no inc  [AII] [ 0 ] [R5 ] [R4 ] [R3 ] [R2 ] [R1 ] [R0 ] 	
	out (VdpOut_Control),a
	ld c,VdpOut_Indirect	
	ret
	
WaitForCeFlag:	;Command Execution - Wait for VDP to be ready
	di
	call VDP_Wait						;Wait for the VDP to be available
	call VDP_GetStatusFirwareDefault	;Reset selected Status register to 0 for the firmware
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

Cls:		
	di
	ld ix,0			;XDest
	ld iy,0			;YDest
	ld hl,256		;Width
	ld de,192		;Height
	ld a,&00		;Colors (&LR)
	call VDP_HMMV_ViaStack		;Fast Copy Vram->Vram
	ret

;Fill area - used by CLS
VDP_HMMV_ViaStack:
		ld bc,&00C0		;Command Byte (don't change)
		push bc
		ld c,a			;Color / Direction (UNUSED)
		push bc			
		push de			;Height
		push hl			;Width
		push IY			;DestY
		push IX			;DestX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_HMMV
		pop hl
		
		ld bc,12		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
				
VDP_HMMV:				;Fast copy from VRAM to VRAM
	ld a,36				;AutoInc From 36
	call SetIndirect
;These Bytes are a sequence of OUTI Commands 	
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3
	defb &ED,&A3,&ED,&A3,&ED,&A3						 ;outi x 11
	ret											
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
Pset:		;BC=(X,Y) D=Color
	push hl
	push bc	
	push de
		ld a,d			;Color
		ld h,0
		ld l,b			;HL=Xpos
		ld d,0
		ld e,c			;DE=Ypos
		ld c,LOG_IMP	;Logical OP applied to pixel
		call VDP_PSET_ViaStack	
	pop de
	pop bc
	pop hl
	ret
	
LOG_IMP	 	  equ %00000000		;Normal (as opposed to XOR etc)

;Set a pixel... XY=HL,DE = color A.... log op C
VDP_PSET_ViaStack:		
		push af
			ld a,&50	;Command Byte (don't change)
			or c		;OR in Logical Operation
			ld c,a
			ld b,0
		pop af
		push bc
		ld c,a			;Color / Direction
		push bc			
		push de			;Height (UNUSED)
		push hl			;Width  (UNUSED)
		push DE			;DestY
		push HL			;DestX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_PSET
		pop hl
		
		ld bc,12		;Skip 6 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
				
VDP_PSET:				;Logical PSET
	ld a,36				;AutoInc From 36
	call SetIndirect
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3
	defb &ED,&A3,&ED,&A3,&ED,&A3
	ret													 ;outi x 11
		
		
		
PsetHLDE:	;DE=Xpos HL=Ypos A=Color
	push hl
	push bc	
	push de
		ex de,hl
		ld c,LOG_IMP	;Logical OP
		call VDP_PSET_ViaStack	
		
	pop de
	pop bc
	pop hl
	ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Point:			;Test XY pos BC - returns pixel A
	push hl
	push bc	
	push de
		ld h,0
		ld l,b		;HL=Xpos
		ld d,0
		ld e,c		;DE=Ypos
		call VDP_POINT_ViaStack	
	pop de
	pop bc
	pop hl
	ret
	
;Get a pixel... XY=HL,DE... returns color in A
VDP_POINT_ViaStack:		
		ld bc,&0040		;Command
		push bc
		push bc			
		push de			;Height (UNUSED)
		push hl			;Width  (UNUSED)
		push DE			;DestY  (UNUSED)
		push HL			;DestX  (UNUSED)
		push DE			;SourceY 
		push HL			;SourceX 
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call WaitForCeFlag	;Wait for VDP to be ready
			call VDP_POINT
		pop hl
		
		ld bc,16		;Skip 6 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		call WaitForCeFlag	;Wait for VDP to be ready
		Call GetColorByte	;Read Status Reg 7
		push af
			call VDP_GetStatusFirwareDefault	
		pop af		
		ret

VDP_POINT:				;Logical POINT
	ld a,32				;AutoInc From 32
	call SetIndirect
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3;outi x 15
	ret

GetColorByte:
	ld a,7
	call VDP_GetStatusRegisterB
	in a,(VdpIn_Status)		;Read the color from the pixel
	ret
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	include "\SrcAll\MultiPlatform_MultDiv.asm"
	include "\ResALL\Vector\VectorFont.asm"
	include "\Sources\Photon\PH_Title.asm"
	
	include "\SrcALL\MultiPlatform_ShowDecimal.asm"
	include "PH_Vector.asm"
	include "PH_Multiplatform.asm"
	include "PH_DataDefs.asm"
	include "PH_RamDefs.asm"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

VDPScreenInitData:	
	db %00000110,128+0		;mode register #0
	db %01100000,128+1		;mode register #1
	db 31		,128+2		;pattern name table
	db 239		,128+5		;sprite attribute table (LOW)
	db %11110000,128+7		;border colour
	db %00001010,128+8		;mode register #2
	db %00000000,128+9	 	;mode register #3
	db 128		,128+10		;colour table (HIGH)
	db 0		,128+46		;Write Mask L
	db 00		,128+47		;Write Mask H
VDPScreenInitData_End:	

palette:	
	dw %0000000000000000; ;0  %-----GGG-RRR-BBB
	dw %0000011100000111; ;2  %-----GGG-RRR-BBB
	dw %0000000001110111; ;3  %-----GGG-RRR-BBB
	dw %0000011100000000; ;1  %-----GGG-RRR-BBB
	dw %0000011101110000; ;4  %-----GGG-RRR-BBB
	dw %0000010000010011; ;5  %-----GGG-RRR-BBB
	dw %0000011000010001; ;6  %-----GGG-RRR-BBB
	dw %0000000101110001; ;7  %-----GGG-RRR-BBB
	dw %0000001101110011; ;8  %-----GGG-RRR-BBB
	dw %0000010101110010; ;9  %-----GGG-RRR-BBB
	dw %0000011101110010; ;10  %-----GGG-RRR-BBB
	dw %0000000101010101; ;11  %-----GGG-RRR-BBB
	dw %0000000001110111; ;12  %-----GGG-RRR-BBB
	dw %0000000100000110; ;13  %-----GGG-RRR-BBB
	dw %0000001100010101; ;14  %-----GGG-RRR-BBB
	dw %0000011000000111; ;15  %-----GGG-RRR-BBB
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	org &C000			;Make cartridge 32k
 