
ScreenWidth32 equ 1
ScreenWidth equ 32
ScreenHeight equ 24
ScreenObjWidth equ 128-4
ScreenObjHeight equ 192-8

UserRam Equ &C000


;CLS equ &BC14		

	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"



VdpIn_Status 	equ &99
VdpOut_Control 	equ &99
VdpOut_Indirect equ &9B
Vdp_SendByteData equ &9B	
VdpOut_Palette equ &9A

;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

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 user Ram
	ld de,UserRam+1
	ld bc,&800
	ld (hl),0
	ldir
	

	ld de, 0		;Tile 0 (Tiles start 512 lines down)
	ld hl,BitmapData		;Font+Sprites
	ld bc,BitmapDataEnd-BitmapData
	call DefineTiles		;Copy the tiles to the VDP
	
	
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

;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
		add 96
		sla b
		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 ScreenWidth
	jr nz,TitlePixNextX	
	inc C
	ld a,c
	cp ScreenHeight
	jr nz,TitlePixNextY

	ld hl,&0D10
	call Locate
	ld hl,txtFire			;Show Fire
	call PrintString
	
	ld hl,&1202
	call Locate
	ld hl,txtUrl			;Show URL
	call PrintString

	ld hl,&1000
	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
	
	ld a,0					;Dummy Key value 
	JR StartDraw

infloop:
	ld bc,150
	ld d,0
PauseBC:
	push de
	push bc
		call ReadJoystick 	;KM Get Joystick... Returns ---FRLDU
	pop bc
	pop de
	
	or a
	jr z,PauseNoKey
	ld d,a
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 in E
	ld a,d
	cp 1
	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 5
	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 7
	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 3
	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,1
	call &00D8			;Read Joystick
	cp 255
	jr nz,JoyNotFire	;Jump if Fire not presesd
	call PlayerFirebullet
JoyNotFire: 
	ld a,3
	call &00D8
	cp 255
	jr nz,JoyNotFire2	;Jump if Fire2 not presesd
	xor a
	ld (PlayerAccX),a	;Stop Motion
	ld (PlayerAccY),a
JoyNotFire2: 
	ld a,e
	ld (KeyTimeout),a	;Update Timeout if a key was pressed
JoySkip: 
	call DrawAndMove

	jp infloop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
PrintCharB:
	push bc
		sub 32				;No Char below space
		ld bc,(CursorY)		;Get X and Y
		rl c				;Y*8
		rl c
		rl c
		rl b				;X*4
		rl b
	jr ShowSpriteB
	
ShowSprite:
	push bc
	jp ShowSpriteB

DoGetSpriteObj:
	push bc
		ld a,(SpriteFrame)
		rlca
		rlca
		rlca
		rlca
		ld h,a
		ld a,(IX+O_SprNum)		;Sprite Source
		add h
		add 96
DrawBoth:
		ld b,(IX+O_Xpos)
		ld c,(IX+O_Ypos)
ShowSpriteB:					;A=SprNum
		di	
			push iy
			push ix
			push de
			push hl
				ld e,a
				ld d,0
				and %00011111	;Get the Xpos, 32 tiles per 256 pixel line, so keep 5 bits
				rlca
				rlca
				rlca
				ld ixh,0
				ld ixl,a
				ld a,e
				and %11100000	;Get the Ypos, need to skip the first 5 bits,
				rr d			;Note we're only currently supporting MAX 256 tiles
				rr a
				rr d
				rr a
				ld iyh,2
				ld iyl,a
							
				ld a,b
				rlca
				exx
					ld h,0		;Xdest
					ld l,a
				exx
				ld a,c
				exx
					ld d,0		;YDest
					ld e,a
				exx
				ld hl,8			;Width
				ld de,8			;Height
				
				call VDP_HMMM_ViaStack		;Fast Copy Vram->Vram
			pop hl
			pop de
			pop ix
			pop iy	
	pop bc
	ret

BlankSprite:	
	ld a,(IX+O_CollProg)
	cp 250
	ret nc
	push bc
		ld a,0		;Sprite 0
	jp DrawBoth

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

GetSpriteAddr:
		ld a,h
		add 96				;Sprites follow the Font
		ld h,a
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BitmapData:
FontData:
	incbin "\ResALL\Yquest\MSX2_Font.raw"

SpriteData:
	incbin "\ResALL\Yquest\MSX2_YQuest.raw"
	incbin "\ResALL\Yquest\MSX2_YQuest2.raw"
	incbin "\ResALL\Yquest\MSX2_YQuest3.raw"
	incbin "\ResALL\Yquest\MSX2_YQuest4.raw"
