	NAME txt_graph

;******************************************************************************************************
;******************************************************************************************************
;	texts routines
;******************************************************************************************************
;******************************************************************************************************
;======================================================================================================	
;	draw XRAM string form strtmp
;======================================================================================================	
?PR?_DrawStrXRAM?txt_graph SEGMENT CODE
	RSEG	?PR?_DrawStrXRAM?txt_graph

	USING	0	

	PUBLIC _DrawStrXRAM
	EXTRN code (FontList)
	EXTRN data (xpos)
	EXTRN data (ypos)
	EXTRN xdata (img0)
	EXTRN xdata (strtmp)

AUXR1	DATA	0A2h

_DrawStrXRAM:	mov	a,xpos
	clr	c
	subb	a,#240
	jc	$+5
	ljmp	LCDwrTxtD	;exit if xpos out of screen

	push	AR7
	mov	a,R5
	jb	acc.1,DrawStrXRAMNI
	mov	a,R5
	jnz	$+5
	lcall	DrawStrBck	;draw black squere if needed
DrawStrXRAMNI:	pop	AR7
	
	mov	a,R7
	mov	b,#3
	mul	ab
	add	a,#low(FontList)
	mov	dpl,a
	clr	a
	addc	a,#high(FontList)
	mov	dph,a
	clr	a
	movc	a,@a+dptr
	mov	R5,a
	mov	a,#1
	movc	a,@a+dptr
	mov	R6,a	;font pointer
	mov	a,#2
	movc	a,@a+dptr
	mov	R4,a	;font heigth
	add	a,ypos
	jnb	acc.7,$+6
	ljmp	LCDwrTxtD	;exit if ypos out of screen
	
	mov	dptr,#strtmp	;string pointer

LCDwrTxt:	;get string char
	movx	a,@dptr
	inc	dptr
	jnz	LCDwrTxtDN
	ljmp	LCDwrTxtD
LCDwrTxtDN:	push	dpl
	push	dph
	;get pointer character pointer data from CP1250 table
	mov	b,#2
	mul	ab
	add	a,R6
	mov	dpl,a
	mov	a,b
	addc	a,R5
	mov	dph,a
	mov	a,#1
	movc	a,@a+dptr
	mov	b,a
	mov	a,#0
	movc	a,@a+dptr
	mov	dpl,b
	mov	dph,a
	;draw character image
	mov	a,#0
	movc	a,@a+dptr
	inc	dptr
	mov	R7,a	;store char x len

	mov	b,xpos	;initial xpos for new char
	anl	b,#00000111b
	mov	a,#00000001b
	jnb	b.1,$+5
	mov	a,#00000100b
	jnb	b.0,$+4
	rl	a
	jnb	b.2,$+4
	swap	a
	mov	R1,a	;horizontal offset multiplier (2^offset)
	;
	inc	auxr1
	;
	mov	a,xpos
	rr	a
	rr	a
	rr	a
	anl	a,#00011111b
	add	a,#low(img0)
	mov	dph,a	;## swapped for optimalization
	mov	a,#high(img0)
	addc	a,#0
	mov	dpl,a	;## swapped for optimalization
	mov	a,#30
	mov	b,ypos
	mul	ab
	add	a,dph
	xch	a,dpl
	addc	a,b
	mov	dph,a
	;
	inc	auxr1

	inc	R7
	mov	a,xpos
	add	a,R7
	mov	xpos,a	;new text x len (in pixels)
	jc	LCDwrTxtNL
	clr	c
	subb	a,#240
	jc	LCDwrTxtNNL
	;xpos over 239, break line
LCDwrTxtNL:	mov	a,ypos
	add	a,R4	;add font heigth to ypos
	mov	ypos,a
	jb	acc.7,LCDwrTxtDC	;exit routine if line over LCD
	inc	auxr1
	mov	b,#30
	mul	ab
	add	a,#low(img0)
	mov	dpl,a
	mov	a,#high(img0)
	addc	a,b
	mov	dph,a	;new img0 pointer offsett
	inc	auxr1
	mov	a,ypos
	add	a,R4
	jb	acc.7,LCDwrTxtDC	;exit routine if line over LCD
	mov	xpos,R7	;xpos = char width + 1
	mov	R1,#1	;horizontal offset multiplier (2^offset)
LCDwrTxtNNL:	
	
	mov	a,R4
	mov	R7,a
