
DefineGameTiles:		;Set up sprite Tiles for gameplay

	ld IY,BitmapData	;Game Sprites
	ld de,&0
	ld H,166
	ld l,2
	call DefineSpriteA	;DE=VDP address, IY=Source,H*L=Tiles to copy
	
	ld IY,FontData		;Font+Cursors
	ld de,333*32
	ld H,4
	ld l,26
	call DefineSpriteA	;DE=VDP address, IY=Source,H*L=Tiles to copy
	ret
	

DefineSpriteA:	;DE=VDP address, IY=Source,H*L=Tiles to copy
	di
	ex de,hl
	call prepareVram	;Set VRAM address we want to write to
	ex de,hl
SpriteNextL:
	ld c,h
SpriteNextH:	
	ld b,8
DefineLine:
	ld a,(iy)
	out (vdpData),a		;Send Byte to VRAM
	inc iy
	ld a,(iy)
	out (vdpData),a		;Send Byte to VRAM
	inc iy
	xor a
	out (vdpData),a		;Send Byte to VRAM (0)
	nop
	out (vdpData),a		;Send Byte to VRAM (0)
	djnz DefineLine
	dec c
	jr nz,SpriteNextH
	dec l
	jr nz,SpriteNextL
	ret
	
;Alt version for Tilemap
DefineSpriteDoubleHeight:	;DE=VDP address, IY=Source,H=Width,L=Height
	di
	ex de,hl
	call prepareVram	;Set VRAM address we want to write to
	ex de,hl
SpriteNextLb:
	ld c,h
SpriteNextHb:	
	ld b,4
DefineLineb:
	ld a,(iy)
	out (vdpData),a		;Send Byte to VRAM
	inc iy
	ld a,(iy)
	out (vdpData),a		;Send Byte to VRAM
	dec iy
	xor a
	out (vdpData),a		;Send Byte to VRAM
	nop
	out (vdpData),a		;Send Byte to VRAM
	
	ld a,(iy)
	out (vdpData),a		;Send Byte to VRAM
	inc iy
	ld a,(iy)
	out (vdpData),a		;Send Byte to VRAM
	inc iy
	xor a
	out (vdpData),a		;Send Byte to VRAM
	nop
	out (vdpData),a		;Send Byte to VRAM
	
	djnz DefineLineb
	dec c
	jr nz,SpriteNextHb
	dec l
	jr nz,SpriteNextLb
	ret
			
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


SetHardwareSprite:	;A=Hardware Sprite No. B,C = X,Y , D,E = Source Data, H=Palette etc
	push hl
	push de
	push af	
			push af
				ld h,&3F			;first byte is at &3F00
				ld l,a				;1 byte per tile - so load L with sprite number
				call prepareVram	;Get the memory address so we can write to it
				ld a,c				;Y pos
				out (vdpData),a
			pop af
			
			rlca					;2 bytes per tile - 1'st is X, 2nd is tile number
			ld h,&3F
			add &80					;next data Starts from &3F80
			ld l,a
			call prepareVram		;Get the memory address so we can write to it
			
			ld a,b					;X Pos
			out (vdpData),a
			ld a,e					;tile number
			out (vdpData),a
	pop af
	pop de
	pop hl
WaitForScreenRefresh:
	ret
	

GetScreenPos:	;return memory pos in HL of screen co-ord B,C (X,Y)
	ld a,b
	srl a
	srl a
	ld (SXpos),a
	
	ld a,e
	inc a
	srl a
	ld (SXCrop),a
	
	ld a,c
	srl a
	srl a
	srl a
	ld (SYpos),a
	ret	
		

PrintCharB:					;Print Char A with Sprite Routine
		add 77+4+1
		ld (CharTileMap+1),a
		ld a,255
		ld (CharTileMap),a
				
		ld bc,(CursorY)		;Get XY into BC
		ld iy,SprChar

		rl c
		rl c
		rl b				
		rl b

		ld a,b
		add 48+2	
		ld  (IY+O_Xpos),a

		ld a,c
		add 2
		ld  (IY+O_Ypos),a
		
		ld a,(CursorZ)
		ld  (IY+O_Zpos),a
			
		ld hl,CharInfo
		ld (SpriteDataHL),hl
		ld a,0
		ld (SprChar+O_SprNum),a
		
		jp DrawSpriteFromIY
		
SetRemoveSpriteForceRedraw:	
	ld a,1
	ld (SMSDoForceRedraw),a
SetRemoveSprite:
	ld a,1
	jr SetDrawSpriteB
SetDrawSprite:
	xor a
SetDrawSpriteB:	
	ld (SMSDoRemoveSprite),a
	ret
	
ShowSpriteR:
	ld ixh,CachTilesR		;Right Eye Cache
	jp ShowSpriteR2	
ShowSpriteL:
	ld ixh,CachTilesL		;Left Eye Cache
