CollisionMaskY equ %11111000	;Masks for un-drawable co-ordinates 
CollisionMaskX equ %11111100


	Ifdef BuildSMS
ScreenWidth32 equ 1
ScreenWidth equ 32
ScreenHeight equ 24
ScreenObjWidth equ 128-2
ScreenObjHeight equ 192
	endif
	
	ifdef BuildSGG
ScreenWidth20 equ 1
ScreenWidth equ 20
ScreenHeight equ 18
ScreenObjWidth equ 80-2
ScreenObjHeight equ 144
	endif

UserRam Equ &C000		;Game Vars
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	ifdef vasm
		include "\SrcALL\VasmBuildCompat.asm"
	else
		read "\SrcALL\WinApeBuildCompat.asm"
	endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	read "\SrcALL\CPU_Compatability.asm"

vdpControl equ &BF
vdpData    equ &BE

	org &0000
	jr ProgramStart		;&0000 - RST 0
	ds 6,&C9			;&0002 - RST 0
	ds 8,&C9			;&0008 - RST 1
	ds 8,&C9			;&0010 - RST 2
	ds 8,&C9			;&0018 - RST 3
	ds 8,&C9			;&0020 - RST 4
	ds 8,&C9			;&0028 - RST 5
	ds 8,&C9			;&0030 - RST 6
	ds 8,&C9			;&0038 - RST 7
	ds 38,&C9			;&0066 - NMI
	ds 26,&C9			;&0080
						
	; effective Start address &0080
ProgramStart:	
    im 1    			;Interrupt mode 1
    ld sp, &dff0		;Default stack pointer

	;Init the screen 												
	ld hl,VdpInitData	;Source of data
    ld b,VdpInitDataEnd-VdpInitData		;Byte count
    ld c,vdpControl		;Destination port
    otir				;Out (c),(hl).. inc HL... dec B, djnz 

	;Define Palette 
    ld hl, &c000	    ; set VRAM write address to CRAM (palette) address 0
		; note &C0-- is a set palette command... it's not a literal memory address 
    call prepareVram

    ld hl,PaletteData	;Source of data
	ifdef BuildSGG
		ld b,16*2 		;Byte count (32 on SGG)
	else
		ld b,16			;Byte count (16 on SMS)
	endif
	ld c,vdpData		;Destination port
	otir				;Out (c),(hl).. inc HL... dec B, djnz  
	
	;Copy bitmap to tilemap
	ld de, 0*8*4			;8 lines of 4 bytes per tile
	ld hl, BitmapData		;Source Address of sprite data
	ld bc, BitmapDataEnd-BitmapData ; Length of sprite data
	call DefineTiles		;Send data to VRAM
	
	ld hl,UserRam		;Clear Game Ram
	ld de,UserRam+1
	ld bc,&1000
	ld (hl),0
	ldir


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;										Our program													

	

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
	
	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
			ld h,a
			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

	ifdef ScreenWidth20
		ld hl,&0900
	else
		ld hl,&0D10
	endif
	call Locate
	ld hl,txtFire			;Show Press Fire
	call PrintString

	ifdef ScreenWidth20
		ld hl,&0804
	else
		ld hl,&1202
	endif
	call Locate
	ld hl,txtUrl			;Show URL
	call PrintString

	ifdef ScreenWidth20
		ld hl,&0411
	else
		ld hl,&1000
	endif
	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:	
	ld bc,1000
	ld d,0
PauseBC:
	push de
	push bc
		call ReadJoystick 	;Read from Joystick
	pop bc
	pop de
	cp %00111111
	jr z,PauseNoKey
	ld d,a
PauseNoKey:
	dec bc
	ld a,b
	or c
	jr nz,PauseBC
	
StartDraw:
	push de
		push bc
			call DrawUi
			ld IX,PlayerObject
			call BlankSprite;Remove old player sprite
		pop bc
	pop de
	
	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
	bit 0,d
	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:
	bit 1,d
	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
	bit 2,d
	jr nz,JoyNotLeft 	;Jump if LEFT not presesd
	ld a,(hl)
	sub 1
	ld (hl),a			;Move X Left 
	ld e,5
