	.PREL
	.IDENT	GRAPHICS
	.INSERT	HVG.LIB
	.INSERT	MACRO.LIB
	.INSERT	BBEQU.ASM
	.RELOC
FR.P1=2
FR.P2=4
FR.P3=6
FR.P4=8
FR.P5=10
FR.P6=12
FR.P7=14
FR.P8=16
BX.X=10
BX.Y=8
BX.XS=6
BX.YS=4
BX.MOD=2
CLP.S=6
CLP.C=10
	.DEFINE	GETARG[NARGS,%RETPL]=
[	MVI	A,NARGS
	LXI	H,%RETPL
	JMP	GETART
%RETPL: ]
	.DEFINE	FRAME=[
	PUSH	Y
	LXI	Y,0
	DADY	SP]
	.DEFINE	UNFRAME=[
	POP	Y]
PIXFUN:: TSTC	'(',PIXDUD
	PUSH	B
	RSTEXP
	PUSH	H
	TSTCC	COMMA,PIXDUD
	RSTEXP
	TSTC	')',PIXDUD
	POP	B
	PUSH	D
	MOV	D,L
	MOV	E,C
	CALL	GPIXEL
	MOV	L,A
	MVI	H,0
	POP	D
	POP	B
	RET
; PIXEL COMMAND
; ROUTINE TO INTERROGATE PIXEL
GPIXEL:	CALL	R2ACLP
	MOV	B,A
	MVI	A,4
	RC
	INR	B
	MOV	A,M
..SHFT:	RLC
	RLC
	DJNZ	..SHFT
	ANI	3
	RET
; GET PARAMETERS AND SHOVE THEM ON THE STACK ROUTINE
; IN A = # PARMS HL= WHERE TO RETURN TO
GETART:: PUSH	H
	PUSH	PSW
	RSTEXP
	POP	PSW	; NEED TO LOOK FOR COMMA?
	PUSH	PSW
	DCR	A
	JRZ	..NOC
	TSTCC	COMMA,PIXDUD
..NOC:	POP	PSW
	XTHL
	DCR	A
	JRNZ	GETART
	PCHL
PIXDUD:	JMP	QWHAT#
; POINT DRAW ROUTINE
POINT::	GETARG	3
	POP	H
	MOV	A,L
	POP	H
	POP	B
	PUSH	D
	MOV	D,L
	MOV	E,C
	CALL	POINTR
	POP	D
	RSTFIN
; POINT ROUTINE
; A=MODE PARAMETER
; DE= Y,X COORDINATES
; HL=SMASHED
POINTR:	BIT	2,A	; OR OR XOR?
	JRNZ	PRPLOP	; NO
; OR OR XOR - SET XPAND
	RLC
	RLC
	ANI	0FCH
	OUT	XPAND
	BIT	5,A
	JRNZ	ORPT
XORPT:	CALL	R2ACLP
	RC
	ORI	0101000B
	JMPR	ORJOIN
ORPT:	CALL	R2ACLP
	RC
	ORI	0011000B
ORJOIN:	OUT	MAGIC
	RES	6,H
	MVI	M,80H
	RET
PRPLOP:	BIT	3,A
	JRNZ	PRIORW
PLOP:	PUSH	B
PLOP1:	OUT	XPAND
	MVI	A,00001000B
	OUT	MAGIC
	STA	0FFFH
	LDA	4FFFH
	MOV	B,A
	CALL	R2ACLP
	JRC	PLOPNG
	ORI	00001000B
	OUT	MAGIC
	MVI	A,10001100B
	OUT	XPAND
	STA	0FFFH
	LDA	4FFFH
	MOV	C,A
	MOV	A,B
	XRA	M
	ANA	C
	XRA	M
	MOV	M,A
PLOPNG:	POP	B
	RET
; PRIORITY
PRIORW:	PUSH	B
	ANI	3
	MOV	C,A
	CALL	GPIXEL
	CMP	C	; COMPARE TO WHATS THERE
	JRNC	PLOPNG
	MOV	A,C
	JMPR	PLOP1
