* DrawLine.s - file has DrawLineN and EraseLineN routines

********************************************************
* ** NAME: DrawLineN - draws pixels on a line on a 1 bit surface 131x... (Normal surface)
*					   only assumes 34 nibbles wide surface
* Category:
*
* Purpose:
*
* Entry: now values are (x1=A[A],y1=C[A]) (x2=B[A],y2=D[A]) address of surface R0[A]
*
* Exit:
*
* Alters: A[A],A[S],B[A],C[A],C[S],D[A],D0,D1
*
* Calls: 
*
* Stack Levels: 0
*
* Notes:
*						
*  Date     Prog	 Modification
* ------  --------  --------------
*
********************************************************
DrawLineN
	?A<=B	A				* want x1<=x2
	GOYES	+			
	ABEX	A 
	CDEX	A				* swap points
+
	B=B-A	A 
	D=D-C	A 
	ACEX	A				* now B[A]=dx >= 0, D[A]=dy A[A]=y C[A]=x

	C=0		S				* prepare mask bits
	C=C+1	S
	?CBIT=0	0
	GOYES	+ 
	C=C+C	S
+	?CBIT=0	1 
	GOYES	+
	C=C+C	S
	C=C+C	S				* C[S] is now the mask

+	CSRB.F	A 
	CSRB.F	A				* C[A]=x/4
	AR0EX	A				* A[A] = @surface
	C=C+A	A 				* C[A]=@surface+(x/4)
	AR0EX	A				* restore R0[A]
	ABEX	A 
	D1=A					* save dx in D1

*	C=@grob+(x/4), B=y, D=dy, D1=dx
*	next? C=C+34*y i.e., C=C+34*B

	C=C+B	A	
	C=C+B	A				* added 2 times y
	A=B		A
	ASL		A
	C=C+A	A
	C=C+A	A				* added 32 times y

* get some values in nice places	
	AD1EX 
	B=A		A 
	CD0EX 
	LA(5)	34				* surface width in nibbles

* now we have A[A] = surface width, B[A]=dx  D[A]=dy  D0=@pixel  C[S]= pixel mask

* now check if y2<y1

	C=D		A 
	C=C+C	A 
	GONC	+
	D=-D	A				* C=C+C	caused a carry iff C<0
	A=-A	A				* this will be used to update y positions in D0
+

* now test if |dy|>|dx|

	C=D		A 
	?C>B	A 
	GOYES	steep_line

* shallow line
	C=B		A 
	D1=C					* D1=dx (loop counter)
	C=-C	A				*  -dx
	B=B+B	A				*  2dx
	D=D+D	A				* 2*dy
	A=DAT0	S

* starting loop, we have:
* A[S]=nibble from image, A[A] = yincrement, C[S] = mask, C[A]=-dx
* B=2*dx, D=2*dy, D0=ptr to image nibble, D1=dx (loop value counter)

* pixel loop here
-
*	'PIXEL' - select from the 3 pixel commands below
	A=A!C	S				* A=A OR C - set pixel - 1/1
*	B=C	S					* A=A AND (NOT C) - clear pixel - 1/3
*	B=-B-1	S				* A=A AND (NOT C) - clear pixel - 2/3
*	A=A&B	S				* A=A AND (NOT C) - clear pixel - 3/3
*	B=C		S				* A=A XOR C - toggle pixel - 1/5
*	B=B&A	S				* A=A XOR C - toggle pixel - 2/5
*	A=A!C	S 				* A=A XOR C - toggle pixel - 3/5
*	B=-B-1	S				* A=A XOR C - toggle pixel - 4/5
*	A=A&B	S				* A=A XOR C - toggle pixel - 5/5

	C=C+C	S				* new mask
	GOC		NewMask			* overflowed
	C=C+D	A				*
	GOC		IncY			* c:=c+2dy; ?c>=0 goto IncY
	D1=D1-	1 				* do this many pixels
	GONC	- 
	DAT0=A	S				* save current nibble back
	RTN						* can return here (bad practice?)
NewMask 
	C=C+1	S				* fix pixel mask
	DAT0=A	S				* save current nibble back
	D0=D0+	1				* x:=x+1, went to new nibble
	C=C+D	A				* 
	GOC		IncY2
	A=DAT0	S				* read nibble
	D1=D1-	1				* and loop (if needed)
	GONC	-
	RTN						* can return here (bad practice?)
IncY
	DAT0=A	S				* save value out
IncY2 
	C=C-B	A 				* y:=y+1; c:=c-2*dx;
	CD0EX 
	C=C+A	A 
	CD0EX					
	A=DAT0	S				* read new nibble in
	D1=D1-	1 
	GONC	-
	DAT0=A	S				* save current nibble back
	RTN						* can return here (bad practice?)

*steep line
steep_line

	D1=C                    * D1=dy (loop counter)
	C=-C	A				*  -dy
	D=D+D	A				* 2*dy
	B=B+B	A				* 2*dx

* starting loop, we have:
* A[S]=nibble from image, A[A] = yincrement, C[S] = mask, C[A]=-dy
* B=2*dx, D=2*dy, D0=ptr to image nibble, D1=dy (loop value counter)

-
	A=DAT0	S				* read nibble
*	'PIXEL' - select from the 3 pixel commands below
	A=A!C	S				* A=A OR C - set pixel - 1/1
*	B=C	S					* A=A AND (NOT C) - clear pixel - 1/3
*	B=-B-1	S				* A=A AND (NOT C) - clear pixel - 2/3
*	A=A&B	S				* A=A AND (NOT C) - clear pixel - 3/3
*	B=C		S				* A=A XOR C - toggle pixel - 1/5
*	B=B&A	S				* A=A XOR C - toggle pixel - 2/5
*	A=A!C	S 				* A=A XOR C - toggle pixel - 3/5
*	B=-B-1	S				* A=A XOR C - toggle pixel - 4/5
*	A=A&B	S				* A=A XOR C - toggle pixel - 5/5

	DAT0=A	S				* store nibble
	CD0EX					* y:=y+1
	C=C+A	A 
	CD0EX   
	C=C+B	A				* c:=c+2*dx
	GONC	+		                 
	
	C=C-D	A				* IF c>=0 THEN x:=x+1; c:=c+2*dy
	C=C+C	S				* next pixel mask
	GONC	+				* mask ok
	C=C+1	S				* reset mask
	D0=D0+	1				* move nibble over
+	D1=D1-	1 
	GONC	-
*	DAT0=A	S				* store final nibble
	RTN
* end of DrawLineN routine


********************************************************
* ** NAME: EraseLineN - erases pixels on a line on a 1 bit surface 131x... (Normal surface)
*					   only assumes 34 nibbles wide surface
* Category:
*
* Purpose:
*
* Entry: now values are (x1=A[A],y1=C[A]) (x2=B[A],y2=D[A]) address of surface R0[A]
*
* Exit:
*
* Alters: A[A],A[S],B[A],C[A],C[S],D[A],D0,D1
*
* Calls: 
*
* Stack Levels: 0
*
* Notes:
*						
*  Date     Prog	 Modification
* ------  --------  --------------
*
********************************************************
EraseLineN
	?A<=B	A				* want x1<=x2
	GOYES	+			
	ABEX	A 
	CDEX	A				* swap points
+
	B=B-A	A 
	D=D-C	A 
	ACEX	A				* now B[A]=dx >= 0, D[A]=dy A[A]=y C[A]=x

	C=0		S				* prepare mask bits
	C=C+1	S
	?CBIT=0	0
	GOYES	+ 
	C=C+C	S
+	?CBIT=0	1 
	GOYES	+
	C=C+C	S
	C=C+C	S				* C[S] is now the mask

+	CSRB.F	A 
	CSRB.F	A				* C[A]=x/4
	AR0EX	A				* A[A] = @surface
	C=C+A	A 				* C[A]=@surface+(x/4)
	AR0EX	A				* restore R0[A]
	ABEX	A 
	D1=A					* save dx in D1

*	C=@grob+(x/4), B=y, D=dy, D1=dx
*	next? C=C+34*y i.e., C=C+34*B

	C=C+B	A	
	C=C+B	A				* added 2 times y
	A=B		A
	ASL		A
	C=C+A	A
	C=C+A	A				* added 32 times y

* get some values in nice places	
	AD1EX 
	B=A		A 
	CD0EX 
	LA(5)	34				* surface width in nibbles

* now we have A[A] = surface width, B[A]=dx  D[A]=dy  D0=@pixel  C[S]= pixel mask

* now check if y2<y1

	C=D		A 
	C=C+C	A 
	GONC	+
	D=-D	A				* C=C+C	caused a carry iff C<0
	A=-A	A				* this will be used to update y positions in D0
+

* now test if |dy|>|dx|

	C=D		A 
	?C>B	A 
	GOYES	steep_line_e

* shallow line
	C=B		A 
	D1=C					* D1=dx (loop counter)
	C=-C	A				*  -dx
	B=B+B	A				*  2dx
	D=D+D	A				* 2*dy
	A=DAT0	S

* starting loop, we have:
* A[S]=nibble from image, A[A] = yincrement, C[S] = mask, C[A]=-dx
* B=2*dx, D=2*dy, D0=ptr to image nibble, D1=dx (loop value counter)

*	DEBUG

* pixel loop here
-
*	'PIXEL' - select from the 3 pixel commands below
*	A=A!C	S				* A=A OR C - set pixel - 1/1
	B=C	S					* A=A AND (NOT C) - clear pixel - 1/3
	B=-B-1	S				* A=A AND (NOT C) - clear pixel - 2/3
	A=A&B	S				* A=A AND (NOT C) - clear pixel - 3/3
*	B=C		S				* A=A XOR C - toggle pixel - 1/5
*	B=B&A	S				* A=A XOR C - toggle pixel - 2/5
*	A=A!C	S 				* A=A XOR C - toggle pixel - 3/5
*	B=-B-1	S				* A=A XOR C - toggle pixel - 4/5
*	A=A&B	S				* A=A XOR C - toggle pixel - 5/5

	C=C+C	S				* new mask
	GOC		NewMaskE		* overflowed
	C=C+D	A				*
	GOC		IncYE			* c:=c+2dy; ?c>=0 goto IncY
	D1=D1-	1 				* do this many pixels
	GONC	- 
	DAT0=A	S				* save current nibble back
	RTN						* can return here (bad practice?)
NewMaskE 
	C=C+1	S				* fix pixel mask
	DAT0=A	S				* save current nibble back
	D0=D0+	1				* x:=x+1, went to new nibble
	C=C+D	A				* 
	GOC		IncY2E
	A=DAT0	S				* read nibble
	D1=D1-	1				* and loop (if needed)
	GONC	-
	RTN						* can return here (bad practice?)
IncYE
	DAT0=A	S				* save value out
IncY2E 
	C=C-B	A 				* y:=y+1; c:=c-2*dx;
	CD0EX 
	C=C+A	A 
	CD0EX					
	A=DAT0	S				* read new nibble in
	D1=D1-	1 
	GONC	-
	DAT0=A	S				* save current nibble back
	RTN						* can return here (bad practice?)

*steep line
steep_line_e

	D1=C                    * D1=dy (loop counter)
	C=-C	A				*  -dy
	D=D+D	A				* 2*dy
	B=B+B	A				* 2*dx

* starting loop, we have:
* A[S]=nibble from image, A[A] = yincrement, C[S] = mask, C[A]=-dy
* B=2*dx, D=2*dy, D0=ptr to image nibble, D1=dy (loop value counter)

-
	A=DAT0	S				* read nibble
*	'PIXEL' - select from the 3 pixel commands below
*	A=A!C	S				* A=A OR C - set pixel - 1/1
	B=C	S					* A=A AND (NOT C) - clear pixel - 1/3
	B=-B-1	S				* A=A AND (NOT C) - clear pixel - 2/3
	A=A&B	S				* A=A AND (NOT C) - clear pixel - 3/3
*	B=C		S				* A=A XOR C - toggle pixel - 1/5
*	B=B&A	S				* A=A XOR C - toggle pixel - 2/5
*	A=A!C	S 				* A=A XOR C - toggle pixel - 3/5
*	B=-B-1	S				* A=A XOR C - toggle pixel - 4/5
*	A=A&B	S				* A=A XOR C - toggle pixel - 5/5

	DAT0=A	S				* store nibble
	CD0EX					* y:=y+1
	C=C+A	A 
	CD0EX   
	C=C+B	A				* c:=c+2*dx
	GONC	+		                 
	
	C=C-D	A				* IF c>=0 THEN x:=x+1; c:=c+2*dy
	C=C+C	S				* next pixel mask
	GONC	+				* mask ok
	C=C+1	S				* reset mask
	D0=D0+	1				* move nibble over
+	D1=D1-	1 
	GONC	-
*	DAT0=A	S				* store final nibble
	RTN
* end of EraseLineN routine
* end DrawLine.s