	
	
	ORG &00F0
	DB 0,5			;type 5 = machine code application program
	DW FileEnd-FileStart	;16 bit length
	DB 0,0,0,0,0,0,0,0,0,0,0,0 ;not used bytes
;Program starts at ORG &0100

FileStart:			
	LD SP,&100				;Set up a base stack pointer
	call ScreenINIT

ScreenWidth40 equ 1
ScreenWidth equ 40
ScreenHeight equ 25
ScreenObjWidth equ 160-2
ScreenObjHeight equ 200-8

UserRam Equ &8000				;System Memory

;CLS equ &BC14					;Clear Screen Function (Bios)

	nolist
;BuildCPC equ 1	; Build for Amstrad CPC

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	ifdef vasm
		include "\SrcALL\VasmBuildCompat.asm"
	else
		read "\SrcALL\WinApeBuildCompat.asm"
	endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	read "\SrcALL\CPU_Compatability.asm"

ShowTitle:
;Init Game Defaults
	ld a,3
	ld (lives),a		;Life count
	xor a
	ld (level),a		;Level number
	ld (PlayerObject),a	;Player Sprite
	call ChibiSound		;Mute sound

	call CLS			;Scr Clear

;Connect to Joystick/Keys
	ld de,ENT_Keboardname
	ld a,11					;Open the keyboard as stream 11
	rst 48					;EXOS
	db 1 					;Open stream	

;Turn off Keyclick
	ld c,7	;Var 7 - CLICK_KEY 
	ld d,1	;1=NoClick
	ld b,1	;0=Read 1=Write 2=Toggle
	rst 48
	db 16		; Read, Write or Toggle EXOS Variable 

	
;Show Title Screen	
	ld hl,TitlePic
	ld c,0
TitlePixNextY:
	ld b,0
TitlePixNextX:
	push bc		
	push hl
		ld a,(hl)				;Sprite number
		or a
		jr z,TitleNoSprite
		ld h,a
		push bc
			call GetSpriteAddr 	;H=spritenum
		pop bc
		sla b
		sla c
		sla c
		sla c
		call ShowSprite			;BC=XY HL=Sprnum
TitleNoSprite:
	pop hl
	inc hl
	pop bc
	inc b
	ld a,b
	cp 40						;Screen Width
	jr nz,TitlePixNextX	
	inc C
	ld a,c
	cp 24						;Screen Height
	jr nz,TitlePixNextY

	ld hl,&1202
	call Locate
	ld hl,txtFire			;Show Press Fire
	call PrintString

	ld hl,&0018
	call Locate
	ld hl,txtUrl			;Show URL
	call PrintString

	ld hl,&1818
	call Locate
	ld hl,txtHiScore
	call PrintString
	ld de,HiScore 			;Show the highscore
	ld b,4
	call BCD_Show


StartLevel:
	Call WaitForFire
	call CLS
	Call ResetPlayer
	call LevelInit
	

infloop:					;Main Loop
	ld bc,20				;Slow Down Delay
	ld d,0
PauseBC:
	push de
	push bc
		call ReadJoystick
	pop bc
	pop de
	or a
	jr z,PauseNoKey
	ld d,a					;Store any pressed joystick buttons
PauseNoKey:
	dec bc
	ld a,b
	or c
	jr nz,PauseBC
	ld a,d

StartDraw:
	push af
		push bc
			call DrawUi
			ld IX,PlayerObject
			call BlankSprite;Remove old player sprite
		pop bc
	pop af
	ld d,a

	ld hl,KeyTimeout
	ld a,(hl)
	or a
	jr z,ProcessKeys
	dec (hl)
	jp JoySkip			;skip player input
ProcessKeys:
	ld hl,PlayerAccY
	ld e,0				;Timeout

	ld a,d
	cp &B0
	jr nz,JoyNotUp		;Jump if UP not presesd
	ld a,(hl)
	sub 1				;Move Y Up the screen
	ld (hl),a
	ld e,5
JoyNotUp:
	ld a,d
	cp &B4
	jr nz,JoyNotDown		;Jump if DOWN not presesd
	ld a,(hl)
	add 1				;Move Y Down the screen
	ld (hl),a
	ld e,5
JoyNotDown:
	ld hl,PlayerAccX
	ld a,d
	cp &B8
	jr nz,JoyNotLeft 	;Jump if LEFT not presesd
	ld a,(hl)
	sub 1
	ld (hl),a			;Move X Left 
	ld e,5
JoyNotLeft:
	ld a,d
	cp &BC
	jr nz,JoyNotRight	;Jump if RIGHT not presesd
	ld a,(hl)
	add 1
	ld (hl),a			;Move X Right
	ld e,5
JoyNotRight: 
	ld a,d
	cp ' '
	jr nz,JoyNotFire		;Jump if Fire not presesd
	call PlayerFirebullet
JoyNotFire: 
	ld a,d
	cp 13	;enter
	jr nz,JoyNotFire2	;Jump if Fire2 not presesd
	xor a
	ld (PlayerAccX),a
	ld (PlayerAccY),a