; TERSE CIRCLE COMMAND
CIRCLE::
	GETARG	4
	FRAME
	PUSH	D
	LXI	H,1		; XA=1
	SHLD	CIRXA#
	DCX	H		; HL=0
	MOV	E,FR.P2(Y)	; DE=R
	MOV	D,FR.P2+1(Y)
	PUSH	D
	DCX	D
	CALL	CIRPNT		; DRAW AT 0,R
	XCHG
	CALL	NEGHL
	XCHG
	CALL	CIRPNT		; AND AT 0,-R
	POP	H		; R IS IN HL
	DAD	H
	DCX	H
	SHLD	CIRYA#
	DCX	H		; DELTA=YA-1
	SHLD	CIRDEL#
CLOOP:
	LHLD	CIRDEL#		; D=DELTA*2
	DAD	H
	BIT	7,H		; IS D<0?
	JRNZ	DMINUS		; YEP
	LDED	CIRYA#		; NO, COMPUTE D=D-YA
	ANA	A
	DSBC	D
	BIT	7,H		; NOW IS D<0?
	JRNZ	CBOTH		; YEP - DO BOTH MOVES
	LHLD	CIRXA#		; NO XA=XA+2
	INX	H
	INX	H
	SHLD	CIRXA#
	XCHG
	LHLD	CIRDEL#		; DELTA=DELTA-XA
	ANA	A
	DSBC	D
	JMPR	DSTOR
; D < 0 CASE
DMINUS:
	LDED	CIRXA#		; D=D+XA
	DAD	D
	BIT	7,H		; IF D<0
	JRZ	CBOTH		; BUMP BOTH
	LHLD	CIRYA#		; ELSE YA=YA-2
	DCX	H
	DCX	H
	SHLD	CIRYA#
	XCHG
	LHLD	CIRDEL#		; DELTA=DELTA+YA
	DAD	D
	JMPR	DSTOR
; INCREMENT BOTH
CBOTH:	LHLD	CIRXA#		; XA=XA+2
	INX	H
	INX	H
	SHLD	CIRXA#
	XCHG
	LHLD	CIRYA#		; YA=YA-2
	DCX	H
	DCX	H
	SHLD	CIRYA#
	LBCD	CIRDEL#		; DELTA=DELTA+YA-XA
	DAD	B
	ANA	A
	DSBC	D
DSTOR:	SHLD	CIRDEL#
	LHLD	CIRYA#
	DCX	H	; IF NEG, 0 OR 1
	DCX	H
	BIT	7,H
	JRZ	..CYOK
; CLOSE TO DONE - DRAW LAST TWO POINTS
	LXI	D,0
	MOV	L,FR.P2(Y)	; HL=R
	MOV	H,FR.P2+1(Y)
	CALL	CIRPNT	; AT R,0
	CALL	NEGHL
	CALL	CIRPNT	; AND -R,0
; WE ARE DONE
	POP	D		; YES - GO HOME
	UNFRAME
	POP	H
	POP	H
	POP	H
	POP	H
	RSTFIN
..CYOK:
; SUBROUTINE TO DRAW 4 POINTS
; AT X,Y -X,Y -X,-Y AND X,-Y
DRAW4:	LHLD	CIRYA#
	CALL	DIV2HL
	PUSH	H
	XCHG
	LHLD	CIRXA#
	CALL	DIV2HL
	CALL	CIRPNT	; X,Y
	XCHG
	CALL	NEGHL
	XCHG
	CALL	CIRPNT
	CALL	NEGHL		; -X
	CALL	CIRPNT		; -X,-Y
	POP	D		; -X,Y
	CALL	CIRPNT
	JMP	CLOOP
CIRPNT:	PUSH	H
	PUSH	D
	MOV	C,FR.P4(Y)	; GET X TRANS FACTOR
	MOV	B,FR.P4+1(Y)
	DAD	B
