	nolist
	;Unrem this if building with vasm
;	include "\SrcALL\VasmBuildCompat.asm"

PrintChar 	equ &BB5A	

	org &100	
	
;Load in our interrupt handler 
	di
	ld hl,&38
	ld a,&C3	;JP
	ld (hl),a
	inc hl
	ld de,InterruptHanlder
	ld (hl),e
	inc hl
	ld (hl),d
	ei

	ld a,(NewPosX+1)
	ld b,a
	ld a,(NewPosY+1)
	ld c,a


	call ShowSprite	;Show the Cursor to the scree

ShowAgain:	
	ld a,(FireDown)
	or a
	jr z,NoFire
	
;Fire is down - show our test sprite at current location	

	ld ix,&300C
	ld de,TestSprite2
	call ShowSpriteB
;
;	xor a
	;ld (FireDown),a		;Clear Fire
NoFire:

;Update the Cursor

	ld a,(OldPosX+1)	;Last Joystick pos
	ld b,a
	ld a,(OldPosY+1)
	ld c,a

	ld a,(NewPosX+1)	;New Joystick pos
	ld h,a
	ld a,(NewPosY+1)
	ld l,a

	or a
	sbc hl,bc			;See if Cursor pos changed
	jr z,ShowAgain
	
	ld a,(OldPosX+1)
	ld b,a
	ld a,(OldPosY+1)
	ld c,a

	call ShowSprite		;Remove old cursor

	ld hl,(NewPosX)		;Update Cursor pos
	ld de,(NewPosY)
	ld (OldPosX),hl
	ld (OldPosY),de

	ld b,h
	ld c,d
	push bc
		call ShowSprite	;Show New Cursor
	pop bc
	
	
	ld a,(FireHeld)
	or a
	jr z,MoFireHeld		;Check if fire is still down

;Fire is Held - show our test sprite at current location	
	ld ix,&0802
	ld de,DragSprite
	call ShowSpriteB	
MoFireHeld:

	jp ShowAgain
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

InterruptHanlder:
	ex af,af'
	exx
		call ReadJoystick	;Get Joystick (mouse)
		ld d,h			;D=Mouse presses

		ld hl,(NewPosY)
		ld bc,256*2		;Hmove speed

		bit 0,d			;Up Key
		jr nz,JoyNotUp
		ld a,h
		or a
		jr z,JoyNotUp	;Cursor at top of screen
		or a
		sbc hl,bc
JoyNotUp:

		bit 1,d			;Down Key
		jr nz,JoyNotDown
		ld a,h
		cp 200-8		;Cursor at bottom of screen
		jr z,JoyNotDown
		add hl,bc
JoyNotDown:

		ld (NewPosY),hl	;Update Ypos
		
		ld hl,(NewPosX)
		ld bc,64*2		;Vmove speed
		
		bit 2,d			;Left Key
		jr nz,JoyNotLeft
		ld a,h
		or a			;Cursor at far left of screen
		jr z,JoyNotLeft
		or a
		sbc hl,bc
JoyNotLeft:

		bit 3,d			;Right Key
		jr nz,JoyNotRight
		ld a,h
		cp 80-2			;Cursor at far right of screen
		jr z,JoyNotRight
		add hl,bc
JoyNotRight:

		ld (NewPosX),hl

		bit 4,d			;Left Click
		jr nz,JoyNotFire
		ld a,(FireHeld)
		or a
		jr nz,JoyNotFireB

		ld a,1
		ld (FireDown),a	;Set FireDown/Held
		ld (FireHeld),a
		jr JoyNotFireB
JoyNotFire:
		xor a		
		ld (FireHeld),a	;Release Fire Held
JoyNotFireB:

	exx
	ex af,af'
	ei
	ret

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

OldPosX: dw 00		;Last Mouse position
OldPosY: dw 00
NewPosX: dw 00		;Current Mouse position
NewPosY: dw 00

FireHeld: db 0		;Mouse Left is Held
FireDown: db 0		;Mouse Left was pressed (not processed yet)


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

ShowSprite:			;Show Mouse Cursor
	ld de,TestSprite ;Sprite Source
	ld ix,&0802
	
ShowSpriteB:		;Show Alt Sprite
	call GetScreenPos
	ld b,ixh		;Lines (Height)
SpriteNextLine:
	push hl
		ld c,ixl	;Bytes per line (Width)
SpriteNextByte:
		ld a,(de)	;Source Byte
		xor (hl)
		ld (hl),a	;Screen Destination

		inc de		;INC Source (Sprite) Address
		inc hl		;INC Dest (Screen) Address

		dec c 		;Repeat for next byte
		jr nz,SpriteNextByte
	pop hl
	call GetNextLine	;Scr Next Line (Alter HL to move down a line)
	djnz SpriteNextLine	;Repeat for next line

	ret			;Finished

;Mouse Cursor	
TestSprite:
	db %00010001,%10001000	
	db %00010001,%10001000	
	db %00010001,%10001000	
	db %11101110,%01110111
	db %11101110,%01110111	
	db %00010001,%10001000	
	db %00010001,%10001000	
	db %00010001,%10001000

;Click Test
TestSprite2:
	incbin "\ResALL\Sprites\SpriteCPC.raw"
	
;Drag Test	
DragSprite
        DB %00000000,%00000000   
        DB %00000000,%00000000    
        DB %00110000,%11000000   
        DB %01110000,%11100000    
        DB %01110000,%11100000    
        DB %00110000,%11000000  
        DB %00000000,%00000000    
        DB %00000000,%00000000     

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

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
;	; de is wiped
;

;Looking at Y line (in C) - we need to take each set of bits, and work with them separately:
;YYYYYYYY	Y line number (0-200)
;-----YYY	(0-7)  - this part needs to be multiplied by &0800 and added to the total
;YYYYY---	(0-31) - This part needs to be multiplied by 80 (&50)



;YYYYY---	(0-31) - This part needs to be multiplied by 80 (&50)
	push de
		;screen is 80 bytes wide = -------- %01010000
		ld a,C		; 00000000 01010000
		and %11111000 	; -------- -YYYY---
		ld h,0
		ld l,a
				; 00000000 01010000
		
		sla l		; -------- YYYY----
		rl h
		
		ld d,h		;value is in first bit position -add it
		ld e,l	
				; 00000000 01010000
		sla e		; -------Y YYY-----
		rl d		;	    
		sla e		; ------YY YY------
		rl d
		
		add hl,de	;value is in 2nd bit position - add it
		;We've now effectively multiplied by 80 (&50)

	;-----YYY	(0-7)  - this part needs to be multiplied by &0800 and added to the total
		ld a,C
		and %00000111	
		
		rlca		;X8
		rlca
		rlca

		ld d,a		;Load into top byte, and add as 16 bit
		ld e,0

		add hl,de
		;We've now effectively multiplied by 8

	;Screen Base
		ld a,&C0	;Add the screen Base &C000
		ld d,a

	;X position
		ld e,B		;Add the X pos 
		add hl,de
	pop de

	ret 		;return memory location in hl
	
GetNextLine:
	push af

		ld a,h		;Add &08 to H (each CPC line is &0800 bytes below the last
		add &08
		ld h,a
			;Every 8 lines we need to jump back to the top of the memory range to get the correct line
			;The code below will check if we need to do this - yes it's annoying but that's just the way the CPC screen is!
		bit 7,h		;Change this to bit 6,h if your screen is at &8000!
		jp nz,GetNextLineDone
		push bc
			ld bc,&c050	;if we got here we need to jump back to the top of the screen - the command here will do that
			add hl,bc
		pop bc
	GetNextLineDone:
	pop af
	ret

	
	;Key input on the CPC goes through the 8255 PPI an AY soundchip, we need to use the PPI to talk to the AY, 
	;and tell it to read input through reg 14

	;Port F6C0 = Select Regsiter
	;Port F600 = Inactive
	;Port F6xx = Recieve Data
	;Port F4xx = Send Data to selected Register
	
ReadJoystick:	
	ld bc,&f782     ;Select PPI port direction... A out /C out 
	xor a
	out (c),c      

	ld bc,&f40e     ; Select Ay reg 14 on ppi port A 
	ld e,b          
	out (c),c       
	ld bc,&f6c0     ;This value is an AY index (R14) 
	ld d,b          
	out (c),c        
	out (c),a   	; F600 - set to inactive (needed)
	ld bc,&f792     ; Set PPI port direction A in/C out 
	out (c),c    
	
	ld a,&49        ;Line 49 - Joystick / Mouse
	
	ld c,&4a        
	ld b,d    		;d=&f6     
	out (c),a       ;select line &F640-F64A
	ld b,e    		;e=&f4   
	in h,(c)
	ld l,255
	ld bc,&f782     
	out (c),c       ; reet PPI port direction - PPI port A out / C out 
	ret				;Result in H
	
	