STTL ; These routines drive the GIGI, VT125, and any other device that ; handles the Remote Graphics Instruction Set. Only the P and V ; commands are used by subroutine PLOT. ; ReGIS commands used by these routines: ;Initialization commands: ; S(I0,N0,A) = Screen: Intensity 0, Negative video off, Addressing normal ; W(V,A0,S0,M1,N0,P1(M2)) = Writing: oVerlay, no Alternating, Shading off, ; direction Multiplier 1, Negate off, Pattern 1 (pattern Multiplier 2) ; T(I0,A0,D0,S1) = Text: Italics off, Alphabet 0, Direction 0, Size 1 ;Normal commands: ; S(E) Screen: Erase ; W(I(C)) Write with cyan (light Blue for pen 1) ; W(I(W)) Write with white (negative Black for pen 2) ; W(I(M)) Write with magenta (purple Red for pen 3) ; P[x,y] Position the graphics cursor (move with pen up) ; Pddd Position one pixel in the specified direction for each digit ; V[x,y] Draw a vector from current position to new position ; Vddd Draw one pixel moving in the specified direction ; V[] Put a dot at current position (needed because the V[x,y] does ; not draw current pixel, in case of W(C) complement mode.) ; SUBTTL Revision History for PLTRGS.MAC ;Edit Date Who Description ;---- --------- --- -------------------------------------------------------- ; 501 26-Jul-82 JMS Add ReGIS output for VT125 and GIGI terminals. ; ; 511 27-Oct-82 JMS Do orthoganal or diagonal moves up to 8 pixels by ; sending only digits to the GIGI. ; (PLTRGS) ; ;End of Revision History for PLTRGS SUBTTL PPDATA macro expansion DEFINE INVALID(Z),< HRROS Z> ;;Force output of [123,456] instead of [,] RGSBYT==INSVL.(^D07,IN.BYT)!INSVL.(.IOASC,IN.MOD) ;Normal ASCII output RGSFLG==SP.PEN!SP.CLR!SP.XHR!SP.TTL ;NEWPEN, ERASE, XHAIRS, TITLE RGSINY== ;Increments per inch ;VT125 has 480/5.7 = 84 per inch (11 inch diag screen) max = [767,487] ;11x11 plot on GIGI with excluding top line use 460/11 = 42. ;LA34 and LA100 have 132 horiz, 72 (144) vert max = [1533,503] ;LA50 has 132 horiz, 66 (132) vert ;DMP4R tabletop plotter has 100 per inch max = [920,701] RGSMAX==^D768-1,,^D480-1;Max X and Y increments RGSTYP==P4.TTY!4 ;This is a graphics terminal, IPLT=4 for WHERE RGSEXT=='PIC' ;Output extension DEFINE LCDATA,< XBLOCK (RGSXHR,1) ;Last position of crosshairs, X,,Y > ;End of DEFINE LCDATA PPDATA (RGS) ;Expand data area SUBTTL Database ;Special character strings GON$: BYTE (7) ESC,"P","p",0 ;Enables ReGIS processor (graphics on) GOFF$: BYTE (7) ESC,"\",0 ;Graphics off (text cursor at random position) HGON$E: BYTE (7) ESC,"\",ESC,"[","H",CR,ESC,"P","p",";" ASCIZ /W(I6) S(E)/ ;Home, GON$, write with Cyan, erase GIGI screen DMPON: BYTE (7) ESC,"[","?","9","i",ESC,"P","3","p",";",0 ;Enable DMP-4R DMPOFF: BYTE (7) ESC,"[","?","8","i",0 ;Disable DMP-4R RGSLN1: BYTE (7) ESC,"\",ESC,"[","H",CR,0 ;Text cursor to line 1 col 1 ;RGSL23:BYTE (7) ESC,"\",ESC,"[","2","3",";","1","H",CR,0 ;Text cursor bottom ;List of names for ReGIS terminals RG.GIG==1B0 ;Use GIGI color map RG.125==1B1 ;Use VT125 color map RG.DMP==1B2 ;Use DMP4R/7R color map DEFINE PLNAM$,< XX ( 4,REGIS,0) ;Generic ReGIS - IPLT = 4 for subroutine WHERE XX ( 4,GIGI, RG.GIG) ;Alias for VK100 XX ( 4,VK100,RG.GIG) ;Alias for GIGI XX (125,VT125,RG.125) ;VT100 family XX ( 4,DMP4R,RG.DMP) ;Houston Instruments (8.5 by 11) XX ( 4,DMP74,RG.DMP) ;Houston Instruments (11 by 16) > ;End of DEFINE PLNAM$ DEFINE XX(NUM,NAM,FLAG),< DEC NUM ASCII /NAM/ EXP FLAG> RGSNAM: PLNAM$ ;Table of plotter types RGSLEN==<.-RGSNAM>/3 SUBTTL INItialize, FINish ;Routine to initialize the GIGI graphics terminal RGSINI: TXNN P4,P4.TTY ;Output going to a TTY? PJRST RGSCL1 ;No, do not send GON$+"S(E)" PFALL RGSCLR ;Yes, clear the screen ;Routine to clear the screen RGSCLR: MOVEI T1,HGON$E ;Put text cursor at home, GON$+"S(E)" MOVX T2,RG.DMP ;Is it a table-top plotter? TDNE T2,PLTTYP(P4) JRST [MOVX T1,<100.0> ;Yes, use 100 coordinates per inch MOVEM T1,PLTINX(P4) MOVEM T1,PLTINY(P4) MOVEI T1,DMPON ;ESCape seq to enable DMP-4R JRST .+1] PUSHJ P,OUTDMP ;Turn on ReGIS and clear the screen MOVEI T1,^D250 ;1/4 second TXNE P4,P4.TTY ;If going to TTY (instead of a disk file) PUSHJ P,TOWAIT ;Wait that amount after output is finished RGSCL1: SETZB X,Y ;Clear coordinates MOVE T1,[^D384,,^D240];Set old cross-hair position MOVEM T1,RGSXHR(P4) ; to middle of screen MOVEI T1,[ASCIZ /;S(I0,N0,A[0,0][767,479]) T(I0,A0,D0,S1) W(V,A0,S0,M1,N0,P1(M2)) P[0,480] /] ;Position to lower left PJRST OUTSTG ;Finish plot by resetting to text mode at upper left corner RGSFIN: MOVEI T1,[ASCIZ /;W(I(W))/] ;Set writing color to white PUSHJ P,OUTSTG ;(so that text looks better on GIGI) TXNN P4,P4.TTY ;Going to terminal? POPJ P, ;No, do not put ESCapes in disk file MOVEI T1,RGSLN1 ;Turn off ReGIS, position to line 1 PUSHJ P,OUTSTG MOVEI T1,DMPOFF ;Command to disable DMP-4R MOVX T2,RG.DMP ;Table-top plotter? TDNE T2,PLTTYP(P4) PUSHJ P,OUTSTG ;Yes, turn it off PJRST TTYDMP ;Dump buffers and return SUBTTL RGSPAS - Pause, plot-on, or plot-off ;Routine to cause plotter to pause and wait for a linefeed ;T1=-1 to pause, T1=0 to turn graphics off, T1=+1 to resume graphics RGSPAS: TXNN P4,P4.TTY ;Output going to a TTY POPJ P, ;No, cannot pause JUMPE T1,RGSOFF ;Turn off graphics if 0 JUMPG T1,RGSON ;Resume graphics if +1 MOVEI T1,[BYTE (7) ESC,"[","H",7,0] ;Text mode, bell PUSHJ P,OUTDMP ;Output it PUSHJ P,INCHR ;Input a character CAIN T1,CR ;Carriage return? PUSHJ P,INCHR ;Yes, must get LF since ReGIS uses ASCII mode PFALL RGSON ;Turn on graphics and go to old position ;Routine to resume plotting RGSON: MOVEI T1,GON$ ;Point to Graphics-ON-string PUSHJ P,OUTSTG ;Send it PFALL RGSPOS ;Go back to previous position ;Routine to put graphics cursor back at last known position ;Preserves X and Y accumulators RGSPOS: PUSH P,X ;Preserve ACs X and Y across call PUSH P,Y DMOVE X,CURR.X(P4) ;Get old position INVALID CURR.X(P4) ;Force output of full coordinates INVALID CURR.Y(P4) MOVEI T1,0 ;With pen up PUSHJ P,RGSMOV ;Go to that position POP P,Y POP P,X POPJ P, RGSOFF: MOVEI T1,GOFF$ ;Set text mode (text cursor in random position) PJRST OUTDMP ;Tell terminal to turn off graphics SUBTTL RGSMOV - Move to beam to new position ;Routine to move graphics cursor ; Calling sequence: ; DMOVE X,(position in increments) ; SETO T1, ;-1 for pen down, 0 for pen up ; PUSHJ P,RGSMOV ; *return* RGSMOV: MOVE T2,CURR.P(P4) ;Get current pen status JUMPE T1,[MOVEI T1,"P" ;T1=0 means to position PUSHJ P,OUTBYT ; with pen up TXZ T2,PN.DWN!PN.FL1 JRST RGSMV1 ] ;Clear the pen down flags MOVEI T1,[ASCIZ /V[]/];"V" to draw a vector TXON T2,PN.FL1 ;Was previous command a "V"? PUSHJ P,OUTSTG ;No, must start a new one TXO T2,PN.DWN ;Pen is now down RGSMV1: MOVEM T2,CURR.P(P4) ;Store flags DMOVE T1,X ;Get new coordinates SUB T1,CURR.X(P4) ;Find delta distance SUB T2,CURR.Y(P4) ; ... MOVM T3,T1 ;Absolute value MOVM T4,T2 CAIG T3,^D8 ;More than 8 pixels away? CAILE T4,^D8 JRST RGSMV2 ;Yes, fewer characters in "[,]" form MOVX T0,RG.GIG!RG.125 TDNN T0,PLTTYP(P4) ;Output to GIGI or VT125? JRST RGSMV2 ;No, DMP4R does not like abbreviation JUMPE T1,RGSMVV ;Check for vertical JUMPE T2,RGSMVH ; or horizontal movement CAME T3,T4 ;+45 or -45 degrees? JRST RGSMV2 ;No, do it the long way ;Here for a diagonal move of 1 to 8 pixels SKIPG T1 ;Plus X direction? SKIPA T4,["5",,"3"] ;No, get the 2 -X movers MOVE T4,["7",,"1"] ;Yes, get the 2 +X movers SKIPG T2 ;Plus Y direction? MOVSS T4 ;No, get "5" or "7" RGSMVD: HRRZ T1,T4 ;Get the move command PUSHJ P,RGSOUT ;Move 1 pixel SOJG T3,RGSMVD ;Do up to 8 of them DMOVEM X,CURR.X(P4) ;Store new position POPJ P, ;Here for a horizontal move of 1 to 8 pixels RGSMVH: MOVEI T4,"0" ;+X SKIPG T1 ;True? MOVEI T4,"4" ;-X JRST RGSMVD ;Here for a vertical move of 1 to 8 pixels RGSMVV: JUMPE T2,CPOPJ ;Output nothing if no movement MOVE T3,T4 ;Get vertical count MOVEI T4,"2" ;+Y SKIPG T2 ;True? MOVEI T4,"6" ;-Y JRST RGSMVD ;Here to move to a specific coordinate RGSMV2: MOVEI T1,"[" ;Start of coordinate PUSHJ P,OUTBYT MOVE T1,X ;Get X position MOVX T0,RG.GIG!RG.125 TDNE T0,PLTTYP(P4) ;Output digits if not GIGI or VT125 CAME X,CURR.X(P4) ;Output nothing if at right position PUSHJ P,OUTDEC ;Output decimal digits MOVEI T1,"," ;Separator PUSHJ P,OUTBYT MOVEI T1,^D480 ;GIGI uses [0,0] as upper left SUB T1,Y ;Top=+0, bottom = +480 MOVX T0,RG.GIG!RG.125 TDNE T0,PLTTYP(P4) ;Output digits if not GIGI or VT125 CAME Y,CURR.Y(P4) ;Output nothing if at right position PUSHJ P,OUTDEC ;Output translated Y position DMOVEM X,CURR.X(P4) ;Store new position MOVEI T1,"]" ;End of coordinate PFALL RGSOUT ;Output it and possible CRLF ;Need to output CRLF after 72 so GED (Graphics Editor) can read disk file RGSOUT: PUSHJ P,OUTBYT ;Output the last byte of this command MOVE T1,BYTE.C(P4) ;Get the count of bytes since last CRLF CAIG T1,^D70 ;Getting close to the end of a line? POPJ P, ;Not time for CRLF yet RGSCRL: MOVEI T1,CRLF ;Start a new line PUSHJ P,OUTSTG SETZM BYTE.C(P4) ;Reset byte count POPJ P, SUBTTL NEWPEN - Change pen colors RGSSPC: TXNE T1,SP.CLR ;Is this a call to ERASE? JRST RGSCLR ;Yes TXNE T1,SP.XHR ;Call to XHAIRS? JRST RXHAIR ;Yes TXNE T1,SP.TTL ;Call to TITLE? JRST RGSTTL ;Yes TXNN T1,SP.PEN ;Call to NEWPEN? POPJ P, ;No ; Change pen color RGSPEN: MOVEI T1,[ASCIZ /W(I/];Set writing intensity PUSHJ P,OUTSTG MOVE T1,C.NPEN ;Get caller's argument CAIL T1,1 ;Within range of 1-8? CAILE T1,^D8 SETOM SAVE0 ;No, return error MOVM T0,T1 ;Watch out for negative numbers IDIVI T0,^D8 ;Force T1 to be within 0 to 7 DPB T1,[POINTR CURR.P(P4),PN.COL] ;Save in case anyone cares MOVEI T2,COLGIG ;Assume going to a GIGI MOVE T3,PLTTYP(P4) ;Get plotter type flags TXNE T3,RG.125 ;VT125? MOVEI T2,COL125 ;Yes TXNE T3,RG.DMP ;DMP-4R or -7R? MOVEI T2,COLDMP ;Yes ADD T1,T2 ;Point to ASCIZ string PUSHJ P,OUTSTG ;Tell ReGIS MOVX T1,PN.FL1 ;Get flag-1 ANDCAM T1,CURR.P(P4) ;Not in a V command MOVEI T1,")" ;End of W command PUSHJ P,OUTBYT ;Send 2 close parens PJRST RGSOUT ;(the last one may need a CRLF after it) ;The color maps for pen plotters are 1=Blue, 2=Red, 3=Black, 0=no color COLGIG: ASCII /(D)/ ;8 Dark (black on black) Color 0 ASCII /(C)/ ;1 Cyan (light Blue) Color 5 ASCII /(W)/ ;2 White (negative Black) Color 7 ASCII /(M)/ ;3 Magenta (purple-Red) Color 3 ASCII /(Y)/ ;4 Yellow Color 6 ASCII /(G)/ ;5 Green Color 4 ASCII /(R)/ ;6 Red (dimmer than Magenta) Color 2 ASCII /(B)/ ;7 Blue (very dim) Color 1 COL125: ASCII /0/ ;8 Dark ASCII /1/ ;1 Blue ASCII /2/ ;2 Red ASCII /3/ ;3 Green ASCII /(C)/ ;4 Cyan (if defined) ASCII /(Y)/ ;5 Yellow (if defined) ASCII /(M)/ ;6 Magenta (if defined) ASCII /(W)/ ;7 White (if defined) COLDMP: ASCII /(D)/ ;8 Dark (keep pen up) ASCII /(B)/ ;1 Blue Pen #3 (Houston Instruments ASCII /(R)/ ;2 Red Pen #1 messed up these 3 ASCII /(G)/ ;3 Green Pen #2 color definitions.) ASCII /4/ ;4 Cyan ASCII /5/ ;5 Yellow ASCII /6/ ;6 Magenta ASCII /1/ ;7 Red (there are only 6 pens) SUBTTL TITLE - Plot text ;CALL TITLE(X,Y,HEIGHT,ICHAR,ANGLE,NUMCHR) ; 0 1 2 3 4 5 RGSTTL: MOVE X,@0(L) ;Get coordinates MOVE Y,@1(L) FADR Y,@2(L) ;Go to top of first letter (ONLY IF ANGLE=0) PUSHJ P,MOVUP ;Go there (BYPASSING WINDOW CHECKS) MOVEI T1,[ASCIZ /T(D/] ;Set ReGIS to text mode (must set direction PUSHJ P,OUTSTG ; before size, else the letters are tilted) IFE FTKA, ;Get the angle in degrees IFN FTKA, ;Integerize it PUSHJ P,OUTDEC ;Output it MOVEI T1,"S" ;Now for the size PUSHJ P,OUTBYT MOVE Y,@2(L) ;Get the height MOVEI X,0 ;Avoid unnecessary overflows PUSHJ P,FP2INC ;Convert to increments MOVEI T1,5(Y) ;Add 5 for rounding IDIVI T1,^D10 ;Get the height number PUSHJ P,OUTDEC ;Output as the size number (I know it's wrong) PUSHJ P,RGSCRL ;Send a CRLF MOVEI T2,@3(L) ;Get addr of string HRLI T2,(POINT 7,) ;Make into byte pointer MOVE T3,@5(L) ;Get byte count RGSTT1: ILDB T1,T2 CAIN T1,"'" ;Embedded apostrophe? PUSHJ P,OUTBYT ;Yes, send 2 in a row PUSHJ P,OUTBYT ;Send the character SOJG T3,RGSTT1 ;Loop for all MOVEI T1,"'" ;Finish off the string PUSHJ P,RGSOUT ;Send it (and possible CRLF) PJRST RGSPOS ;Reset graphics cursor position SUBTTL XHAIRS - allow the user the use the crosshairs RXHAIR: SETZM @0(L) ;Clear X SETZM @1(L) ;Clear Y SETOM @2(L) ;Set LETTER to -1 in case of error TXNN P4,P4.TTY ;Output going to a TTY? JRST [ERRSTR (MSG,<% XHAIRS works with GIGI terminals only>) PJRST TRACE] ;Trace back from PUSHJ P,%XHAIRS PUSH P,CURR.X(P4) ;Preserve current pen position PUSH P,CURR.Y(P4) PUSHJ P,RGSPOS ;Make sure graphics cursor is really there MOVEI T1,RXH.X ;Point to string PUSHJ P,OUTSTG ;Make an hourglass at current pen position HLRZ X,RGSXHR(P4) ;Act like the Tektronix and trigger HRRZ Y,RGSXHR(P4) ; the crosshairs at their old position MOVEI T1,0 ;Pen up PUSHJ P,RGSMOV ;Go there POP P,CURR.Y(P4) ;Restore last known position POP P,CURR.X(P4) ND KLUDGE,-1 IFE KLUDGE,< MOVEI T1,[ASCIZ /R(P(I))/] ;Report Position Interactive MOVEI T2,TEMP ;Where to store the string MOVEI T3,^D10 ;Read up to 10 chars MOVEI T4,"]" ;Stop at end of coordinates PUSHJ P,RDTBIN ;Prompt and read TTY in binary mode > ;End of IFE KLUDGE kludge==-1 ifn kludge,< if2, PUSHJ P,OUTDMP ;Put in buffer PUSHJ P,TTASCM ;Close channel (but keep it INITed) PUSHJ P,CLRIB ;Clear input buffer ;Nulls and Control-C can be read in Packed Image Mode MOVE T1,BUFR.N(P4) ;Get channel number HRRI T1,.FORED ;Set for input MOVEM T1,FLP+.FOFNC MOVEI T1,^D8 ;8-bit bytes MOVEI T2,.IOPIM ;Packed image mode PUSHJ P,REOPEN ;PIM works for INCHR even with no input buffer MOVE T1,[POINT 7,@3(L)] ;Put the characters in 4th arg HLRZ T2,-1(L) ;Get the number of args CAIL T2,-3 ;Is it more than 3? MOVE T1,[POINT 7,TEMP] ;No, put chars in TEMP MOVEM T1,HEADBP ;Store byte pointer MOVE T2,BLANKS ;5 spaces MOVEM T2,0(T1) ;Clear the string MOVEM T2,1(T1) SETZB X,Y ;Clear position ;Read in 10 bytes from the terminal. Single Control-C will not stop execution. PUSHJ P,INCHR ;Get the first character from the TTY MOVEM T1,@2(L) ;Store LETTER CAIN T1,3 ;Control-C as first character? JRST RXHARC ;Yes, abort PUSHJ P,INCHR ;Get "[" CAIN T1,3 ;Control-C as second character? JRST RXHARC ;Yes, abort RXHARX: PUSHJ P,INCHR ;Get a digit of X CAIN T1,"," ;End of number? JRST RXHARY ;Yes IMULI X,^D10 ;Shift accumulated number ADDI X,-"0"(T1) ;Add in new digit JRST RXHARX ;Loop RXHARY: PUSHJ P,INCHR ;Get a digit of Y CAIN T1,"]" ;End of number? JRST RXHAR1 ;Yes IMULI Y,^D10 ;Shift ADDI Y,-"0"(T1) ;Add JRST RXHARY RXHAR1: PUSHJ P,INCHR ;Get CR > ;end of ifn kludge RXHAR2: MOVE T1,@2(L) ;Get first character CAIN T1,3 ;Control-C? JRST RXHARC ;Yes MOVNS Y ;Translate Y coord ADDI Y,^D480 ; to normal RXHARD: HRLM X,RGSXHR(P4) ;Remember position HRRM Y,RGSXHR(P4) ; of crosshairs PUSHJ P,OPNFIL ;Set up output again PUSHJ P,RGSPOS ;Return cursor to previous pen position PUSHJ P,RXHAR3 ;Return data to caller JUMPE T1,RGSCLR ;Formfeed, erase the screen MOVEI T1,RXH.X ;Point to string PJRST OUTSTG ;Undo the hourglass RXHARC: MOVEI T1,[BYTE(7)ESC,"\","^","C",7,0] ;GOFF$+"^C"+beep PUSHJ P,OUTDMP ;Show that Control-C was noticed ERRSTR (NON,<^C>) ;Show on controlling terminal also MONRT. ;Quiet exit to monitor level MOVEI T1,GON$ ;Send graphics-on-string PUSHJ P,OUTSTG ; to resume plotting JRST RXHARD ;Allow ".CONTINUE" (X and Y are 0) RXH.X: ASCIZ /V(W(C,I))[+10,-10][-20][+20,+20][-20][+10,-10]/ ;Vector, Write(Complement,no Intensity), draw an "X" with crossbars LITRGS: LIT PAGE ;End of PLTRGS.MAC