; GROSS CLIP CHECK
	MOV	A,L		; SIGN OF L TO CY
	RLC
	MOV	A,H
	ACI	0
	JRNZ	..CIRX
	XCHG
	MOV	C,FR.P3(Y)	; Y TRIP
	MOV	B,FR.P3+1(Y)
	DAD	B
	MOV	A,L
	RLC
	MOV	A,H
	ACI	0
	JRNZ	..CIRX
	MOV	D,L
	MOV	A,FR.P1(Y)
	CALL	POINTR
..CIRX:	POP	D
	POP	H
	RET
DIV2HL:
	ANA	A
	MOV	A,H
	RAR
	MOV	H,A
	MOV	A,L
	RAR
	MOV	L,A
	RET
NEGHL:
	MOV	A,H
	CMA
	MOV	H,A
	MOV	A,L
	CMA
	MOV	L,A
	INX	H
	RET
;  SCROLL COMMAND
; BASIC LINK IN
SCROLC::
	CALL	SCCLNK
	RSTFIN
SCCLNK:
	GETARG	5
; ENTRY FROM CHAR DISPLAY
SCROLE::
	FRAME
	PUSH	D
	CALL	CLIP
	JRC	..NOSC
; CONVERT X SIZE TO BYTES
	MOV	A,BX.XS(Y)
	ADI	3
	RRC
	RRC
	ANI	3FH
	MOV	C,A
; WHICH DIRECTION?
	MOV	A,BX.MOD(Y)
	ANA	A
	JRZ	..NOSC
	LXI	D,-40
	MOV	B,BX.YS(Y)
	MOV	A,BX.Y(Y)
	JM	..MINU
; POSITIVE CASE
	LXI	D,40
	ADD	B
	DCR	A
..MINU:	DCR	B	; FUDGE Y SIZE
	JRZ	..NOSC	; SKIP IF WAS ONLY 1
	PUSH	D
	MOV	D,A
	MOV	E,BX.X(Y)
	CALL	R2A
	POP	D
	MOV	A,BX.MOD(Y)
	CALL	ABS
..SCR1:	PUSH	B
	PUSH	H
..SCR2:	PUSH	B
	PUSH	D
	MVI	B,0
	XCHG
	DAD	D
	PUSH	H
	LDIR
	POP	H
	POP	D
	POP	B
	DJNZ	..SCR2
..KILL:	MVI	M,0
	INX	H
	DCR	C
	JRNZ	..KILL
	POP	H
	POP	B
	DCR	A
	JRNZ	..SCR1
..NOSC:
	POP	D
	UNFRAME
	POP	H
	POP	H
	POP	H
	POP	H
	POP	H
	RET
SNAP::	GETARG	4
	TSTCC	COMMA,..SDUD
	CALL	TSTVFF#
	PUSH	H
	FRAME
	PUSH	D
	CALL	CLIP
	JRC	..NOSN
	PUSH	X
	MOV	A,BX.XS(Y)
	MOV	L,BX.MOD(Y)
	MOV	H,BX.MOD+1(Y)
	MOV	M,A		; STUFF X SIZE OF PAT
	INX	H
	MVI	M,0
	INX	H
	ADI	3
	RRC
	RRC
	ANI	3FH
	MOV	E,A
	MOV	D,BX.YS(Y)
	MOV	M,D
	INX	H
	MVI	M,0
	INX	H
	PUSH	H
	POP	X
	PUSH	D
	MOV	E,BX.X(Y)
	MOV	A,BX.Y(Y)
	ADD	D
	DCR	A
	MOV	D,A
	CALL	R2A
	PUSH	H		; IY=SOURCE POINTER
	POP	Y
	MOV	C,A		; C=SHIFT AMOUNT
	POP	D		; DE=SIZES
	JRZ	..EASY		; JUMP ON EASY CASE
; CASE OF FIRST PIXEL TO SNAP NOT BEING ON BYTE BOUNDARY
..HARD:	PUSH	D
	PUSH	Y
	MOV	H,0(Y)		; H=FIRST BYTE TO START