ShowSpriteR2:	
	ld c,ixl	;Bytes per line (Width)
	
	ld a,(IY+O_SprNum)			;Sprite Num
	add (IY+O_SprH)
	and %00111111
	push iy
		push ix
			ld ix,(SpriteDataHL)
			ld d,0
			rlca
			rlca
			ld e,a
			add ix,de

			ld e,(ix+0)			;Xpos
			ld d,(ix+1)			;Ypos
			
			ld h,(ix+2)			;Wid
			ld l,(ix+3)			;Hei
			srl l
			srl l
			srl l				;Y Pixels-> Tiles
			
			srl h
			srl h
			srl h				;X Pixels-> Tiles
		pop ix
		
		srl c
		ld ixl,c
		
		ld a,ixl
		or a
		jr z,SprFinish		;Width=0
		
		ld a,(SXpos)
		ld b,a
		ld a,(SYpos)
		ld c,a
		
		ld a,(SXCrop)
		or a
		call nz,DoLineCrop
		
		ld a,ixl
		add b				;Calculate end Xpos
		ld iyh,a
				
		ld a,l				;Calculate End Ypos
		add c
		ld iyl,a
				
		ld a,(SMSDoRemoveSprite)		;Zero Tilemap Here
		or a
		jr z,FillAreaWithTiles2_Yagain
		ld de,ZeroTileMap
FillAreaWithTiles2_Yagain:	;DE=Tilemap ;BC=XYpos ; iyh=XEnd IYL=Yend ;iXH=Cache
		push bc
			call GetCacheScreenPos	;Move to the correcr VDP location
			push ix
FillAreaWithTiles2_Xagain:;Tilemap takes two bytes, ---pcvhn nnnnnnnn
				ld a,(de)
				inc de
				ld ixh,0
				ld ixl,a
				
				cp 255 
				jr nz,TileLowBank
				ld a,(de)				;Get High Byte
				inc de
				push bc
					ld b,0
					ld c,a
					add ix,bc
				pop bc
TileLowBank:							;Update The tilecache
			ld a,ixl		;nnnnnnnn - Tile number
			ld (hl),a	
			inc hl
			ld a,ixh		;---pcvhn - p=Priority (1=Sprites behind) C=color palette 
			ld (hl),a		;(0=back 1=sprite), V=Vert Flip, H=Horiz Flip, N=Tilenum (0-511)
			inc hl
			inc b			;Increase Xpos
			ld a,b
			cp iyh			;Are we at the end of the X-line?
			jr nz,FillAreaWithTiles2_Xagain
			pop ix
		pop bc
		
		ld a,(SpriteHClipPlus2-2)
		inc a
		srl a
		call nz,DoLineCrop		;Do Cropping.
	
		inc c				;Increase Ypos
		ld a,c
		cp iyl				;Are we at the end of the height Y-line?
		jr nz,FillAreaWithTiles2_Yagain
		
		xor a
		ld (SpriteHClipPlus2-2),a
SprFinish:		
	pop iy
	doei	
	ret
	
DoLineCrop:
	push bc
		ld b,a				;Do the crop (miss some tiles)
LineCropAgain:		
		ld a,(de)
		inc de
		cp 255
		jr z,LineCropAgain	;Remove the second byte
		djnz LineCropAgain
	pop bc
	ret
	
	
;This will load into an XY pos into a 'Cached' tilemap 
	;at memory address &XX00 where X=IXH 
GetCacheScreenPos:	;Move to a memory address in VDP by BC cursor pos
	push bc				;B=Xpos, C=Ypos
		ld h,c
		xor a			
		rr h			;Multiply Y*64
		rra
		rr h
		rra
		rlc b			;Multiply X*2 (Two byte per tile)
		or b
		ld l,a
		ld a,h
		add ixh			;Address of TileMap &3800 
		ld h,a			;(32x28 - 2 bytes per cell = &700 bytes)
	pop bc
	ret	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
	
ShowTileMapAltPosQtrIntro:	;HL=Tilemap BC=Tile Data IYH=X	A=Y 	;E=Height ;D=Wid	
	push ix
		ex de,hl

		ld c,a
		ld a,iyh
		ld b,a
		push bc
		push de
			ld ixh,CachTilesR
			call FillAreaWithTilesCustomQ
		pop de
		pop bc
		ld ixh,CachTilesL
		call FillAreaWithTilesCustomQ
	pop ix
	ret
FillAreaWithTilesCustomQ:
	ld iy,&100C
	add iy,bc
	
FillAreaWithTilesCustom:					;DE=Tilemap ;BC=XYpos ; iyh=XEnd IYL=Yend ;iXH=Cache
	push iy
	jp FillAreaWithTiles2_Yagain
	
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							;this does not cause a problem
	
	

PrintSpace:
	ld a,' '
Printchar:
	push af
	push ix
	push bc
	push hl
	push de
		sub 32				;No Char below 32
		ld bc,FontData
PrintTileb:
		call PrintCharB
PrintTilec:
		ld hl,CursorX
		inc (hl)
		ld hl,SpriteInfo
		ld (SpriteDataHL),hl
	pop de
	pop hl
	pop bc
	pop ix
	pop af
	ret
	