JoyNotLeft:
	bit 3,d
	jr nz,JoyNotRight	;Jump if RIGHT not presesd
	ld a,(hl)
	add 1
	ld (hl),a			;Move X Right
	ld e,5
JoyNotRight: 
	bit 4,d
	jr nz,JoyNotFire	;Jump if Fire not presesd
	call PlayerFirebullet
JoyNotFire: 
	bit 5,d
	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:					;Print a Font Char Sprite 
	push bc	
		sub 32				;No Character below 32
		ld h,a
		ld bc,(CursorY)		;Get Xy Pos
	jr ShowSpriteB
	
ShowSprite:	
	push bc					;Show Sprite A	
	jr ShowSpriteB
	
DoGetSpriteObj:
	push bc
		ld a,(SpriteFrame)	;Show Sprite of Objec XY
		rlca				;SpriteFrame*16 (16 sprites per bank)
		rlca
		rlca
		rlca
		ld h,a
		ld a,(IX+O_SprNum)	;Sprite Source
		add 96
		add h
		ld h,a
DrawBoth:
		ld b,(IX+O_Xpos)	;Skip unusable bits of XYpos 
		srl b					;(limit to 8x8 tile)
		srl b
		ld c,(IX+O_Ypos)
		srl c
		srl c
		srl c
ShowSpriteB:
			call GetVDPScreenPos;Move to the correcr VDP location
			ld a,h
			out (vdpData),a	;Tilemap takes two bytes,nnnnnnnn - Tile number
			ld a,0			;---pcvhn p=Priority (1=Sprites behind) C=color palette
			out (vdpData),a	;(0=back 1=sprite), V=Vert Flip, H=Horiz Flip, N=Tilenum (0-511)
	pop bc
	ret		

BlankSprite:	
	ld a,(IX+O_CollProg)
	cp 250					;don't draw if CollProg is >=250
	ret nc

	push bc
		ld h,0
	jp DrawBoth

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CLS:
	ld c,0
CLSNextY:
	ld b,0
CLSNextX:
	push bc		
		push hl
			ld h,0			;Zero TRile
			call ShowSprite ;BC=XY HL=Sprnum
		pop hl
		inc hl
	pop bc
	inc b
	ld a,b
	cp 32					;Screen Width
	jr nz,CLSNextX	
	inc C
	ld a,c
	cp 24					;Screen Height
	jr nz,CLSNextY

	ret	

	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DefineTiles:	;DE=VDP address, HL=Source,BC=Bytecount
	ex de,hl
	call prepareVram	;Set VRAM address we want to write to
	ex de,hl
DefineTiles2:
	ld a,(hl)
	out (vdpData),a		;Send Byte to VRAM
	inc hl
	dec bc				;Decrease counter and see if we're done
	ld a,b
	or c
	jr nz,DefineTiles2
	ret
	
prepareVram:				;Set vdpData to write to memory address HL in vram
	    ld a,l
	    out (vdpControl),a
	    ld a,h
	    or &40				;we set bit 6 to define that we want to Write data...
	    out (vdpControl),a	;As the VDP ram only goes from &0000-&3FFF 
    ret		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GetVDPScreenPos:	;Move to a memory address in VDP by BC cursor pos
	push hl
	push bc				;B=Xpos, C=Ypos
		ifdef BuildSGG
			ld a,c
			add 3		;Need add 3 on Ypos for GG to reposition screen
			ld h,a
		else 
			ld h,c
		endif
		xor a			
		rr h			;Multiply Y*64
		rra
		rr h
		rra
		rlc b			;Multiply X*2 (Two byte per tile)
		or b
		ifdef BuildSGG
			add 6*2		;Need add 6 on Xpos for GG to reposition screen
		endif
		ld l,a
		ld a,h
		add &38			;Address of TileMap &3800 
		ld h,a				;(32x28 - 2 bytes per cell = &700 bytes)
		call prepareVram
	pop bc
	pop hl
	ret
		
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BitmapData:
FontData:
	incbin "\ResALL\Yquest\FontSMS.raw"