..HDBL:	INX	Y		; BUMP SOURCE
	MOV	D,0(Y)		; D=NEXT GUY
	MOV	L,D		; INTO L AS WELL
	MOV	B,C		; REINIT SHIFT AMT
..HDSL:	DAD	H		; SHIFT OVER SA PIXELS
	DAD	H
	DJNZ	..HDSL
	MOV	0(X),H		; STUFF TO DEST
	MOV	H,D		; SETUP FOR NEXT ITERATION
	INX	X
	DCR	E
	JRNZ	..HDBL
	POP	Y		; TO NEXT LINE
	LXI	D,40
	DADY	D
	POP	D
	DCR	D
	JRNZ	..HARD
	JMPR	..SNPD
..SDUD:	JMP	QWHAT#
; FASTER LOOP FOR ZERO SHIFT AMOUNT CASE
..EASY:	LXI	B,40
..EZLL:	MOV	A,E
	PUSH	Y
..EZBL:	MOV	L,0(Y)
	MOV	0(X),L
	INX	X
	INX	Y
	DCR	A
	JRNZ	..EZBL
	POP	Y
	DADY	B
	DCR	D
	JRNZ	..EZLL
;
..SNPD:
	POP	X
..NOSN:	POP	D
	UNFRAME
	POP	H
	POP	H
	POP	H
	POP	H
	POP	H
	RSTFIN
; TERSE SHOW COMMAND
SHOW::
	GETARG	3
	TSTCC	COMMA,..SHWD
	CALL	TSTVFF#
	JMPR	..SHOK
..SHWD:	JMP	QWHAT#
..SHOK:	POP	B
	MOV	A,C	; SAVE MODE
	MVI	B,0
	MOV	C,M
	PUSH	B
	INX	H
	INX	H
	MOV	C,M
	PUSH	B
	PUSH	D
	FRAME
	PUSH	D
	PUSH	H
	PUSH	PSW
	PUSH	H
	CALL	CLIP
	POP	H
	JRC	..NOSH
	MOV	A,BX.YS(Y)
	CMP	M	; DID Y SIZE SHRINKO?
	JRNZ	..NOSH	; YES
	MOV	B,A	; NO
	DCX	H	; TO X SIZE
	DCX	H
	MOV	A,BX.XS(Y) ; LOOKAT X SIZE
	CMP	M
	JRNZ	..NOSH
	ADI	3	; COMPUTE X SIZE IN BYTES
	RRC
	RRC
	ANI	3FH
	MOV	C,A
; GET AND FIX COORDINATES
	MOV	A,BX.Y(Y)
	ADD	B	; FUDGE TO TOP OF BOX
	DCR	A
	MOV	D,A
	MOV	E,BX.X(Y)
	CALL	R2A
	MOV	D,A
	POP	PSW	; RESTORE MODE
	RLC
	RLC
	RLC
	RLC
	ANI	30H
	ORA	D
	OUT	MAGIC
	RES	6,H	; MAKE ADDRESS MAGIC
	POP	D
	INX	D	; MOVE PAST Y SIZE
	INX	D
	XCHG		; HL=SOURCE, DE=DEST
; NORMAL? WRITE
..NWRT:	XRA	A
	PUSH	B
	PUSH	D
	MOV	B,A
	LDIR
	STAX	D
	POP	D
	XCHG
	MVI	C,BYTEPL
	DAD	B
	XCHG
	POP	B
	DJNZ	..NWRT
	JMPR	..OK
..NOSH:	POP	PSW
	POP	PSW
..OK:	POP	D
	UNFRAME
	POP	H
	POP	H
	POP	H
	POP	H
	POP	H
	RSTFIN
; BOX COMMAND
BOXDRW:: CALL	BOXLNK
	RSTFIN
BOXLNK: GETARG	5
DOBOX::	FRAME
	PUSH	D
	CALL	CLIP