JoyNotFire2: 
	ld a,e
	ld (KeyTimeout),a
JoySkip: 
	
	call DrawAndMove

	jp infloop

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

PrintCharB:					;Print Char A with Sprite Routine
	push bc
		sub 32				;No Char below 32
		ld h,a
		ld l,0
		
		srl h				;Font * 16
		rr l
		srl h
		rr l
		srl h
		rr l
		srl h
		rr l
		ld bc,FontData
		add hl,bc

		ld bc,(CursorY)		;Get XY into BC
		rl c				;Y*8
		rl c
		rl c
		rl b				;X*2
	jr ShowSpriteB
	
ShowSprite:					;Draw Sprite A at XY pos BC
	push bc
	jr ShowSpriteB

DoGetSpriteObj:				;Get Settings from Object IX
	push bc
		ld h,(IX+O_SprNum)	;Sprite Source
		call GetSpriteAddr
	
DrawBoth:
		ld b,(IX+O_Xpos)
		srl b				;Skip bottom bit of Xpos 
		ld c,(IX+O_Ypos)
ShowSpriteB:
		call GetScreenPos

		ld bc,&08FF			;Lines (Height)
SpriteNextLine:
		push de
SpriteNextByte:
			ldi				;Do 2 bytes of sprite
			ldi
		pop de
		call GetNextLine	;Scr Next Line (Alter HL to move down a line)
		djnz SpriteNextLine	;Repeat for next line
	pop bc
	ret		

BlankSprite:	
	ld a,(IX+O_CollProg)
	cp 250
	ret nc

	push bc
		ld hl,FontData			;Sprite Source (Space)
	jp DrawBoth

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

GetSpriteAddr:
		ld l,0				;Sprite Source
		
		srl h				;16 bytes per sprite
		rr l
		srl h
		rr l
		srl h
		rr l
		srl h
		rr l
		ld bc,SpriteData
		add hl,bc

		ld a,(SpriteFrame)	;Sprite frame (256 bytes per bank)
		add h
		ld h,a	
	ret

WaitForFire:
	call DoRandom		;Reseed Random Numbers
	call ReadJoystick
	cp ' '
	jr nz,WaitForFire

WaitForFireB:
	call DoRandom		;Reseed Random Numbers
	call ReadJoystick
	cp ' '
	jr z,WaitForFireB
	ret
	 
ReadJoystick:
	push bc
		ld a,11 			;Keyboard is channel 11
		rst 48				;EXOS call
		db 9 				;Channel Read Status
		;Result in C (0=Byte waiting / 1=no byte / FF=StreamEnd)
			
		ld a,c				
		or a				;0=ready
		ld a,0				;return zero if z flag not set
		jr nz,TestChar_NoCharWaiting
		
		;Get the waiting character
		ld a,11 			;Keyboard is channel 11
		rst 48				;EXOS call
		db 5 				;Read from channel - result in b
		ld a,b
TestChar_NoCharWaiting:
	pop bc
	ret

cls:
	ld hl,&C000
	ld de,&C001
	ld bc,&3E80
	ld (hl),0
	ldir
	
	ret

GetScreenPos:	;return memory pos in HL of screen co-ord B,C (X,Y)
				;Input  BC= XY (x=bytes - so 80 across)
				;Output HL= screen mem pos
	push hl
;screen is 80 wide = 00000000 01010000
		ld d,C		;YYYYYYYY 00000000
		xor a
		
		srl d
		rra			;0YYYYYYY Y0000000
		srl d
		rra 		;00YYYYYY YY000000
		
		ld h,d
		ld l,a		;Store first part for later
		
		srl d
		rra			;000YYYYY YYY00000
		srl d
		rra			;0000YYYY YYYY0000
		
		add l
		jr nc,GetScreenPos_NoOverflow
		inc d
GetScreenPos_NoOverflow:
		add B		;Add the X pos 
		ld e,a
		
		ld a,d
		adc h
		add &C0		;Add screen Base &C000
		ld d,a	
	pop hl
	ret 			;return memory location in hl


	
GetNextLine:
	push af
		ld a,e	
		add &50		;each line is 80 bytes wide
		ld e,a
		jr nc,GetNextLineDone
		inc d		;Deal with overflow if needed
GetNextLineDone:
	pop af
	ret

	
	;The code below was based on an example from the Enterprise forever forum
ScreenINIT:
	di
	LD A,12		;disable memory wait states
	OUT (191),A	

	;setting the Border color to black

	LD BC,&100+27	;B=1 write
	;C=27 number of system variable (BORDER)	
	LD D,0			;new value
	rst 6*8
	db 16			;handling EXOS variable

	CALL BankSwitch_RequestVidBank	;get a free Video segment
	Jr NZ,VideoFail	;if not available then exit
	LD A,C		
	LD (VIDS),A		;store segment number page to the page 3.
	OUT (&B3),A		

	LD DE,0			;segment number low two bits
	RRA				;will be the top two bits of the video address
	RR D			
	RRA				
	RR D			
	LD (VIDADR1),DE ;this is the start of pixel data in the video memory

	LD HL,&3F00		;after the pixel bytes starting the Line Parameter Table (LPT)
	ADD HL,DE	
	LD (LPTADR),HL	
		
	LD HL,LPT		;Line Parameter Table copy to the end of video segment
	LD DE,&FF00	
	LD BC,LPTH	
	LDIR		