BitmapDataEnd:

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

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
	call &00D8				;Read Trigger
	cp 255
	jr z,WaitForFire

WaitForFireB:
	call DoRandom
	ld a,1
	call &00D8				;Read Trigger
	cp 255
	jr nz,WaitForFireB
	ret
	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Transfer 8x8 tiles from ROM to Vram 
; Source=HL, DEST = DE Bytes=BC
DefineTiles:
	push iy
	push ix
	push de
	push bc
		ld a,(hl)			;Load in the first byte of the data to copy for writing to the VDP
		push hl
			push af
				ld a,e
				and %00011111	;Get the Xpos, 32 tiles per 256 pixel line, so keep 5 bits
				rlca
				rlca
				rlca
				ld ixh,0		;Destination X
				ld ixl,a
				ld a,e
				and %11100000	;Get the Ypos, need to skip the first 5 bits,
				rr d			;Note we're only currently supporting MAX 256 tiles
				rr a
				rr d
				rr a
				ld iyh,2		;Destination Y
				ld iyl,a
				di				;Stop interrupts, and wait for the VDP to finish it's last job
				call VDP_FirmwareSafeWait	
			pop af
			ld c,a				;First byte
			ld hl,8		;Width
			ld de,8		;Height
			call VDP_HMMC_Generated_ViaStack
			ei
		pop hl
	pop bc
	pop de
	pop ix
	pop iy
	inc hl				;We wrote one byte already
	dec bc				;so alter HL and BC
CopyTilesToVdp_Again:		
	ld a,(hl)
	out (Vdp_SendByteData),a	;Copy all the other bytes to the area with OUTs
	inc hl
	dec bc
	ld a,b
	or c
	ret z
	ld a,c
	and %00011111
	jr nz,CopyTilesToVdp_Again					
	inc de				;We've finished a tile, so start the next one
	jp DefineTiles
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Draw sprites ingame (Vram->Vram)	

VDP_HMMM_ViaStack:		;Fast copy from VRAM to VRAM

		ld bc,&00D0		;Command Byte (don't change)
		push bc
		push bc			;unused
		push de			;Height
		push hl			;Width
		exx
			push de		;DestY
			push hl		;DestX
		exx
		push iy			;SourceY
		push ix			;SourceX
		
		ld hl,0
		add hl,sp		;Load Stack into HL
		
		push hl
			call VDP_FirmwareSafeWait	;Wait for VDP to be ready
			call VDP_HMMM
		pop hl
		
		ld bc,16		;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
				
VDP_HMMM:				;Fast copy from VRAM to VRAM

	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	
	ret														  ;outi x 15
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;Transfer sprites to VRAM from ROM	
		
VDP_HMMC_Generated_ViaStack:	;Fill ram from calculated values (first in A)

		ld bc,&00F0		;Command Byte (don't change)
		push bc
		ld c,a			;First Pixel (B unused)
		push bc
		push de			;Height
		push hl			;Width
		push iy			;Ypos
		push ix			;Xpos
		
		ld hl,0
		add hl,sp
		push hl
			call VDP_HMMC_Generated
		pop hl
		
		ld bc,12	;Skip 8 pairs of vars pushed onto the stack
		add hl,bc
		ld sp,hl
		ret
		
VDP_HMMC_Generated:		;Fill ram from calculated values (first in A)

	;Set the autoinc for more data
	ld a,36				;AutoInc From 36
	call SetIndirect
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3
	defb &ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3,&ED,&A3			; 11 outis
	
	ld a,128+44			;128 = NO Increment ;R#44    Color byte (from CPU->VDP)
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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
Cls:		
	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 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						 ;outi x 11
	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
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	;Wait for VDP to be ready
VDP_FirmwareSafeWait:
	di
	call VDP_Wait						;Wait for the VDP to be available
	call VDP_GetStatusFirwareDefault	;Reset selected Status register to 0 for the firmware
	ret

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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;Set 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
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

	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
	;read "\SrcALL\Multiplatform_ShowHex.asm"			;Hex Display
	
	;Settings to define our graphics screen

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/character colour at text mode
	db %00001010,128+8		;mode register #2
	db %00000000,128+9	 	;mode register #3
	db 128		,128+10		;colour table (HIGH)
VDPScreenInitData_End:	

palette:	
	dw %0000000000000000; ;0  %-----GGG-RRR-BBB
	dw %0000011100000000; ;1  %-----GGG-RRR-BBB
	dw %0000001000100010; ;2  %-----GGG-RRR-BBB
	dw %0000010101010101; ;3  %-----GGG-RRR-BBB
	dw %0000011101110111; ;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