LCDwrTxtL1:	clr	a
	movc	a,@a+dptr
	mov	b,R1
	mul	ab
	mov	R0,a
	inc 	dptr
	inc	auxr1
	movx	a,@dptr
	xrl	a,R0	;xor low part of character word
	movx	@dptr,a
	inc	dptr
	movx	a,@dptr
	xrl	a,b	;xor high part of character word
	movx	@dptr,a
	mov	a,dpl	;move pointer to next line
	add	a,#low(30-1)
	mov	dpl,a
	jnc	LCDwrTxtL1S1
	inc	dph
LCDwrTxtL1S1:	inc	auxr1
	djnz	R7,LCDwrTxtL1	
	;add space
	pop	dph
	pop	dpl
	jmp	LCDwrTxt
LCDwrTxtDC:	pop	dph
	pop	dpl
LCDwrTxtD:	ret	

;======================================================================================================	
;	draw string black background
;======================================================================================================	
?PR?_DrawStrBck?txt_graph SEGMENT CODE
	RSEG	?PR?_DrawStrBck?txt_graph

	USING	0	

DrawStrBck:	mov	a,R7
	mov	b,#3
	mul	ab
	add	a,#low(FontList)
	mov	dpl,a
	clr	a
	addc	a,#high(FontList)
	mov	dph,a
	clr	a
	movc	a,@a+dptr
	mov	R5,a
	mov	a,#1
	movc	a,@a+dptr
	mov	R6,a	;font pointer
	mov	a,#2
	movc	a,@a+dptr
	mov	R7,a	;font heigth
	add	a,ypos
	inc	a
	jnb	acc.7,$+6
	ljmp	DrawStrBckDE	;exit if ypos out of screen

	mov	R1,#3	;string len in pixels
	
	mov	dptr,#strtmp	;string pointer
DrawStrBckLL:	;get string char
	movx	a,@dptr
	inc	dptr
	jz	DrawStrBckD
	push	dpl
	push	dph
	;get pointer character pointer data from CP1250 table
	mov	b,#2
	mul	ab
	add	a,R6
	mov	dpl,a
	mov	a,b
	addc	a,R5
	mov	dph,a
	mov	a,#1
	movc	a,@a+dptr
	mov	b,a
	mov	a,#0
	movc	a,@a+dptr
	mov	dpl,b
	mov	dph,a
	;draw character image
	mov	a,#0
	movc	a,@a+dptr
	inc	dptr
	add	a,R1	;add new char len to str len in pixels
	inc	a
	mov	R1,a
	pop	dph
	pop	dpl
	sjmp	DrawStrBckLL

DrawStrBckD:	mov	a,xpos
	add	a,#-2
	add	a,R1
	jc	DrawStrBckDE	;skip if x out of range
	clr	c
	subb	a,#240
	jnc	DrawStrBckDE	;skip if x out of range		              			

	mov	a,#30
	mov	b,ypos
	mul	ab
	add	a,#low(img0)
	mov	dpl,a
	mov	a,#high(img0)
	addc	a,b
	mov	dph,a	;pointer to the tol left corner of the squere
	
	;draw black filled squere
	mov	a,xpos
	add	a,#-2
	mov	R0,a
	clr	c
	subb	a,#240
	jnc	DrawStrBckDE	;skip if x out of range
	mov	a,R0
	mov	b,#8
	div	ab
	mov	R3,a
	mov	a,#00000001b
	jnb	b.1,$+5
	mov	a,#00000100b
	jnb	b.0,$+4
	rlc	a
	jnb	b.2,$+4
	swap	a
	mov	R2,a

	mov	a,dpl
	add	a,R3
	mov	dpl,a
	mov	a,dph
	addc	a,#0
	mov	dph,a

	inc	R7
	mov	R3,AR1
DrawStrBckDL:	
	mov	R4,dpl
	mov	R5,dph
	mov	R6,AR7
	
	mov	a,R1
	clr	c
	subb	a,#1
	jz	DrawStrBckNFL
	mov	a,R3
	cjne	a,AR1,DrawStrBckDFL
	;first and last column
DrawStrBckNFL:	mov	a,dpl
	add	a,#low(30)
	mov	dpl,a
	mov	a,dph
	addc	a,#high(30)
	mov	dph,a
	dec	R6
	dec	R6

DrawStrBckDFL:	movx	a,@dptr
	orl	a,R2
	movx	@dptr,a
	mov	a,dpl
	add	a,#low(30)
	mov	dpl,a
	mov	a,dph
	addc	a,#high(30)
	mov	dph,a
	djnz	R6,DrawStrBckDFL
	mov	dpl,R4
	mov	dph,R5
	mov	a,R2
	rl	a
	mov	R2,a
	jnb	acc.0,DrawStrBckDS
	inc	dptr
DrawStrBckDS:	djnz	R1,DrawStrBckDL

/*	;draw black filled squere
	mov	R0,xpos
	dec	R0
	mov	a,R0	;x0
	add	a,R1
	mov	R1,a	;x1
	mov	b,#8
	div	ab
	mov	R2,a
	mov	R3,b
	mov	a,R0
	mov	b,#8
	div	ab
	mov	R0,a
	mov	R1,b
	clr	c
	subb	a,R2
	jnz	DrawStrBckNS
	;------ x0 and x1 in same byte ------
	mov	b,R1
	mov	a,#00000001b
	jnb	b.1,$+5
	mov	a,#00000111b
	jnb	b.0,$+5
	setb	c
	rlc	a
	jnb	b.2,$+5
	swap	a
	orl	a,#00001111b
	mov	R4,b	;mask from left side
	mov	b,R3
	mov	a,#01111111b
	jnb	b.1,$+5
	mov	a,#00011111b
	jnb	b.0,$+5
	clr	c
	rrc	a
	jnb	b.2,$+5
	swap	a
	anl	a,#00001111b
	xrl	a,R4	;left mask xored with right mask
	mov	R4,a
	;draw to all lines
DrawStrBckSL:	movx	a,@dptr
	orl	a,R4
	movx	@dptr,a
	mov	a,dpl
	add	a,#low(30)
	mov	dpl,a
	mov	a,dph
	addc	a,#high(30)
	mov	dph,a
	djnz	R7,DrawStrBckSL
	ajmp	DrawStrBckSD

DrawStrBckNS:	cpl	a
	inc	a	;horizontal bytes
	add	a,#-1
	jz	DrawStrBckNSM
	;------ middle part ------
	mov	R6,a

	djnz	R6,DrawStrBckNSM

DrawStrBckNSM:
DrawStrBckSD:*/
DrawStrBckDE:	ret




;******************************************************************************************************
;******************************************************************************************************
;	graphics routines
;******************************************************************************************************
;******************************************************************************************************
;======================================================================================================	
;	draw line
;======================================================================================================	
?PR?_DrawLine?txt_graph SEGMENT CODE
?DT?_DrawLine?txt_graph SEGMENT DATA
	PUBLIC	_DrawLine
	PUBLIC	?_DrawLine?BYTE

	RSEG	?DT?_DrawLine?txt_graph
?_DrawLine?BYTE:	ds	4

	RSEG	?PR?_DrawLine?txt_graph

	;R7:Ax
	;R5:Ay
	;R3:Bx

_DrawLine:	mov	a,R7
	mov	R2,a	;Ax
	clr	c
	subb	a,#240
	jc	$+3
	ret
	mov	a,R3
	mov	R4,a	;Bx
	clr	c
	subb	a,#240
	jc	$+3
	ret
	mov	a,R5
	mov	R3,a	;Ay
	jnb	acc.7,$+4
	ret
	mov	a,?_DrawLine?BYTE+3
	mov	R5,a	;By
	jnb	acc.7,$+4
	ret
	
;	mov	a,R7
;	mov	R3,a
;	mov	a,R6
;	mov	R2,a

	mov	a,R4
	clr	c
	subb	a,R2
	mov	R6,a	;dx or -dx
	jnc	DrawLineQC
	;swap A and B because Ax must be lower than Bx
	mov	a,R2
	xch	a,R4
	mov	R2,a
	mov	a,R3
	xch	a,R5
	mov	R3,a
	mov	a,R6
	cpl	a
	inc	a
	mov	R6,a	;dx
	;Ax > Bx
DrawLineQC:	
	;calculate A point img pointer and mask
	mov	a,R2
	mov	b,#8
	div	ab
	push	b	;push pixel offset
	add	a,#low(img0)
	mov	dph,a	;## swapped for optimalizaition
	mov	a,#0
	addc	a,#high(img0)
	mov	dpl,a	;## swapped for optimalizaition
	mov	a,R3
	mov	b,#30
	mul	ab
	add	a,dph
	xch	a,dpl
	addc	a,b
	mov	dph,a	;initial byte pointer
	;convert bit offset to bit mask
	pop	b
	mov	a,#00000001b
	jnb	b.1,DrawLineO2M1
	mov	a,#00000100b
DrawLineO2M1:	jnb	b.2,DrawLineO2M2
	swap	a
DrawLineO2M2:	jnb	b.0,DrawLineO2M3
	rl	a
DrawLineO2M3:	mov	b,a
	;which quartal?
	mov	a,R5
	clr	c
	subb	a,R3
	jc	DrawLineQ4	;IV.Q
	;I.Q (By >= Ay)
	mov	R7,a	;dy
	clr	c
	subb	a,R6
	jc	DrawLineQ1X	;dx > dy
	;======= dy >= dx =======
	mov	a,R7
	mov	R0,a	;initial temp=dy
	inc	a
	mov	R7,a	;(dy+1) used for loop counter
	mov	R5,a	;(dy+1)
	inc	R6	;(dx+1)
	;
DrawLineQ1YL1:	movx	a,@dptr
	orl	a,b	;add pixel into image
	movx	@dptr,a
	mov	a,R0
	clr	c
	subb	a,R6	;temp-=(dx+1)
	mov	R0,a
	jnc	DrawLineQ1YS1
	;temp < 0
	add	a,R5	;temp+=(dy+1)
	mov	R0,a
	;now x++
	mov	a,b	;load bit mask
	rl	a	;rotate bit (x++)
	mov	b,a	;store it back
	jnb	b.0,DrawLineQ1YS1
	inc	dptr	;mask out of range, dptr++ (move to next byte, mask reseted back to 00000001b)
DrawLineQ1YS1:	;now we have to make y++ step
	mov	a,dpl
	add	a,#low(30)
	mov	dpl,a
	mov	a,dph
	addc	a,#high(30)
	mov	dph,a	;dptr+=xres
	djnz	R7,DrawLineQ1YL1	;next pixel?
	;done - hell yeah
	jmp	DrawLineDone
	;======= dx > dy =======
DrawLineQ1X:	mov	a,R6
	mov	R0,a	;initial temp=dx
	inc	a
	mov	R6,a	;(dx+1) used for loop counter
	mov	R5,a	;(dx+1)
	inc	R7	;(dy+1)
	;
DrawLineQ1XL1:	movx	a,@dptr
	orl	a,b	;add pixel into image
	movx	@dptr,a
	mov	a,R0
	clr	c
	subb	a,R7	;temp-=(dy+1)
	mov	R0,a
	jnc	DrawLineQ1XS1
	;temp < 0
	add	a,R5	;temp+=(dx+1)
	mov	R0,a
	;now y++
	mov	a,dpl
	add	a,#low(30)
	mov	dpl,a
	mov	a,dph
	addc	a,#high(30)
	mov	dph,a	;dptr+=xres
DrawLineQ1XS1:	;now we have to make x++ step
	mov	a,b	;load bit mask
	rl	a	;rotate bit (x++)
	mov	b,a	;store it back
	jnb	b.0,DrawLineQ1XS2
	inc	dptr	;mask out of range, dptr++ (move to next byte, mask reseted back to 00000001b)
DrawLineQ1XS2:	djnz	R6,DrawLineQ1XL1	;next pixel?
	;done - hell yeah
	sjmp	DrawLineDone
	
	;IV.Q (Ay > By)
DrawLineQ4:	cpl	a
	inc	a
	mov	R7,a	;dy
	clr	c
	subb	a,R6
	jc	DrawLineQ4X	;dx > dy
	;======= dy >= dx =======
	mov	a,R7
	mov	R0,a	;initial temp=dy
	inc	a
	mov	R7,a	;(dy+1) used for loop counter
	mov	R5,a	;(dy+1)
	inc	R6	;(dx+1)
	;
DrawLineQ4YL1:	movx	a,@dptr
	orl	a,b	;add pixel into image
	movx	@dptr,a
	mov	a,R0
	clr	c
	subb	a,R6	;temp-=(dx+1)
	mov	R0,a
	jnc	DrawLineQ4YS1
	;temp < 0
	add	a,R5	;temp+=(dy+1)
	mov	R0,a
	;now x++
	mov	a,b	;load bit mask
	rl	a	;rotate bit (x++)
	mov	b,a	;store it back
	jnb	b.0,DrawLineQ4YS1
	inc	dptr	;mask out of range, dptr++ (move to next byte, mask reseted back to 00000001b)
DrawLineQ4YS1:	;now we have to make y-- step
	mov	a,dpl
	add	a,#low(-30)
	mov	dpl,a
	mov	a,dph
	addc	a,#high(-30)
	mov	dph,a	;dptr-=xres
	djnz	R7,DrawLineQ4YL1	;next pixel?
	;done - hell yeah
	sjmp	DrawLineDone
	;======= dx > dy =======
DrawLineQ4X:	mov	a,R6
	mov	R0,a	;initial temp=dx
	inc	a
	mov	R6,a	;(dx+1) used for loop counter
	mov	R5,a	;(dx+1)
	inc	R7	;(dy+1)
	;
DrawLineQ4XL1:	movx	a,@dptr
	orl	a,b	;add pixel into image
	movx	@dptr,a
	mov	a,R0
	clr	c
	subb	a,R7	;temp-=(dy+1)
	mov	R0,a
	jnc	DrawLineQ4XS1
	;temp < 0
	add	a,R5	;temp+=(dx+1)
	mov	R0,a
	;now y--
	mov	a,dpl
	add	a,#low(-30)
	mov	dpl,a
	mov	a,dph
	addc	a,#high(-30)
	mov	dph,a	;dptr+=xres
DrawLineQ4XS1:	;now we have to make x++ step
	mov	a,b	;load bit mask
	rl	a	;rotate bit (x++)
	mov	b,a	;store it back
	jnb	b.0,DrawLineQ4XS2
	inc	dptr	;mask out of range, dptr++ (move to next byte, mask reseted back to 00000001b)
DrawLineQ4XS2:	djnz	R6,DrawLineQ4XL1	;next pixel?
	;done - hell yeah
	;ajmp	DrawLineDone
	
DrawLineDone:	ret	


;======================================================================================================	
;	draw icon
;======================================================================================================	
?PR?_DrawIcon?txt_graph SEGMENT CODE
?DT?_DrawIcon?txt_graph SEGMENT DATA
	PUBLIC	_DrawIcon
	PUBLIC	?_DrawIcon?BYTE

	RSEG	?DT?_DrawIcon?txt_graph
?_DrawIcon?BYTE:	ds	6

	RSEG	?PR?_DrawIcon?txt_graph

_DrawIcon:	mov	a,R5
	jb	acc.7,_DrawIconE	;exit if y out of screen
	add	a,?_DrawIcon?BYTE+3
	dec	a
	jb	acc.7,_DrawIconE	;exit if (y+yres) out of screen
	mov	a,R7
	clr	c
	subb	a,#240
	jnc	_DrawIconE
	mov	a,R7
	add	a,R3
	clr	c
	subb	a,#241
	jnc	_DrawIconE

	mov	a,#30
	mov	b,R5
	mul	ab
	mov	R0,a
	mov	a,R7
	rr	a
	rr	a
	rr	a
	add	a,R0
	mov	dpl,a
	clr	a
	addc	a,b
	mov	dph,a
	mov	a,#low(img0)
	add	a,dpl
	mov	dpl,a
	mov	a,#high(img0)
	addc	a,dph
	mov	dph,a	;image pointer
	mov	R7,?_DrawIcon?BYTE+3	;icon lines
	mov	a,R3
	mov	b,#8
	div	ab
	xch	a,b
	jz	_DrawIconS2
	inc	b
_DrawIconS2:
_DrawIconL2:	mov	R6,b
_DrawIconL1:	mov	R0,dpl
	mov	R1,dph      
	mov	dpl,?_DrawIcon?BYTE+5
	mov	dph,?_DrawIcon?BYTE+4
	clr	a
	movc	a,@a+dptr
	inc	dptr
	mov	?_DrawIcon?BYTE+5,dpl
	mov	?_DrawIcon?BYTE+4,dph
	mov	dph,R1
	mov	dpl,R0
	movx	@dptr,a
	inc	dptr
	djnz	R6,_DrawIconL1
_DrawIconS1:	clr	c
	mov	a,dpl
	subb	a,b
	mov	dpl,a
	mov	a,dph
	subb	a,#0
	mov	dph,a
	mov	a,#30
	add	a,dpl
	mov	dpl,a
	mov	a,dph
	addc	a,#0
	mov	dph,a
	djnz	R7,_DrawIconL2
_DrawIconE:	ret

	END