SpriteData:
	incbin "\ResALL\Yquest\SMS_YQuest.raw"
	incbin "\ResALL\Yquest\SMS_YQuest2.raw"
	incbin "\ResALL\Yquest\SMS_YQuest3.raw"
	incbin "\ResALL\Yquest\SMS_YQuest4.raw"
BitmapDataEnd:

	

ReadJoystick:
		in a,(&DC)	;UD are in Player1's port	---FRLDU 0=Down 1=up
	ret
	
WaitForFire:
	call DoRandom
	call ReadJoystick 			; KM Get Joystick... Returns ---FRLDU
	and %00010000
	jr nz,WaitForFire

WaitForFireB:
	call DoRandom
	call ReadJoystick 			; KM Get Joystick... Returns ---FRLDU
	and %00010000
	jr z,WaitForFireB
	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

	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;					VDP Register settings (needed to turn on screen)							
	
VdpInitData:
	db %00000110,128+0 ; reg. 0, display and interrupt mode.
	db %11100001,128+1 ; reg. 1, display and interrupt mode.
	db &ff		,128+2 ; reg. 2, name table address. &ff = name table at &3800
	db &ff		,128+3 ; reg. 3, Name Table Base Address  (no function) &0000
	db &ff 		,128+4 ; reg. 4, Color Table Base Address (no function) &0000
	db &ff		,128+5 ; reg. 5, sprite attribute table. -DCBA98- = bits of address $3f00
	db &00		,128+6 ; reg. 6, sprite tile address. -----D-- = bit 13 of address $2000
	db &00		,128+7 ; reg. 7, border color. 			----CCCC = Color
	db &00 		,128+8 ; reg. 8, horizontal scroll value = 0.
	db &00		,128+9 ; reg. 9, vertical scroll value = 0.
	db &ff 		,128+10; reg. 10, raster line interrupt. Turn off line int. requests.
VdpInitDataEnd:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;								Basic palette in native format									
	
PaletteData:
	ifdef BuildSGG					;SGG
		dw &0000; ;0  -BGR
		dw &00F1; ;1  -BGR
		dw &0555; ;2  -BGR
		dw &0AAA; ;3  -BGR
		dw &0FFF; ;4  -BGR
		dw &0682; ;5  -BGR
		dw &03D3; ;6  -BGR
		dw &033E; ;7  -BGR
		dw &067E; ;8  -BGR
		dw &05AE; ;9  -BGR
		dw &04FF; ;10  -BGR
		dw &0A2A; ;11  -BGR
		dw &0F0F; ;12  -BGR
		dw &0D30; ;13  -BGR
		dw &0B63; ;14  -BGR
		dw &0FD0; ;15  -BGR
	else 							;SMS
		db %00000000; ;0  --BBGGRR
		db %00001100; ;1  --BBGGRR
		db %00010101; ;2  --BBGGRR
		db %00101010; ;3  --BBGGRR
		db %00111111; ;4  --BBGGRR
		db %00011000; ;5  --BBGGRR
		db %00001100; ;6  --BBGGRR
		db %00000011; ;7  --BBGGRR
		db %00010111; ;8  --BBGGRR
		db %00011011; ;9  --BBGGRR
		db %00011111; ;10  --BBGGRR
		db %00100010; ;11  --BBGGRR
		db %00110011; ;12  --BBGGRR
		db %00110000; ;13  --BBGGRR
		db %00100100; ;14  --BBGGRR
		db %00111100; ;15  --BBGGRR
	endif

	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;										Footer													

	
	org &7FF0
	db "TMR SEGA"	;Fixed data (needed by some SGG)
	db 0,0			;Reserved
	db &69,&69		;16 bit Checksum (sum of bytes $0000-$7FEF... Little endian)
					;Only needed for 'Export SMS', not checked by emulator without bios
	db 0,0,0 		;BCD Product Code & Version
	
	ifdef BuildSGG	;Region & Rom size (see below) - only checked by SMS export bios
		db &6C		;GG Export - 32k
	else
		db &4C		;SMS Export - 32k
	endif

;&3- SMS Japan 
;&4- SMS Export 
;&5- GG 	Japan 
;&6- GG 	Export 
;&7- GG 	International 
;&-C 32KB   
;&-F 128KB   
;&-0 256KB   
;&-1 512KB

 