	.TITLE	PLOTER
	.IDENT	/DUMB/
	.MCALL	QIOW$C,QIOW$S,QIO$C,QIO$S,filio$,spcio$
	.NLIST	TTM
	.LIST	MEB
	FILIO$
	SPCIO$
;
;	THIS IS A SET OF PLOTTING ROUTINES FOR THE DUMB TERMINAL WITH
;	RETROGRAPHICS. IT USES STANDARD PLOT 10 ESC SEQUENCES.
;
	.psect	$VARS,RW,D,CON,LCL
GTSBUF:	.BYTE	TC.TTP		; GET TERMINAL TYPE (HOPEFULLY VT05B)
TTYPE:	.BYTE	0
PLOTEN:	.WORD	0
ISTAT:	.BLKW	2
;
;	DATA TABLES
;
ESC=33
EWBUF:	.BYTE	17,34,ESC,14	; LOCK KB:,PT MODE,2*CLEAR+HOME,
	.BYTE	ESC,5		; REQUEST REPLY WHEN DONE
TSTBUF:	.BYTE	34,ESC,5		; REQUEST REPLY WHEN DONE
CURBUF:	.BYTE	35,ESC,32	; Enter vector, and get cursor
ADM:	.BYTE	37,30		; GO TO ADM MODE,UNLOCK KB:
ER100:	.ascii	<esc>/[2J/		; erase entire display
	.ascii	<esc>/[H/		; Set Y
	.even
PCNT:	.BLKW	1		; CONTAINS PARAMETER COUNT
XHI:	.BYTE	0
XLO:	.BYTE	0
YHI:	.BYTE	0
YLO:	.BYTE	0
CNT:	.WORD	0		; NUMBER OF VECTORS (POINTS TO CONVERT)
PLTYPE:	.WORD	0		; CURRENT TYPE OF PLOT
BUFF:	.BLKW	40.		; DATA BUFFER FOR OUTPUT

	.psect
;
;	CALL ERASE	(THIS ERASES THE SCREEN + HOMES CURSOR)
;
ERASE::	MOV	#^RSE ,-(SP)	; SET UP NAME
	MOV	#^RERA,R4	; FIRST 3 CHAR NEXT
	JSR	R4,NAM$		; FOR TRACEBACK
	CALL	SCOPE		; Is it graphics scope
	CMPB	TTYPE,#t.V100	; Check if VT-100
	BNE	ER1		; Not ?
	QIOW$c	IO.WAL,5,1,,ISTAT,,<ER100,7>
ER1:	TSTB	PLOTEN		; Plot terminal ??
	BEQ	RETN		; No
	QIOW$C	IO.RPR!TF.TMO!TF.RNE!TF.BIN,5,1,,ISTAT,,<BUFF,6,1,EWBUF,6>
	CALL	STCLR		; CLEAR STATUS
	JMP	ADMSET		; Return to ADM mode

;
;
;
;
;	THIS MUST BE CALLED BEFORE ANY OTHER PLOT ROUTINES
;
SCOPE::	TSTB	TTYPE		; Do we have type already
	BNE	PLTST		; Yes
	CLRB	PLOTEN
	QIOW$C	SF.GMC,5,1,,,,<GTSBUF,2>
	QIOW$C	IO.RPR!TF.TMO!TF.RNE!TF.BIN,5,1,,ISTAT,,<BUFF,6,1,TSTBUF,3>
	CMP	ISTAT+2,#5	; Successful completion ?
	BNE	RETN		; No plot board ?
	CALL	ADMSET
	DECB	PLOTEN
PLTST:	TSTB	PLOTEN		; Plot enabled ?
	BEQ	RETN		; No ?
RETY:	CLC			; Clear carry
	RETURN
RETN:	SEC			; Set carry for no.
	RETURN
;
;	CALL INTENS(IBRGHT)
;		IBRGHT	= 0	ZERO BRIGHTNESS, ERASE LINES
;		IBRGHT	= 1	NON ZERO BRIGHTNESS, DRAW LINES
;
INTENS::MOV	#^RENS,-(SP)		; SET UP NAME
	MOV	#^RINT,R4		; FIRST 3 CHAR NEXT
	JSR	R4,NAM$			; FOR TRACEBACK
	TST	(R5)+
	CALL	SCOPE		; Graphics scope?
	BCS	RETN		; NO, SO EXIT
	MOV	#BUFF,R4
	MOVB	#34,(R4)+	; SET POINT MODE
	MOVB	#ESC,(R4)+	; ESCAPE
	TST	@(R5)+		; TEST BRIGHTNESS
	BEQ	1$		; NONE
	MOVB	#141,(R4)+	; NON ZERO BRIGHTNESS
	BR	2$
1$:	MOVB	#177,(R4)+	; ZERO BRIGHTNESS
2$:	CALL	WAIT
	JMP	ADMSET
;
;
;	ROUTINE TO PLOT POINTS
;	CALL PTPL(IX,IY [,ISIZE] )
;
PTPL::	MOV	#^RL ,-(SP)		; SET UP NAME
	MOV	#^RPTP,R4		; FIRST 3 CHAR NEXT
	JSR	R4,NAM$			; FOR TRACEBACK
	CALL	MULTI		; MULTIPLE SET UP
	CALL	STCLR
	MOVB	#34,PLTYPE	; SAVE POINT PLOT TYPE
	BR	VECT1		; NOW DO PLOT
;
;	ROUTINE TO PLOT VECTORS
;	CALL VECT(IX,IY [,ISIZE])
;		ISIZE < 0 MEANS START VECTOR AT FIRST IX,IY
;		ISIZE > 0 START VECTOR AT LAST IX,IY PLOTTED
;
STGET:	MOVB	YHI,(R4)+
	MOVB	YLO,(R4)+
	MOVB	XHI,(R4)+
	MOVB	XLO,(R4)+
	RETURN
VECT::	MOV	#^RT ,-(SP)		; SET UP NAME
	MOV	#^RVEC,R4		; FIRST 3 CHAR NEXT
	JSR	R4,NAM$			; FOR TRACEBACK
	CALL	MULTI		; GET INPUT PARAM
	MOVB	#35,PLTYPE	; VECTOR MODE
VECT1:	MOVB	PLTYPE,(R4)+	; SET MODE
	TST	(R3)		; TEST FIRST POINT
	BGE	1$		; POSITIVE IS OK
	CALL	STCLR		; CLEAR OLD VALUE
1$:	TST	CNT		; CHECK IF NO OLD VECTOR
	BGE	2$		; NO
	NEG	CNT		; MAKE IT POSITIVE COUNT
	CALL	STCLR		; CLEAR OUT OLD STATUS
2$:	CALL	STGET		; RESTORE OLD STATUS
3$:	CALL	CONVXY		; CONVERT TO ESC SEQUENCE
	CALL	WAIT
	TST	CNT		; ARE WE DONE?
	BGT	VECT1		; NO CONTINUE
	BR	ADMSET

;
;	CALL PLCHAR(IX,IY,ARRAY,ISIZE)
;
PLCHAR::
CHAR::	MOV	#^RHAR,-(SP)		; SET UP NAME
	MOV	#^RPLC,R4		; FIRST 3 CHAR NEXT
	JSR	R4,NAM$			; FOR TRACEBACK
	CALL	MULTI		; MULTIPLE SET UP
	CLR	CNT		; ONLY 1 ADDRESS
	MOVB	#35,(R4)+	; VECT MODE
	CMP	(R2),#-1	; CHECK IF NO COORDINATE SPEC
	BEQ	10$		; NO COORDINATE
	CALL	STCLR
	CALL	CONVXY		; PLOT 1 POINT
10$:	MOV	(R5)+,R0	; BUFFER ADDRESS FOR CHAR
	CMPB	PCNT,#3		; TEST PARAM COUNT
	BLT	ERROR
	BEQ	20$
	MOV	@(R5)+,R1	; NUMBER OF CHAR
	BGT	1$		; NON ZERO COUNT
20$:	MOV	#5000.,R1	; BAD COUNT
1$:	MOVB	#37,(R4)+	; ALPHA MODE
2$:	MOVB	(R0)+,R2	; GET CHAR
	BEQ	4$		; IF ZERO WE ARE DONE
	BIC	#200,R2		; STRIP TO 7 BIT ASCII
	CMP	R2,#40		; IS IT OK
	BGE	3$		; YES
	CMP	R2,#15		; IS IT GRAPHICS CONTROL?
	BLE	3$		; NO, ACCEPT IT
	MOV	#40,R2		; NO
3$:	MOVB	R2,(R4)+	; SAVE IN BUFFER
	CMP	R4,#BUFF+70.	; BUFFER FILLED?
	BHI	5$		; YES
	SOB	R1,2$		; CONTINUE TILL DONE
4$:	CLR	R1		; NO MORE CHAR
5$:	CALL	WAIT		; WRITE ALPHA + WAIT FOR END
	TST	R1		; ARE WE DONE
	BGT	1$		; NO, CONTINUE
	BR	ADMSET

;
;
;
ERROR:	JMP	BPARM
;
;	THIS SECTION OUTPUTS THE PLOT + WAITS FOR DONE
;
;		WRITE ALL + WAIT FOR REPLY WITH NO ECHO
;
WAIT:	MOVB	#ESC,(R4)+	; ESCAPE
	MOVB	#5,(R4)+	; REQUEST REPLY WHEN DONE
WAIT1:	SUB	#BUFF,R4	; NUMBER OF BYTES TO WRITE
	BLE	1$		; NO DATA TO WRITE
	QIOW$S	#IO.RPR!TF.TMO!TF.RNE!TF.BIN,#5,#1,,#ISTAT,,<#BUFF,#6,#1,#BUFF,R4>
1$:	MOV	#BUFF,R4	; RESET R4 TO START OF BUFFER
	RETURN
;
;	SET BACK TO ADM MODE + ENABLE KB:
;
ADMSET:	QIOW$C	IO.WVB,5,1,,,,<ADM,2>	; SET TO ADM MODE , WAIT
	RETURN

;
;
STCLR:
	CLR	XHI		; CLEAR OLD X STATUS
	CLR	YHI		; ALSO Y
	RETURN
;
;	SET UP ROUTINE TO CHECK PARAM
;
MULTI:	MOVB	(R5),PCNT	; PARAMTER COUNT
	TST	(R5)+		; SKIP PARAM COUNT
	CALL	SCOPE		; Is it graphics scope
	BCS	5$		; No
	CLR	CNT
	MOV	(R5)+,R2	; X COORDINATE BUFFER
	MOV	(R5)+,R3	; Y COORDINATE BUFFER
	CMPB	PCNT,#2		; CHECK ON # OF PARAM
	BLT	ERROR
	CMPB	PCNT,#3
	BNE	1$		; NO COUNT OR IT IS CHAR
	MOV	@(R5),CNT	; BUFFER SIZE
1$:	MOV	#BUFF,R4	; OUTPUT BUFFER
	MOVB	#17,(R4)+	; Turn off KB:
	RETURN
5$:	TST	(SP)+		; POP STACK
	RETURN		; RETURN TO CALLER (DO NO PLOTS)
;
;	CALL	CURSOR(IX,IY,ICHAR)
;
CURSOR::MOV	#^RSOR,-(SP)		; SET UP NAME
	MOV	#^RCUR,R4		; FIRST 3 CHAR NEXT
	JSR	R4,NAM$			; FOR TRACEBACK
	CALL	MULTI		; MULTIPLE INPUT SETUP
	QIOW$S	#IO.RPR!TF.TMO!TF.RNE!TF.BIN!TF.RAL,#5,#1,,#ISTAT,,<#BUFF,#6,#12,#CURBUF,#3>
	CMP	ISTAT+2,#6	; Check char count
	BNE	40$		; Incorrect ?
	MOV	#BUFF,R4	; Get buffer address
	MOVB	(R4)+,R0
	BICB	#200,R0		; STRIP OFF EXTRA BITS
	MOVB	R0,@(R5)	; TYPED CHAR TO USER
	CALL	XYCODE		; DECODE THE X COORDINATE
	MOV	R0,(R2)
	CALL	XYCODE		; DECODE THE Y COORDINATE
	MOV	R0,(R3)
	MOVB	(R4),R0
	BIC	#177600,R0	; GET CODE
	CMP	R0,#15		; IS IT 'CR'
	BEQ	50$
40$:	MOVB	#-1,@(R5)	; Bad data ??
50$:	BR	ADMSET
;
;
;
XYCODE:	MOVB	(R4)+,R0
	BIC	#177740,R0
	MOVB	(R4)+,R1
	BIC	#177740,R1
	ASH	#5,R0
	ADD	R1,R0
	RETURN

;
;	SUBROUTINE TO CONVERT X,Y VALUES (  (R2),(R3)  ) AND PUT RESULT
;	INTO BUFFER (R4)
;	R0,R1 ARE DESTROYED
;
CONVXY:
10$:	MOV	(R3)+,R1	; GET Y VALUE
	BGE	11$
	NEG	R1		; TAKE ABSOLUTE VALUE OF R1
	CALL	STCLR
	MOVB	#35,PLTYPE	; SET TO PLOT TYPE
	TST	(R2)		; IF POSITIVE LEAVE WELL ENOUGH ALONE
	BGE	12$		; OK
	MOVB	#34,PLTYPE	; SET TO POINT PLOT TYPE
12$:	MOVB	PLTYPE,(R4)+	; SET MODE
11$:	CMP	R1,#779.	; VERTICAL TOO BIG?
	BLOS	1$		; NO
	MOV	#779.,R1	; YES, SET TO MAX
1$:	CLR	R0		; SET UP DOUBLE WORD INTEGER
	DIV	#32.,R0		; SPLIT TO 2 DIGITS
	ADD	#40,R0		; ADD ON BLANK
	CMPB	R0,YHI		; IS IT ALREADY SET
	BEQ	2$		; YES, SKIP OUTPUT
	MOVB	R0,(R4)+	; SET UP Y HIBITS
	CLRB	YLO		; MAKE SURE TO DO YLO
2$:	ADD	#140,R1		; NOW IS LOW Y DIGIT
	CMPB	R1,YLO		; DO WE SKIP Y LO
	BEQ	3$		; YES
	MOVB	R1,(R4)+	; PUT YLO INTO BUFFER
3$:	MOVB	R0,YHI		; SAVE YHI
	MOVB	R1,YLO		; SAVE YLO
	MOV	(R2)+,R1	; GET X
	BGE	4$		; NON NEGATIVE LEAVE IT SAME
	NEG	R1		; TAKE ABSOLUTE VALUE
4$:	CMP	R1,#1023.	; IS IT TOO BIG?
	BLOS	5$		; NO
	MOV	#1023.,R1	; YES, SUBSTITUTE MAX VALUE
5$:	CLR	R0		; SET UP DOUBLE WORD INTEGER
	DIV	#32.,R0		; SPLIT 2 DIGITS
	ADD	#40,R0		; ADD ON BLANK
	CMPB	R0,XHI		; HAS IT CHANGED
	BEQ	7$		; NO
	CMPB	-1(R4),YLO	; WAS YLO PUT IN BUFF?
	BEQ	6$		; YES
	MOVB	YLO,(R4)+	; NO, INCLUDE IT NOW
6$:	MOVB	R0,(R4)+	; PUT XHI INTO BUFFER
7$:	ADD	#100,R1		; NOW IS LOW X
	MOVB	R1,(R4)+	; PUT XLO INTO BUFFER (MANDATORY)
	MOVB	R0,XHI		; SAVE XHI
	MOVB	R1,XLO		; SAVE XLO
	DEC	CNT		; ARE WE DONE?
	BLE	15$		; YES
	CMP	R4,#BUFF+70.	; TEST IF BUFFER IS FULL YET
	BLO	10$		; BUFFER IS NOT FULL , CONTINUE
15$:	MOVB	#37,(R4)+	; END OF VECTORS OR POINTS
	RETURN

;
;	CALL	PLSTAT(IX,IY)
;		RETURNS STATUS IX,IY POSITION
;
PLSTAT::TST	(R5)+
	MOV	#XHI,R4
	MOV	#2,R3
1$:	CALL	XYCODE
	MOV	R0,@(R5)+
	SOB	R3,1$
	RETURN
;
;	CALL	SCTEST(ISTAT)
;		ISTAT	= 0		IF NON GRAPHICS TERMINAL
;		ISTAT	= NON ZERO	IF GRAPHICS TERMINAL
;
SCTEST:: MOV	#1,R0		;TEST INPUT PARAM LIST
	TST	(R5)+
	CLR	@(R5)		; Initial status = NO
	CALL	SCOPE		; Get status
	BCS	1$		; Not graphics
	DEC	@(R5)		; Set graphics status
1$:	RTS	PC		; Return
	.END
