.TITLE PLOT55 - VT55 PLOTTING ROUTINE ; ; ; DECEMBER 6,1975 GEORGE S. KACZOWKA ; HIAS, INC. ; ; THIS ROUTINE IS A FORTRAN CALLABLE SUBROUTINE PROVIDING ; FULL SUPPORT FOR THE VT55 GRAPHICS TERMINAL. ; ; IMPORTANT NOTE: THIS VERSION OF PLOT55 IS ; FOR USE WITH THE RSX-11M, RSX-11D, AND IAS ; OPERATING SYSTEMS ONLY. A SEPARATE SOURCE ; FILE, PLOT55.MAC, IS INCLUDED FOR RT-11 USERS. ; ; ; CALL FORMAT: ; ; CALL PLOT55(,,,) ; ; WHERE: ; ; - COMMAND CODE ; ; - "X" VALUE ; ; - "Y" VALUE ; ; - TERMINAL PARAMETER TABLE ; ; ; ; .MCALL QIO$S,WTSE$S,ALUN$S ; .MACRO CALL A JSR PC,'A .ENDM CALL ; .MACRO RETURN RTS PC .ENDM RETURN ; .SBTTL PLOT55 - ENTRY POINT ; ; .GLOBL PLOT55 ; ; PLOT55: MOV #SCRTCH,R4 ;START WITH DUMMY AREA CMPB @R5,#4 ;ALL CALLS MUST HAVE FOUR ARGS BEQ 1$ ;USE EXTERNAL TABLE CMPB @R5,#3 ;3 ARGS? BNE ERR1 ;SET ERROR CODE -1 (INV ARGS) 3$: MOV #SCRTCH,R4 ;POINT TO INTERNAL AREA BR 2$ ;CONTINUE 1$: MOV 10(R5),R4 ;SET UP SCRATCH AREA POINTER CMP R4,#-1 ;DUMMY ARG? BEQ 3$ ;YES - GO BACK AND FAKE IT 2$: MOV 2(R5),R0 ;GET COMMAND POINTER CMP R0,#-1 ;VALID? BEQ ERR1 ;**INV AGRS** MOV @R0,R0 ;GET ACTUAL COMMAND VALUE BMI ERR1 ;**INV ARGS** CMP R0,#MAXCMD ;SEE IF WITHIN LIMITS BHIS ERR1 ;**INV ARGS** ASL R0 ;*2 FOR WORD OFFSET JMP @DISPAT(R0) ;VECTOR TO PROCESSING CODE ; ; DISPAT: .WORD ATTDET ;ATTACH/DETACH TO DEVICE .WORD GRAPH ;SELECT GRAPH .WORD CONTRL ;GRAPHICS CONTROL .WORD PLOTPT ;PLOT POINT .WORD HORIZ ;PLOT HORIZONTAL LINE .WORD VERT ;PLOT VERTICAL LINE .WORD MARKER ;PLOT GRAPHIC MARKER .WORD DEFORG ;DEFINE ORIGINE (X,Y) .WORD VECTOR ;PLOT VECTOR .WORD CURSOR ;SET CURSOR POSITION .WORD ERASES ;ERASE SCREEN .WORD ERASEL ;ERASE LINE .WORD DUMP ;DUMP CHARACTERS .WORD COMAND ;SEND VT55 COMMAND IN "X" ; MAXCMD=<.-DISPAT>/2 ; .SBTTL UTILITY CODE ; ; ;--- GETX - ROUTINE TO EXTRACT X VALUE ; GETX: MOV 4(R5),R1 ;GET X VALUE POINTER CMP R1,#-1 ;NOT SPECIFIED? BEQ 1$ ;ASSUME 0 MOV @R1,R1 ;GET IT BIC #176000,R1 ;KILL EXTRA BITS 2$: RETURN ;RETURN TO CALLER ; 1$: CLR R1 ;RESET IT RETURN ;RETURN ; ; ;--- GETY - ROUTINE TO EXTRACT Y VALUE ; GETY: MOV 6(R5),R2 ;GET Y POINTER CMP R2,#-1 ;OMITTED? BEQ 1$ ;YES - SKIP IT MOV @R2,R2 ;GET VALUE BIC #177000,R2 ;KILL EXTRA BITS 2$: RETURN ;RETURN TO CALLER ; 1$: CLR R2 ;SET Y TO 0 RETURN ;RETURN ; ; ;--- SNDCHR - ROUTINE TO SEND OUT A CHARACTER IN R0 ; SNDCHR: MOV R0,-(SP) ;SAVE IT CMP CHRCNT(R4),#BUFSIZ ;BUFFER FULL? BLO 1$ ;NO - CONTINUE CALL OUTPUT ;OUTPUT IT SO FAR 1$: MOV CHRCNT(R4),R0 ;GET CURRENT CHARACTER COUNT ADD R4,R0 ;OFFSET TO BUFFER ADD #BUFF,R0 ;POINT INTO THE BUFFER MOVB (SP),(R0) ;SET INTO THE BUFFER INC CHRCNT(R4) ;UPDATE CHARACTER COUNT MOV (SP)+,R0 ;RESTORE CHARACTER RETURN ;RETURN TO CALLER ; ; ;--- OUTPUT - ROUTINE TO OUTPUT CHARACTERS STORED ; OUTPUT: TST CHRCNT(R4) ;ANY CHARACTERS TO BE OUTPUT? BEQ 1$ ;NO - SKIP IT MOV R4,R3 ;CONSTRUCT POINTER IN R3 ADD #BUFF,R3 ;POINT TO IT TST LUN(R4) ;RETURN IF ZERO OR NEG BLE 2$ TST EFN(R4) ;RETURN IF ZERO OR NEG BLE 2$ QIO$S #IO.WLB,LUN(R4),EFN(R4),,,, BCS 2$ WTSE$S EFN(R4) ;WAIT FOR I/O COMPLETE 2$: CLR CHRCNT(R4) ;RESET CHARACTER COUNT 1$: RETURN ;RETURN ; ; ;--- EXIT - RETURN ENTRY POINT ; EXIT: CALL DSABL ;DISABLE IF NEED BE CALL OUTPUT ;OUTPUT IF NEED BE CLR R0 ;SET FOR STANDARD RETURN RETURN ;RETURN TO CALLER ; ERR1: CALL DSABL ;DISABLE IF NEED BE CALL OUTPUT ;AND OUTPUT IF NEED BE MOV #-1,R0 ;SET ERROR CODE RETURN ;RETURN ; ; ; ;--- ADDR - ROUTINE TO MAKE 2 ADDR BYTES ; ADDR: MOV R0,-(SP) ;SAVE WORD BIC #37,R0 ;GET HIGH BYTE BIC R0,@SP ;AND LOW BYTE ASL R0 ;SHIFT INTO POSITION ASL R0 ASL R0 ;AND GET SET FOR SWAB SWAB R0 ;NOW IN LOW BYTE BIS #40,R0 ;SET BIT MOV R0,R2 ;SET AS SECOND BYTE MOV (SP)+,R1 ;RESTORE LOW BYTE BIS #40,R1 ;MAKE PRINTABLE RETURN ;EXIT ; ; ;--- SEND2 - ROUTINE TO SEND OUT R1 AND R2 ; SEND2: MOV R1,R0 ;SEND CHR1 CALL SNDCHR ;SEND IT MOV R2,R0 ;GET CHR2 CALL SNDCHR ;DO IT RETURN ;RETURN TO CALLER ; ; ;--- ENABL - ENABLE GRAPHICS ; ENABL: TSTB ENAB(R4) ;GRAPHICS ALREADY ENABLED? BNE 1$ ;YES CALL ESC ;SEND ESC MOV #'1,R0 ;AND ENTER GRAPHICS CALL SNDCHR ;SEND IT INCB ENAB(R4) ;FLAG IT 1$: CALL CR ;RETURN CARRIAGE RETURN ;EXIT ; ; ;--- DSABL - DISABLE GRAPHICS ; DSABL: TSTB ENAB(R4) ;GRAPHICS ENABLED? BEQ 1$ ;NO - EXIT CALL ESC ;SEND ESC MOV #'2,R0 ;SEND DISABLE CODE CALL SNDCHR ;SEND IT CALL CR ;RESET CARRIAGE CLRB ENAB(R4) ;RESET ENABLE FLAG 1$: RETURN ;EXIT ; ; ;--- ESC - SEND ESCAPE CHAR ; ESC: MOV #33,R0 ;SEND IT CALL SNDCHR ;TO THE TERMINAL RETURN ;EXIT ; ; ;--- CR - SEND CARRIAGE RETURN ; CR: MOV #15,R0 ;SET CHARACTER CALL SNDCHR ; SEND IT TO THE TERMINAL RETURN ;EXIT ; .SBTTL COMMAND FUNCTIONS ; ; ;--- ATTDET - ATTACH AND DETACH CODE ; ATTDET: CALL GETX ;GET X VALUE TST R1 ;ZERO OR ONE? BEQ 2$ ;IF ZERO, ATT TO DEFAULT BLT 1$ ;NEGATIVE MEANS DETACH MOV R1,LUN(R4) ;SET LUN=(R1) CALL GETY ;GET EFN VALUE TST R2 ;SEE IF USING DEFAULT BEQ 2$ ;YES - SKIP OUT MOV R2,EFN(R4) ;SET IT 2$: TST LUN(R4) ;NEG OR ZERO MEANS ERROR BLE 4$ ;ERROR ; QIO$S #IO.ATT,LUN(R4) ;ATTACH TO DEVICE BR 3$ ; 1$: QIO$S #IO.DET,LUN(R4) ;DETACH FROM LUN MOV R1,LUN(R4) ;SET LUN=R1 3$: CLR R0 ;SUCCESS RETURN 4$: MOV #-1,R0 ;ERROR CODE RETURN ; ; ;--- GRAPH - SELECT GRAPH CODE ; GRAPH: CALL GETX ;SEE WHICH ONE CLRB GRF(R4) ;SET FOR GRAPH 0 TST R1 ;WAS IT? BEQ 1$ ;YES - EXIT MOVB #10,GRF(R4) ;SET FOR GRAPH 1 1$: RETURN ;RETURN TO CALLER ; ; ;--- CONTRL - GRAPHICS CONTROL CODE ; CONTRL: CALL GETY ;GET Y CODES BIC R2,STATUS(R4) ;RESET CODES CALL GETX ;GET ENABLE CODES BIS R1,STATUS(R4) ;SET THOSE BITS CALL ENABL ;TURN ON GRAPHICS MOVB #'A,R0 ;SEND COMMAND LDE0 CALL SNDCHR MOV STATUS(R4),R0 ;GET FIRST WORD CALL ADDR ;ADDRESS CONVERT MOV R1,R0 ;GET FIRST CHAR CALL SNDCHR ;SEND IT MOV #'I,R0 ;COMMAND LDE1 CALL SNDCHR ;SEND IT MOV R2,R0 ;AND GET PARAMETERS CALL SNDCHR ;SEND IT TOO BIC #512.,STATUS(R4) JMP EXIT ;EXIT CODE ; ; ;--- PLOTPT - PLOT POINT CODE ; PLOTPT: MOV 4(R5),R1 ;GET X ADDRESS CMP R1,#-1 ;OMITTED? BEQ 6$ ;YES - THAT IS AN ERROR MOV @R1,R1 ;GET VALUE MOV R1,-(SP) ;SAVE IT FOR LATER BGE 2$ ;IF >=0 THEN STANDARD PLOT MOV ORGX(R4),R1 ;GET VALUE FROM DEFORG 2$: CMP R1,#MAX.X ;MAX VALUE? BLOS 1$ ;OK - FORGET IT MOV #MAX.X,R1 ;SET IT ; ; DEFINE ORIGIN ; 1$: CALL ENABL ;ENABLE GRAPHICS MOV #'H,R0 ;COMMAND LSC CALL SNDCHR ;SEND IT MOV R1,R0 ;GET ADDRESS CALL ADDR ;ADDRESS IT CALL SEND2 ;SEND THEM MOVB GRF(R4),R0 ;GET GRAPH CODE ADD #'B,R0 ;FORCE COMMAND FOR LDG0 OR LDG1 CALL SNDCHR ;SEND CHAR MOV (SP)+,R1 ;GET ORIGINAL VALUE BMI 3$ ;NEG - HANDLE IT CALL GETY ;GET Y VALUE MOV R2,R0 ;SET UP CALL ADDR ;CONSTRUCT ADDRESS CALL SEND2 ;SEND OUT BOTH CHARACTERS JMP EXIT ;EXIT ; 3$: NEG R1 ;MAKE POSITIVE VALUE MOV 6(R5),R2 ;GET Y POINTER CMP R2,#-1 ;OMITTED? BEQ 6$ ;YES - ERROR MOV #20,-(SP) ;SET COUNT FOR MOV R1,-(SP) ;SAVE IT 4$: MOV (R2)+,R0 ;GET VALUE MOV R2,-(SP) ;SAVE IT CMP R0,#MAX.Y ;WITHIN RANGE? BLOS 5$ ;YES - SKIP MOV #MAX.Y,R0 ;GET CORRECT VALUE 5$: CALL ADDR ;ADDRESS IT CALL SEND2 ;SEND IT MOV (SP)+,R2 ;RECOVER POINTER DEC 2(SP) ;COUNT OUT FOR CR BGT 10$ ;SKIP IF OK CALL CR ;SEND MOV #20,2(SP) ;RESET COUNT 10$: DEC @SP ;COUNT IT OUT BGT 4$ ;CONTINUE CMP (SP)+,(SP)+ ;POP OFF COUNTER+CR COUNT JMP EXIT ;EXIT ; 6$: JMP ERR1 ;ERROR CODE ; ; ; ;--- HORIZ - HORIZONTAL LINE ROUTINE ; HORIZ: CALL GETY ;GET VALUE CALL GETX ;AND ENABLE/DISABLE MOV R1,-(SP) ;SAVE ENABL/DSABLE SW CALL ENABL ;ENABLE GRAPHICS MOV #'D,R0 ;COMMAND LHL CALL SNDCHR ;SEND CHARACTER MOV R2,R0 ;GET ADDR CALL ADDR ;ADDRESS IT TST (SP)+ ;POP OFF SWITCH BEQ 1$ ;DISABLE IT BIS #20,R2 ;SET FOR ENABLE 1$: CALL SEND2 ;SEND THE CODE JMP EXIT ;EXIT WITH STYLE ; ; ;--- VERT - VERTICAL LINE ; VERT: CALL GETX ;GET POSITION CALL GETY ; AND ENABLE/DISABLE CALL ENABL ;ENABLE GRAPHICS MOV R2,-(SP) ;SAVE SWITCH MOV #'L,R0 ;COMMAND LVL CALL SNDCHR ;SEND IT MOV R1,R0 ;GET ADDRESS CALL ADDR ;ADDRESS IT TST (SP)+ ;SENSE SWITCH BEQ 1$ ;DISABLE IT BIS #20,R2 ;SET ENABLE SWITCH 1$: CALL SEND2 ;SEND IT JMP EXIT ; ; ; ; ;--- MARKER - ROUTINE TO SET UP HASH MARKER ; MARKER: CALL GETX ;GET POSITION CALL GETY ;AND ENABLE/DISABLE SWITCH CALL ENABL ;ENABLE GRAPHICS MOVB GRF(R4),R0 ;SET FOR GRAPH CONTROL ADD #'C,R0 ;MAKE LDC0 OR LDC1 CALL SNDCHR ;SEND IT MOV R2,-(SP) ;SAVE SWITCH MOV R1,R0 ;CONSTRUCT ADDR CALL ADDR ;MAKE INTO 2 BYTES TST (SP)+ ;SENSE THE SWITCH BEQ 1$ ;DISABLE BIS #20,R2 ;SET ENABLE FLAG 1$: CALL SEND2 ;SEND BOTH CHARACTERS JMP EXIT ;EXIT CODE ; ; ;--- DEFORG - DEFINE ORIGIN ; DEFORG: CALL GETX ;GET X VALUE MOV R1,ORGX(R4) ;SET IT CALL GETY ;GET Y VALUE MOV R2,ORGY(R4) ;SAVE IT JMP EXIT ;EXIT CODE ; ; ;--- VECTOR - ROUTINE TO PLOT VECTOR ; VECTOR: CALL GETX ;GET X VALUE (DEST) CALL GETY ;AND GET Y VALUE CALL ENABL ;ENABLE GRAPHICS CMP R1,ORGX(R4) ;SEE WHICH WE WILL START FROM BHIS 1$ ;FORGET IT MOV R1,R0 ;SAVE IT MOV ORGX(R4),R1 ;SWAP MOV R0,ORGX(R4) ;BOTH MOV R2,R0 ;SAVE MOV ORGY(R4),R2 ;GET IT MOV R0,ORGY(R4) ;SWAP 1$: SUB ORGX(R4),R1 ;GET DELTA X BEQ 9$ ;PLOT SINGLE POINT MOV R1,DX(R4) ;SAVE IT MOV #20,-(SP) ;GET COUNT FOR MOV #1,-(SP) ;SET SWITCH TO 1 SUB ORGY(R4),R2 ;GET DELTA Y BPL 2$ ;IF POSITIVE, THEN OK NEG R2 ;MAKE POSITIVE NEG @SP ;AND REVERSE POLARITY OF SW 2$: MOV #BIGINC,R3 ;GET BIG INCREMENT VALUE CLR R0 ;SET SLOPE TO 0 3$: CMP R1,R2 ;SEE IF BIGGER BHIS 4$ ;SLOW DIVIDE FINISHED SUB R1,R2 ;DECREMENT INC R0 ;UPDATE SLOPE BR 3$ ;CONTINUE ; 4$: ASR R3 ;SHIFT OFF BIGINC BEQ 5$ ;THROUGH ASL R2 ;*2 ASL R0 ;*2 BR 3$ ;CONTINUE DIVIDE ; 5$: MOV R0,SLOPE(R4) ;SET SLOPE CLR SUM(R4) ;RESET SUM VALUE MOV #'H,R0 ;SET UP LSC CALL SNDCHR ;SEND IT MOV ORGX(R4),R0 ;GET STARTING X VALUE CALL ADDR ;ADDRESS IT CALL SEND2 ;SEND IT MOV #'B,R0 ;SET FOR LDG0 OR LDG1 BISB GRF(R4),R0 ;SET UP GRAPH # CALL SNDCHR ;SEND IT 6$: ADD SLOPE(R4),SUM(R4);USE PSEUDO GRIDS 7$: CMP SUM(R4),#BIGINC ;TIME TO UPDATE Y? BLO 8$ ;NO ADD (SP),ORGY(R4) ;UPDATE Y SUB #BIGINC,SUM(R4) ;RESET SUM BR 7$ ;CONTINUE 8$: MOV ORGY(R4),R0 ;GET Y VALUE CALL ADDR ;ADDRESS IT CALL SEND2 ;SEND IT DEC 2(SP) ;COUNT OUT CR COUNT BGT 10$ ;KEEP GOING CALL CR ;SEND IT OUT MOV #20,2(SP) ;RESET COUNT 10$: DEC DX(R4) ;COUNT OUT DELTA X BPL 6$ ;GO AGAIN CALL GETX ;GET X VALUE MOV R1,ORGX(R4) ;SET AS NEW ORIGIN CALL GETY ;GET Y VALUE MOV R2,ORGY(R4) ;SAVE IT CMP (SP)+,(SP)+ ;POP OFF SWITCH&COUNT JMP EXIT ;EXIT ; 9$: JMP PLOTPT ;PLOT POINT ; ; ; ;--- CURSOR - ADDRESS ALPHA CURSOR ; CURSOR: CALL ESC ;START WITH ESC MOV #'H,R0 ;SET FOR HOME CALL SNDCHR ;SEND IT CALL GETY ;GET Y POSITION MOV #12,R0 ;SEND A LF 1$: DEC R2 ;SEE IF OUTPUT ONE BMI 2$ ;NO - EXIT CALL SNDCHR ;SEND IT BR 1$ ;CONTINUE 2$: CALL GETX ;GET HORIZ POS CALL CR ;RETURN CARRIAGE (FOR DRIVER) MOV #103,-(SP) ;SET FOR SPACES 3$: DEC R1 ;COUNT IT OUT BMI 4$ ;SKIP OUT CALL ESC ;SEND ESC CHAR MOV (SP),R0 ;GET COMMAND CHAR CALL SNDCHR ;SEND IT BR 3$ ;CONTINUE 4$: TST (SP)+ ;POP OFF COMMAD CHAR JMP EXIT ;EXIT ; ; ;--- ERASES - ERASE SCREEN ; ERASES: CALL ESC ;SEND ESC MOV #'J,R0 ;GET COMMAND CALL SNDCHR ;SEND IT JMP EXIT ;EXIT ; ; ;--- ERASEL - ERASE LINE ; ERASEL: CALL ESC ;SEND ESC MOV #'K,R0 ;SET COMMAND CALL SNDCHR ;SEND IT JMP EXIT ;EXIT ; ; ;--- DUMP - DUMP OUT CHARACTERS ; DUMP: CALL GETX ;GET NUMBER OF CHARACTERS MOV 6(R5),R2 ;POINT TO CHARACTERS CMP R2,#-1 ;OMITTED? BEQ 9$ ;YES - ERROR TST R1 ;HOW MANY? BEQ 2$ ;UNTIL A NULL... 1$: MOVB (R2)+,R0 ;GET IT CALL SNDCHR ;SEND IT DEC R1 ;COUNT IT OUT BGT 1$ ;CONTINUE 3$: JMP EXIT ;EXIT ; 2$: MOVB (R2)+,R0 ;GET CHAR BEQ 3$ ;EXIT CALL SNDCHR ;SEND IT BR 2$ ;CONTINUE ; 9$: JMP ERR1 ;REFLECT ERROR ; ; ;--- COMAND - SEND COMMAND ; COMAND: CALL ESC ;SEND AN ESCAPE CALL GETX ;GET CHARACTER TO SEND MOV R1,R0 ;SEND IT CALL SNDCHR ;TO THE TERMINAL JMP EXIT ;EXIT ; ; .SBTTL STORAGE DEFINITIONS ; ; MAX.X=512. MAX.Y=236. ; BIGINC=400 ; ; THE FOLLOWING OFFSETS DESCRIBE THE PARAMETER TABLE (ARG4) ; OF THE CALL. THIS TABLE IS ALWAYS POINTED TO BY R4 ; ; LUN= 000000 ;LOGICAL UNIT OF TERMINAL EFN= 000002 ;EVENT FLAG TO BE USED ORGX= 000004 ;X ORIGIN ORGY= 000006 ;Y ORIGIN SUM= 000010 ;WORK REG SLOPE= 000012 ;WORK REG STATUS= 000014 ;TERMINAL STATUS GRF= 000016 ;GRAPH NUMBER ENAB= 000017 ;ENABLED/DSABLED SWITCH DX= 000020 ;WORK REG CHRCNT= 000022 ;CHAR COUNT IN BUFFER BUFF= 000024 ;6 CHARACTER BUFFER ; BUFSIZ=6. ; ;--- SCRTCH - 16 WORD PARAMETER BLOCK ; SCRTCH: .WORD 0,0,0,0,0,0,0,0 ;USED IN CASE USER DOESN'T .WORD 0,0,0,0,0,0,0,0 ;SPECIFY ONE. ; .END