..SKPL:	JRC	..SKIP		; ABORT IF TOTAL OFFSCREEN
; WE NOW HAVE REASONABLE STUFF ON OUR STACK
; LETS DEAL WITH MODE STUFF NOW
	MOV	C,BX.MOD(Y)
	MOV	A,C		; IS MODE ZERO?
	ANA	A
	JRZ	..SKIP		; YEP - IGNORE
	ANI	4		; ISOLATE WRITE MODE
	STA	WRMODE#
	MOV	A,C		; ISOLATE PIXEL NUMBER
	ANI	3
	MOV	C,A
	MVI	B,0		; LOOKUP BYTE OF THOSE GUYS
	LXI	H,MSKTBL
	DAD	B
	MOV	A,M
	STA	PIXVAL#
; NOW THE EXCITING BOX PAINTING STARTS
	MOV	E,BX.XS(Y)
..BOXP:	MOV	A,E
	ANA	A
	JRZ	..SKIP
; IS MOD(X,4)=1?
	MOV	A,BX.X(Y)
	ANI	3
	CPI	1
	JRNZ	..MNZ
; YES - IS XS>4?
	MOV	A,E
	CPI	4
	JRC	..XSL4
; YS IS >4 - SO PAINT A FULL STRIPE
	MVI	C,0FFH		; DO WHOLE KIT AND KABOODLE
	CALL	..STRC
	MVI	D,4		; A=X ADDR SUBTRACTOR
	JMPR	..XSTF
..MNZ:	DCR	A
	ANI	3
	MOV	C,A
	MVI	A,4
	SUB	C
	CMP	E		; COMPARE TO XS
	JRC	..XSBG
	MOV	A,E		; MOD IS BIGGER
..XSBG:	MOV	B,A		; B=MIN
	MOV	D,A
	XRA	A		; FORM BIT MASK
..BITF:	RRC
	RRC
	ORI	11000000B
	DJNZ	..BITF
	MOV	B,C
..DOSF:	RRC
	RRC
	ANI	3FH
	DJNZ	..DOSF
	MOV	C,A		; REMEMBERIZE
	CALL	..STRC
..XSTF:	MOV	A,D
	ADD	BX.X(Y)		; UPDATE X COORDINATE
	MOV	BX.X(Y),A
	MOV	A,E		; AND PIXELS LEFT (XS)
	SUB	D
	MOV	E,A
	JMPR	..BOXP		; LOOP BACK FOR MORE
; PAINT A FINAL STRIPE
..XSL4:	MOV	B,A
	XRA	A
..XSLA:	RRC
	RRC
	ORI	11000000B
	DJNZ	..XSLA
	MOV	C,A
	CALL	..STRC
..SKIP:
	POP	D
	UNFRAME
	POP	H
	POP	H
	POP	H
	POP	H
	POP	H
	RET
; LOOP TO PAINT A BOX STRIPE
; MASK TO USE PASSED IN C
..STRC:	PUSH	D
	MOV	D,BX.Y(Y)
	MOV	E,BX.X(Y)
	CALL	R2A		; CONVERT COORDINATES
	LXI	D,-40		; NEGATIVE SCREEN INCREMENT
	MOV	B,BX.YS(Y)	; B=Y SIZE
	LDA	WRMODE#		; WHICH TIGHT LOOP TO USE?
	ANA	A
	JRNZ	..PLOP
; WRITE MAGIC (XOR FOR NOW)
..XORL:	LDA	PIXVAL#
	ANA	C
	XRA	M
	MOV	M,A
	DAD	D
	DJNZ	..XORL
	POP	D
	RET
; PLOP WRITE LOOP
..PLOP:	LDA	PIXVAL#
	XRA	M
	ANA	C
	XRA	M
	MOV	M,A
	DAD	D
	DJNZ	..PLOP
	POP	D
BOXPUT::	RET
; CLIP BOTH COORDINATES ROUTINE
CLIP:
	LHLD	WINPTR#
	CALL	CLIPPER
	RC
	PUSH	Y
	DCX	Y
	DCX	Y
	LHLD	WINPTR#
	INX	H
	INX	H
	INX	H
	INX	H
	CALL	CLIPPER
	POP	Y
	RET