VidAgain:		
	LD HL,(LPTADR)	;LPT video address
	LD B,4			;4 bit rotate
LPTA: SRL H
	RR L
	DJNZ LPTA
	LD A,L			;low byte send to Nick
	OUT (&82),A	
	LD A,H			;high 4 bits enable Nick running
	OR &C0		
	
	;switch to the new LPT at the end of current frame send to Nick
	OUT (&83),A	
			
VideoFail:
	ret



BankSwitch_RequestVidBank:           
	LD HL,FileEnd		;buffer area
	LD (HL),0			;start of the list
GetSegment:	
	rst 6*8				;get a free segment
	db 24			
	RET NZ				;if error then return
	LD A,C				;segment number
	CP &FC				;<0FCh?, no video segment?
	JR NC,ENDGET		;exit cycle if video
	INC HL				;next buffer address
	LD (HL),C			;store segment number
	JR GetSegment		;get next segment
ENDGET: 
	PUSH BC				;store segment number
FREES:	LD C,(HL)		;deallocate onwanted

		rst 6 *8
		db 25			;free non video segments

		DEC HL			;previoud buffer address
		JR Z,FREES		;continue deallocating when call the EXOS 25 function with
		;c=0 which is stored at the start of list, then got a error, flag is NZ
		
	POP BC				;get back the video segment number
	XOR A				;Z = no error
	ret


;NICK Line Parameter Table (LPT)

LPT: DB 256-200		;Screen Size: 200 lines.... 
					;Two's complement of the number of scanlines in this mode line.
	   ;ICCRMMML
	db %00110010   		;I   VINT=0, no IRQ
						;CC  Colour Mode=01, 4 colours mode (2/4/16/256)
						;R   VRES=1, full vertical resolution (full/half)
						;MMM Video Mode=001, pixel graphics mode
						;L   Reload=0, LPT will continue
	
	DB 11   		;left margin=11
	DB 51  			;right margin=51
VIDADR1:  DW 0    	;primary video address, address of pixel data
	DW 0  			;secondary vide0 address, not used in pixel graphics mode
ENT_PALETTE:	
	; 	GRBGRBGR  	;g0 | r0 | b0 | g1 | r1 | b1 | g2 | r2 | - x0 = lsb 
	db %00000000	;Color 0: Black
	db %00001100	;Color 1: Purple
	db %11110010	;Color 2: Lt Green
	db %11111111	;Color 3: White
	db 0,0,0,0 		;Colors 4-7 (unused)

;Line definitions			
	DB -50,&12,63,0,0,0,0,0,0,0,0,0,0,0,0,0	;50 lines of border, this is the bottom margin,
	DB -3,16,63,0,0,0,0,0,0,0,0,0,0,0,0,0	;3 black lines, syncronization off
	DB -4,16,6,63,0,0,0,0,0,0,0,0,0,0,0,0	;4 lines, syncronization on
	DB -1,&90,63,32,0,0,0,0,0,0,0,0,0,0,0,0	;1 line, syncronization will switch off at half of line
												;the NICK chip generate video IRQ at this line
	DB 252,&12,6,63,0,0,0,0,0,0,0,0,0,0,0,0 ;4 black lines
	DB -50,&13,63,0,0,0,0,0,0,0,0,0,0,0,0,0 ;50 lines of border, this is the top margin,
LPTEnd:              
LPTH equ LPTEnd-LPT ;length of LPT
	
VIDS:		DB 0	;variables for storing allocated memory
LPTADR:     DW 0		
	

	
ENT_Keboardname: db 9,'KEYBOARD:'

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
		
	read "YQ_DataDefs.asm"
	read "YQ_RamDefs.asm"
	read "YQ_Multiplatform.asm"
	
	read "\SrcALL\Multiplatform_ChibiSound.asm"			;Sound Driver
	read "\SrcALL\MultiPlatform_ShowDecimal.asm"		;Show decimal numbers
	read "\SrcALL\Multiplatform_BCD.asm"				;Show Binary Coded Decimal

SpriteData:
	incbin "\ResALL\Yquest\CPC_YQuest.raw"
	incbin "\ResALL\Yquest\CPC_YQuest2.raw"
	incbin "\ResALL\Yquest\CPC_YQuest3.raw"
	incbin "\ResALL\Yquest\CPC_YQuest4.raw"
	
FontData:												;Bitmap Font (4 color)
	incbin "\ResALL\Yquest\FontCPC.raw"
	
Palette:
	db 0,5,19,26			;Palette in native format
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FileEnd: