
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Draw Line
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	ifndef NoDrawLine

DrawLine:	;Start=IX,IY... Dest Hl,DE=Yoffset 
	ld b,ixh
	ld c,ixl
	ld (Xpos24+1),bc	;Source X
	or a
	sbc hl,bc			;Calculate Difference X
	;push hl
		ex de,hl
		ld b,iyh
		ld c,iyl
		ld (Ypos24+1),bc	;Dest Y
		or a 
		sbc hl,bc			;Calculate Difference Y
		ex de,hl
	;pop hl
	
DrawLineRelative:	;HL=Xoffset DE=Yoffset 
	ld a,h
	or l
	or d
 	or e
	jr nz,DrawLineRelativeOK
	inc e			;Draw at least 1 dot
	inc l 
DrawLineRelativeOK:

	ld ix,XposDir	;XY Flip markers
	ld (IX),0
	bit 7,h
	call nz,FlipHL	;Xpos is negative

	ld ix,yposDir
	ld (IX),0

	bit 7,d
	jr z,NoFlipDE
	ex de,hl
	call FlipHL		;Ypos is negative
	ex de,hl
	
NoFlipDE:
	or a
	sbc hl,de
	jr nc,HLBigger	;X length > Ylength
	add hl,de
	push de
		ld a,e
		ld h,l			;HL=L/E
		call Div8ZeroL	;HL=Source	A=Divider (HL=HL/A A=Rem)
	pop bc
	ld de,&0100		;1 Vpixel per draw
	jr DEBigger
	
HLBigger:
	add hl,de		;Fix HL
	push hl
		ld a,l
		ld h,e			;HL=E/L
		call Div8ZeroL	;HL=Source	A=Divider (HL=HL/A A=Rem)
		ex de,hl
	pop bc
	ld hl,&0100		;1 Hpixel per draw
	
DEBigger:
	ld a,b			;Swap BC - we use DJNZ for lower unit
	ld b,c			;Pixels of movement for larger direction
	ld c,a
	inc c			;Make sure C loop works!
	
	ld iyh,d		;Ymove
	ld iyl,e

	ex de,hl
	ld ixh,d		;Xmove
	ld ixl,e

LineAgain:
	push bc
		ld hl,(Xpos24+1)
		ld a,(Ypos24+1)
		ld c,a		;C=Ypos

		ld a,(LineColor)
		ld d,a

		ld a,h		;AB=Xpos
		ld b,l

		call Pset	;X=AB   Y=C   color=D

		ld d,ixh	
		ld e,ixl
		ld hl,XposDir
		call Add24

		ld d,iyh	
		ld e,iyl
		inc hl		;HL= YposDir
		call Add24
	pop bc
	djnz LineAgain
	dec c
	jr nz,LineAgain
	ret
	
	endif
	
DrawLineSafe: ;Start=IX,IY... Dest hl,DE=Yoffset 
	push ix
	push iy
	push hl
	push de
	push af
		call DrawLine
	pop af
	pop de
	pop hl
	pop iy 
	pop ix
	ret
	
	
	
FlipHL:
	inc (ix)		;Update Flip Marker
	ld a,h
	cpl				;$0001 -> $FFFF
	ld h,a
	ld a,l
	cpl
	ld l,a
	inc hl
	ret
	
;;;;;;;;;;;;;;;;;;

Add24:	;ADD DE to (HL) 24 bit UHL Little Endian (DLHU)
	ld a,(hl)
	inc hl			;First byte is direction marker (D)
	or a
	jr nz,Sub24
	ld a,(hl)		;(HL)=(HL)+$00 $DD $EE
	add e
	ld (hl),a		;L
	inc hl
	ld a,(hl)
	adc d
	ld (hl),a		;H
	inc hl
	ret nc
	inc (hl)		;U
	ret
Sub24:				;(HL)=(HL)-$00 $DD $EE
	ld a,(hl)
	sub e
	ld (hl),a		;L
	inc hl
	ld a,(hl)		;H
	sbc d
	ld (hl),a
	inc hl			;U
	ret nc
	dec (hl)
	ret
	
	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Font Driver
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PrintString:
	ld a,(hl)		;Print a '255' terminated string 
	cp 255
	ret z
	inc hl
	call PrintChar
	jr PrintString	

	
	
PrintCharNum:
		sub '!'	
			ld hl,VNumSet
			jr PrintCharactersB
PrintSpace:
	ld a,' '
PrintChar:			;Print Char A
	push af
	push bc
	push de
	push hl	
		cp ' '
		jr z,PrintCharSpace		;Space
		cp ':'+1
		jr c,PrintCharNum		;Numbers and Symbols

		and %11011111			;Convert Upper-> Lower
		sub 'A'
		ld hl,VCharSet
PrintCharactersB:
		sla a				;2 Bytes per address
		ld c,a
		ld b,0

		add hl,bc			;Get Address of Cpacket for char
		ld a,(hl)
		ld ixl,a
		inc hl
		ld a,(hl)
		ld ixh,a

		Call DrawCpacket	;Draw it
PrintCharSpaceB:
		ld bc,12
		call DoScale
		add hl,bc
		ld (Xpos24+1),hl	;Move to next Char
	pop hl
	pop de
	pop bc
	pop af
	ret
PrintCharSpace:				;Print a space
	ld hl,(Xpos24+1)
	jr PrintCharSpaceB		;Move Right 1 char

		
Locate:	;(HL,DE) = (X,Y)
	ld (Xpos24+1),hl		;Postition drawing cursor
	ld (Ypos24+1),de
	xor a
	ld (Xpos24),a
	ld (Ypos24),a
	jp ZeroLow24Byte		;Set Low byte of XY to zero
	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Draw Vectrex Packet format
;	$CC,$YY,$XX ... CC 00=Move FF=Line 01=Done
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DrawPacket:	;Draw HL
	ld de,(Xpos24+1)		;Back Up Xpos
	push de
		ld de,(Ypos24+1)	;Back Up Ypos
		push de		
VtXAgain:
			ld a,(hl)		;Check Command
			inc hl
			or a			;$00 = Move 
			jr z,VtxMove
			inc a			;$FF = Draw Line
			jr z,VtxLine
			cp 2			;$01 = Line Done
			jr z,VtxDone	;Update Pos & Return
VtxLine:
			ld a,(hl)		;Get Ypos
			neg
			ld c,a
			inc hl	
			call SexBC
			ld d,b
			ld e,c
			ld c,(hl)		;Get Xpos
			inc hl	
			call SexBC
			push hl
				ld h,b
				ld l,c
				call DrawLineRelative	;HL=Xoffset DE=Yoffset 
			pop hl
			jr VtXAgain
VtxMove:
			ld a,(hl)			;Ypos
			neg
			ld c,a 
			inc hl	
			call SexBC
			ex de,hl
				ld hl,(Ypos24+1) ;Move Ypos
				add hl,bc
				ld (Ypos24+1),hl
			ex de,hl
			ld c,(hl)			;Xpos
			inc hl	
			call SexBC
			ex de,hl
				ld hl,(Xpos24+1) ;Move Xpos
				add hl,bc
				ld (Xpos24+1),hl
			ex de,hl
			jr VtXAgain

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Draw CPacket format - (7 bit per axis - 2 command bits)
;	%CYYYYYYY,%DXXXXXXX ... %CD %?0=Move %?1=Line %1?=End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DrawCpacket:		;Draw Cpacket IX
	ld hl,(Xpos24+1)			;Back Up Xpos
	push hl
		ld hl,(Ypos24+1)		;Back Up Ypos
		push hl		
			jr DrawCpacketStart
DrawCpacketAgain:
			inc ix				;Move to next CMD
			inc ix	
			
DrawCpacketStart:				;CMD CHECK
			bit 7,(ix+1)		;%CD=%?0 = Move Type
			jr z,CpacketMove
CpacketLine:					;%CD=%?1 = Line Type
			ld a,(ix+0)			
			neg
			ld c,a				;Ypos
			call SexBC7bit
			ld d,b
			ld e,c
			ld c,(ix+1)			;Xpos
			call SexBC7bit
			push ix
				ld h,b
				ld l,c
				call DrawLineRelative	;HL=Xoffset DE=Yoffset 
			pop ix
			bit 7,(ix)			;%CD=%1? = Drawing Done
			jr z,DrawCpacketAgain
VtxDone:
		pop hl
		ld (Ypos24+1),hl		;Restore Ypos
	pop hl
	ld (Xpos24+1),hl			;Restore Xpos
ZeroLow24Byte:
	xor a
	ld (Xpos24),a		;Low byte of 24 bit XY
	ld (Ypos24),a
	ret

CpacketMove:
	ld a,(ix+0)			;Get Ypos
	neg
	ld c,a 
	call SexBC7bit
	ld hl,(Ypos24+1)
	add hl,bc			;Move Ypos
	ld (Ypos24+1),hl
	
	ld c,(ix+1)			;Get Xpos
	call SexBC7bit
	ld hl,(Xpos24+1)
	add hl,bc			;Move Xpos
	ld (Xpos24+1),hl
	
	jp DrawCpacketAgain	;Back to start of Cpacket processor

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
SexBC7bit:			;Sign Extend 7bit C-> BC
	res 7,c
	bit 6,c
	jr z,SexBC
	set 7,c
SexBC:				;Sign Extend 8bit C-> BC
	ld b,255
	bit 7,c
	jr nz,DoScale
	inc b			;B=0

DoScale:			;Scale BC 
	ld a,(Scale)
DoScaleAgain:
	or a
	ret z			;0= full size
	cp 128
	jr nc,ScaleNegative
ScalePositive:		;>0 x2 x4 x8
	sla c			
	rl b
	dec a
	jr DoScaleAgain
ScaleNegative:		;<0 /2 /4 /8
	sra b
	rr c
	inc a
	jr DoScaleAgain

	
	
	