; CLIP COORDINATE ROUTINE
; HL = PARM AREA START IN WINDOW TABLE
; IY POINTS TO STACK FRAME SUCH THAT
; SIZE IS 6 BYTES DOWN, COORDINATE 10 BYTES DOWN
CLIPPER:
	MOV	E,M	; GET UPPER LIMIT
	INX	H
	MOV	D,M
	INX	H
	MOV	C,M	; GET LOWER LIMIT
	INX	H
	MOV	B,M
	PUSH	B
	MOV	L,CLP.C(Y)		; HL=COORDINATE
	MOV	H,CLP.C+1(Y)
	MOV	C,CLP.S(Y)		; BC=SIZE
	MOV	B,CLP.S+1(Y)
	CALL	..TSTB		; BARF IF <= 0
	JRZ	..NODR
	DCX	B
	CALL	..DVBC		; BC=BC DIVIDE 2
	ANA	A
	DSBC	B		; HL=LOWER
	MOV	CLP.C(Y),L		; STUFF BACK STUFF
	MOV	CLP.C+1(Y),H
	XCHG			; TO DE
	CALL	CPHLDE		; IS LOWER>UL?
	JRC	..NODR		; DONT DRAW
	XTHL
	CALL	CPHLDE		; IS LOWER < LOWER LIMIT?
	JRC	..LOK
	PUSH	H		; SAVE LOWER LIMIT
	XCHG			; HL=LOWER,DE=LL
	ANA	A
	DSBC	D		; HL=LOWER - LIMIT
	XCHG
	MOV	L,CLP.S(Y)		; HL=SIZE
	MOV	H,CLP.S+1(Y)
	DAD	D
	MOV	CLP.S(Y),L		; STORE BACK
	MOV	CLP.S+1(Y),H
	CALL	..TSTH		; IF H<= 0 ABORT
	JRZ	..NOD1
	POP	H		; SET COORDINATE AT
	MOV	CLP.C(Y),L		; LOWER LIMIT
	MOV	CLP.C+1(Y),H
; DEAL WITH OTHER END
..LOK:	XCHG		; DE=LOWER LIMIT
	MOV	L,CLP.C(Y)		; HL=COORDINATE
	MOV	H,CLP.C+1(Y)
	MOV	C,CLP.S(Y)		; BC=SIZE
	MOV	B,CLP.S+1(Y)
	CALL	..TSTB
	JRZ	..NODR
	DCX	B
	DAD	B		; ADD TO LOWER EDGE
	XCHG			; UPPER TO DE
	CALL	CPHLDE		; CAN WE DRAW?
	POP	H		; H=UL
	JRZ	..UOK		; JUMP IF ON EDGE
	JRNC	..NOD2		; IF UPPER < LOWER LIMIT DONT
	CALL	CPHLDE		; IS UPPER > UL?
	JRNC	..UOK		; NO PROB
	ANA	A		; COMPUTE SIZE FUDGE
	DSBC	D
	XCHG			; TO DE
	MOV	L,CLP.S(Y)
	MOV	H,CLP.S+1(Y)
	DAD	D		; HL=NEW SIZE
	MOV	CLP.S(Y),L
	MOV	CLP.S+1(Y),H
	CALL	..TSTH	; IF HL<=0 ABORT
	JRZ	..NOD2
..UOK:	ANA	A		; RETURN CARRY CLEAR
	RET			; FOR GOOD GUYS
..NOD1:	POP	H		; BAD GUY - CLEAN UP STACK
..NODR:	POP	H
..NOD2:	STC			; CY FOR DONT DRAW
	RET
; TEST FOR BC BEING <= 0
..TSTB:	MOV	A,B
	ANA	A
	JM	..LESZ
	ORA	C
	RET
..LESZ:	XRA	A
	RET
; SIMILAR ROUTINE FOR HL
..TSTH:	MOV	A,H
	ANA	A
	JM	..LESZ
	ORA	L
	RET
; DIVIDE BC BY 2
..DVBC:	ANA	A
	MOV	A,B
	RAR
	MOV	B,A
	MOV	A,C
	RAR
	MOV	C,A
	RET
; ROUTINE TO COMPARE HL TO DE
; RETURNS CY SET FOR HL<DE (OR DE>HL)
;	CY CLEAR, ZERO SET IF HL=DE
;	CY CLEAR, ZERO CLEAR IF HL>DE (OR DE<HL)
CPHLDE:: MOV	A,H
	XRA	D		; ARE SIGNS DIFF?
	JP	..CK1		; NO
	XCHG			; YES - REVERSE ARGS
	CALL	..CK1		; DO CHECK
	XCHG			; BACK TO NORMAL
	RET
..CK1:	MOV	A,H
	CMP	D
	RNZ
	MOV	A,L
	CMP	E
	RET
; SCREEN CLEAR COMMAND - CLEARS ENTIRE SCREEN AND RESETS
; VDM CURSOR AS WELL
CLRSCR::
; ENTRY FROM TAPE STUFF TO CLEAR OFF SCREEN
ENTCLR::
	CALL	HKCLRS#
	PUSH	D
	LXI	H,4000H
	MOV	M,L
	LXI	D,4001H
	LXI	B,0FFFH
	LDIR
	CALL	RESCXY#	; CALL CURSOR RESET
	POP	D
	RSTFIN
LINEDR::
	GETARG	3
	FRAME
	PUSH	D
	LDED	OLDXY#
	MOV	H,FR.P2(Y)
	MOV	L,FR.P3(Y)
	SHLD	OLDXY#
	MOV	A,FR.P1(Y)
	ANA	A
	JRZ	..NODR
	CALL	DVECT
..NODR:	POP	D
	UNFRAME
	POP	H
	POP	H
	POP	H
	RSTFIN
; STRANGE TABLE ...
MSKTBL:	.BYTE	0,055H,0AAH,0FFH
; THIS ROUTINE IMPLEMENTS LARRY LIVERMORE'S VECTOR
; DRAWING ALGORITHM.  SEE ZGRASS TECH DOC
; INPUT:	L = X1 COORDINATE
;		H = Y1 COORDINATE
;		E = X2 COORDINATE
;		D = Y2 COORDINATE
;
; OUTPUT:	A = 0, DE = X2,Y2, BC, HL CLOBBERED
; RAM USE:
; INCRO		2 BYTES	HOLDS X,Y INCREMENTS
; MNMX		2 BYTES	HOLDS MIN, MAX DELTAS
; PIXVAL	1 BYTE HOLDS LEFT JUSTIFIED PIXEL FOR XOR WRITE
; WRMODE	1 BYTE HOLDS PLOP-XOR FLAG
; COMPUTE DELTAS AND ABS(DELTAS)
DVECT:	PUSH	D
	MOV	B,L	; COMPUTE Y STUFF
	MOV	C,E
	CALL	CDELTA
	MOV	E,B
	MOV	L,C
	MOV	B,H
	MOV	C,D	; AND X STUFF
	CALL	CDELTA
	MOV	H,C
	MOV	D,B
	SHLD	INCRO#
; DECIDE WHICH IS BIGGER - CALL BIGGER MX, SMALLER MN
	MVI	C,0
	MOV	A,D
	CMP	E
	JRC	..DV1
	MOV	D,E
	MOV	E,A
	INR	C
..DV1:	MOV	A,D
	SRLR	A
	MOV	B,A
	XCHG
	SHLD	MNMX#
	POP	D
	MOV	A,L
	INR	A
VECT2:	PUSH	PSW
	MOV	A,FR.P1(Y)
	CALL	POINTR	; DRAW THE POINT!
; NOW INCREMENT COORDINATES
VECT2A:	LHLD	MNMX#
	MOV	A,B
	ADD	H
	CMP	L
	JRC	VECT4	; JUMP IF NOT
; M+MN IS >=MX, SET M=MOD(M+MN,MX)
	SUB	L
	MOV	B,A
; INCREMENT BOTH DIRECTIONS
	LHLD	INCRO#
	MOV	A,D	; CONFUSE Y
	ADD	H
	MOV	D,A
VECT3:	MOV	A,E	; THEN X
	ADD	L
	MOV	E,A
	JMPR	VECT5
; M + MN IS < MX, SET M = M + MN
VECT4:	MOV	B,A
; INCREMENT ONLY MAX DIMENSION
	LHLD	INCRO#
	MOV	A,C	; C = DIRECTION FLAG
	RRC
	JRNC	VECT3	; 0=>X, SO GO DO IT
	MOV	A,D	; Y CASE
	ADD	H
	MOV	D,A
; END OF LOOP
VECT5:	POP	PSW
	DCR	A
	JRNZ	VECT2
	RET
; SUBROUTINE TO COMPUTE DELTA AND INCREMENT FOR TWO COORDINATES
CDELTA:	PUSH	H
	PUSH	D
	MOV	L,C
	CALL	SGNEXT
	XCHG
	MOV	L,B
	CALL	SGNEXT
	XRA	A
	DSBC	D
	ORA	H
	JRZ	..CD1
	MOV	C,A
	MOV	A,L
	CMA
	INR	A
	MOV	B,A
	JMPR	..CD3
..CD1:	ORA	L
	JRZ	..CD2
	MVI	A,1
..CD2:	MOV	B,L
	MOV	C,A
..CD3:	POP	D
	POP	H
	RET
; SIGN EXTENSION SUBROUTINE
SGNEXT:	MVI	H,0
	MOV	A,L
	ANA	A
	RP
	DCR	H
	RET
; ABSOLUTE VALUE ROUTINE
; THIS ROUTINE COMPUTES THE ABSOLUTE VALUE OF THE ARGUMENT
; PASSED IN A.  THE RESULT IS RETURNED IN A.
ABS:	ANA	A
	RP
	CMA
	INR	A
	RET
; RELATIVE TO ABSOLUTE CONVERSION ROUTINE
; WITH CLIPPING AGAINST BOUNDARYS OF CURRENT WINDOW
R2ACLP::
	LHLD	WINPTR#
	MOV	A,E		; CHECK X UPPER
	CALL	CMPM
	INX	H
	INX	H
	JRZ	..OKX
	JRNC	..BAD
	CALL	CMPM	; CHECK X LOWER
	JRC	..BAD
..OKX:	INX	H
	INX	H
	MOV	A,D
	CALL	CMPM		; CHECK Y UPPER
	JRZ	R2A
	JRNC	..BAD
	INX	H
	INX	H
	CALL	CMPM		; CHECK Y LOWER
	JRNC	R2A
..BAD:	STC
	RET
; NONCLIPPING ENTRY POINT
R2A::	PUSH	B
	MOV	A,D
	CMA
	ADI	52
	MOV	L,A
	MVI	H,0
	DAD	H
	DAD	H
	DAD	H
	MOV	B,H
	MOV	C,L
	DAD	H
	DAD	H
	DAD	B
	MOV	A,E
	ADI	79
	RRC
	RRC
	ANI	3FH
	MOV	C,A
	MVI	B,0
	DAD	B
	SET	6,H
	MOV	A,E
	DCR	A
	ANI	3
	POP	B
	RET
; SPECIAL COMPARE ROUTINE FOR R2ACLP THAT REALLY WORKS
; THIS GUY COMPARES M WITH A
CMPM:	XRA	M	; DO SIGNS DIFFER?
	JM	..REVR	; YEP - REVERSE IT
	XRA	M	; UNDOIT
	CMP	M	; AND COMPARE
	RET
..REVR:	XRA	M	; SAME SCAM
	CMP	M
	CMC		; BUT ZORK THE CY
	RET
	.END
                                                                   