TITLE TOLP - Routine to read *.PLT files SUBTTL Joe Smith, CSM, 13-Mar-84 ; Subroutine TOLP is the reverse of subroutine PLOT. TOLP reads a .PLT ;file from the disk, and translates it to calls to PLOT, NEWPEN, OPRTXT, ;TITLE, and PAUSEP. Subroutine TOLP is used by both the FORTRAN program ;TEK and the GLXLIB program SPROUT for interpreting compressed plot files. ;Written 2-Mar-83 for the Colorado School of Mines. ;Revised 28-Jun-83. Changed to index all variables using J, 13-Mar-84. ; Table of Contents for TOLP - Reverse PLOT ; ; ; Section Page ; ; 1. Calling sequence ; 1.1 MACRO programs (such as SPROUT) . . . . . . . 2 ; 2. Definitions . . . . . . . . . . . . . . . . . . . . . 3 ; 3. Entry to TOLP(READER,ICHAR,ITEXT) . . . . . . . . . . 4 ; 4. Verify that the plot file starts correctly . . . . . . 5 ; 5. Exit from TOLP ; 5.1 ERROR and DONE routines . . . . . . . . . . . 6 ; 5.2 Error messages . . . . . . . . . . . . . . . . 7 ; 6. Input routines, GETWRD and GETHLF . . . . . . . . . . 8 ; 7. Interface to external subroutines . . . . . . . . . . 9 ; 8. Format of a .PLT file . . . . . . . . . . . . . . . . 10 ; 9. Main input loop . . . . . . . . . . . . . . . . . . . 11 ; 10. Process halfwords . . . . . . . . . . . . . . . . . . 12 ; 11. Opcode dispatch and handlers . . . . . . . . . . . . . 12 ; 12. Data area . . . . . . . . . . . . . . . . . . . . . . 14 SUBTTL Calling sequence -- MACRO programs (such as SPROUT) COMMENT ~ For SPROUT: (S1=1,S2=2,T1=3,T2=4,T3=5,T4=6,J=14,P=17) EXTERN TOLP. ;Routine to reverse PLOT INTERN PLOT ;Routine to move the pen INTERN NEWPEN,OPRTXT,PAUSEP,TITLE ;Other routines called by TOLP MOVEI S1,READ36 ;Input routine MOVEI S2,3 (or MOVEI S2,0) ;3 for internal header and trailer MOVE T1,J$XPOS(J) ;Current X position MOVE T2,J$YPOS(J) ;Current Y position PUSHJ P,TOLP.## ;Call routine to process PLOT file MOVEI S1,[ITEXT (<^T/0(S2)/ ^F/@J$DFDA(J)/>)] ;S2 points to ASCIZ SKIPE S2 ;If errors were detected, copy string PUSHJ P,PUTERR ; and file name to error buffer JRST PLTLP0 ;File is at EOF, finish up ;Routine to read a word from the input file, returns -1 for EOF, -2 on abort READ36: $CALL INPBYT ;Get a word MOVE T1,C ;Copy to expected AC JUMPT .POPJ ;Use it if OK MOVNI T1,-1 ; else -1 for EOF TXNE S,RQB+ABORT ;EOF caused by REQUE? MOVNI T1,-2 ;Yes, signify as such POPJ P, ;Continue back in TOLP ;End of CSM edit to SPROUT SUBTTL Calling sequence -- FORTRAN programs (such as TEK) CALL TOLP (READER,ICHAR,ITEXT) READER = (input) The name of the subroutine that will read one word from the .PLT file. This name must be declared in an EXTERNAL statement. IFLAG = (input) Flag for doing header and trailer. 0 = Don't do either, 1 = Header, 2 = Trailer, 3 = Both 4400 = Plot wraps around at 11 inches, 4803 = 12 inches + headers (output) Returned as 0 if no errors, word count if error occured. ITEXT = (output) The text of the error message, up to 80 characters stored in a (16A5) format. This array is not modified if IFLAG is returned as zero. ITEXT can be a CHARACTER*80 variable. FORTRAN example: DIMENSION ITEXT(16) !80 characters EXTERNAL READER !Subroutine to do input EXTERNAL PLOT,NEWPEN,OPRTXT,PAUSEP,TITLE !Required routines from FORLIB TYPE 10 10 FORMAT(' Name of PLT file: ',$) ACCEPT 20, ITEXT !Get name from user 20 FORMAT(16A5) OPEN(UNIT=1,DIALOG=ITEXT,ACCESS='SEQIN',MODE='IMAGE') CALL PLOTS(IERR,'TTY') !Initialize the graphics terminal IF(IERR.NE.0) STOP 'Cannot start plotting' D CALL FACTOR(0.7) !Optional, reduce size to fit on TEK screen IFLAG = 4400 !Make large plots wrap around CALL TOLP(READER,IFLAG,ITEXT) CALL PLOT(X,Y,999) !Proper end to the plot IF(IFLAG.EQ.0) STOP 'Plot is done' TYPE 30, (ITEXT(I),I=1,IFLAG) !Type the returned error message 30 FORMAT(' ?Error in plot - ',16A5) END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE READER(IWORD) !Called from inside TOLP READ(1,ERR=40) IWORD !Read 1 binary word from .PLT file RETURN !OK 40 IWORD = -1 !Minus one means End-of-File RETURN END ~ ;End of COMMENT SUBTTL Definitions SEARCH MACTEN ;Get TXNE and PJRST definitions SALL ;AC definitions TF=0 ;Scratch AC S1=1 ;GLXLIB AC definitions S2=2 ;(S1 and S2 are super-temp) T1=3 ;T1-T4 usually preserved T2=4 T3=5 T4=6 P1=7 ;Flag bits J=14 ;Pointer to data page L=16 ;Link to FORTRAN arguments P=17 ;PDL pointer .XCREF S1,S2,T1,T2,T3,T4,P1,P ;CREF only J and TF ;Flag bits in F F.V11== 1B1 ;File came from PLOT version 11 F.LONG==1B2 ;Long mode, 2 halfwords per move F.DOWN==1B3 ;Pen is down F.HEAD==1B4 ;Processing the header F.PLOT==1B5 ;Processing the plot F.TRAL==1B6 ;Processing the trailer F.EOP== 1B7 ;EOP opcode was seen F.MOVE==1B8 ;At least one move made with the pen down F.DOHD==1B9 ;Do plot the header F.DOTR==1B10 ;Do plot the trailer ;Function codes for subroutine PLOT PEN.DN==2 ;Move with the pen down PEN.UP==3 ;Move with the pen up INCS=400.0 ;Increments per inch in floating point ;Version 11 fudge factors STARTX==-^D400 ;Starting X value (-1.0 inch) STARTY==^D4400 ;Starting Y value (11.0 inches) PENSEP==^D300 ;Pen separation (0.75 inches) ;Feature test switches ND FORTRA,0 ;0=SPROUT calling sequence, -1=FORTRAN calls IF2,> IF2,> PAGE ;Argument types for FORTRAN-77 calling conventions OPDEF XMOVEI [SETMI] ;For extended addressing OPDEF IFIW [1B0] ;Instruction Format Indirect Word .NODDT IFIW OPDEF LOGICAL [IFIW 01,0] ;36 bit Boolean OPDEF INTEGER [IFIW 02,0] ;Fixed point argument OPDEF REAL [IFIW 04,0] ;Floating point argument OPDEF OCTAL [IFIW 06,0] ;12 digit octal (1 word) OPDEF PROC [IFIW 07,0] ;Subroutine label OPDEF DREAL [IFIW 10,0] ;Double precision floating point OPDEF DCOMP [IFIW 11,0] ;2 word COMP (COBOL only) OPDEF DOCTAL [IFIW 12,0] ;24 digit octal (2 words) OPDEF GFLOAT [IFIW 13,0] ;G-floating double precision OPDEF COMPLEX [IFIW 14,0] ;Real + imaginary OPDEF CHARACT [IFIW 15,0] ;Byte string descriptor to CHAR variables OPDEF STRING [IFIW 17,0] ;ASCIZ string ACFLD== ;Argument type is in the AC field ACPNTR==POINT 4,0,12 ;P and S of a byte pointer to the AC field DEFINE ACTYPE(TYPE),<_-^D23> ;For compare immediate SUBTTL Entry to TOLP(READER,ICHAR,ITEXT) ENTRY TOLP ;Name of this routine EXTERN PLOT ;Routine to drive the plotter EXTERN NEWPEN ;Routine to change pen colors EXTERN OPRTXT ;Routine to send a message to the OPR EXTERN PAUSEP ;Routine to pause the plotter EXTERN TITLE ;Routine to use hardware text capabilities ;A good plot file starts with the following 4 words, the first 2 are mandatory GOODPL: 400000,,000001 ;1B0 + 1B35 "PLOT" ;4 ASCII characters right justified ..==BYTE (3)0(9)12(6)0(18)514 ;Version 12(514) or version 11C(436) ..== PD.FLG,,400000 ;Flag bits, set short mode pen up IFN FORTRA,< ; CALL TOLP(READER,IFLAG,ITEXT) ; READER = routine ; IFLAG = header flag bits ; ITEXT = message returned there SIXBIT /TOLP/ TOLP: MOVEM L,SAVEL ;Save link to args MOVEI S1,@0(L) ;Addr of reader routine MOVE S2,@1(L) ;Flag bits SETZB T1,T2 ;No offset MOVEI J,J$DATA## ;Point to data area > ;End of IFN FORTRA IFE FORTRA,< TOLP.:: ;Entry to TOLP from SPROUT, TF is scratch ;S1/ addr of input routine ;S2/ 0 if /NOHEADER, 3 if /HEADER ;T1/ J$XPOS(J) T2/ J$YPOS(J) TOLP:> ;End of IFE FORTRA MOVEM P1,SAVEP1(J) ;Preserve P1 MOVEI P1,0 ;Clear flags MOVEM S1,INPRTN(J) ;Save address of input routine TROE S2,1 ;Do the header? TXO P1,F.DOHD ;Yes TROE S2,2 ;Trailer? TXO P1,F.DOTR ;Yes CAIG S2,^D<7*400> ;Want a reasonable wraparound value? MOVX S2,1B17 ;No, set to no wrap MOVEM S2,MAXINC(J) ;Increments will be modulo this number DMOVEM T1,XORIG(J) ;Set current X and Y positions SETZM INDATA(J) ;Force GETHLF to read a word SUBTTL Verify that the plot file starts correctly VERIFY: PUSHJ P,GETWRD ;Get first word from the file JSP S1,ILLFMT ;EOF on first word, bad plot CAME T1,GOODPL+0 ;First word match? JSP S1,ILLFMT ;Could be ASCII text or a .REL file PUSHJ P,GETWRD ;Get second word JSP S1,ILLFMT CAME T1,GOODPL+1 ;2nd word match with "PLOT"? JSP S1,ILLFMT PUSHJ P,GETWRD ;Get version number of PLOT.REL JSP S1,ILLFMT ; from 3rd word LDB T2,[POINT 9,T1,11];Get the major version number CAIG T2,11 ;After version 11? TXO P1,F.V11 ;No, must use kludges ;Initialize incremental pen position SETZB T1,CUR.X(J) ;Simulate CALL PLOT(0.0,0.0,3) SETZB T2,CUR.Y(J) ; to lift pen at current position MOVEI T3,PEN.UP MOVEM T3,PLOTI(J) PUSHJ P,EXPLOT ;Call external PLOT routine ;Set up kludges for version 11 of PLOT.REL HRREI T1,STARTX ;Get X starting value HRREI T2,STARTY ;Get Y starting value TXNN P1,F.V11 ;Use them if version 11 SETZB T1,T2 ; since version 12 is fixed TXNE P1,F.DOHD ;Is the header wanted? MOVEI T1,0 ;Yes, put it on the screen MOVEM T1,CUR.X(J) ;Set X and MOVEM T2,CUR.Y(J) ; Y positions MOVEI T1,1 ;Current pen is #1 MOVEM T1,PENSAV(J) ;(another V11 kludge) ;Skip over optional flag bytes in the PLT file GET1ST: PUSHJ P,GETHLF ;Get next byte JSP S1,ILLFMT ;Premature EOF TRNE T1,PD.OPC ;Opcode? JRST SOH ;Yes, start of header ANDI T1,PD.FLG ;No, keep only the defined flag bits MOVEM T1,INFLAG(J) ;Save input file flags (not used yet) JRST GET1ST ;Go for opcode SOH: TXO P1,F.HEAD ;Now in start of header JRST PLTME1 ;Jump into main loop SUBTTL Exit from TOLP -- ERROR and DONE routines .DIRECTIVE FLBLST ;List only first line of ASCIZ ILLFMT: SUBI S1,2 ;For DDT, S1 points to PUSHJ or compare instr JSP S2,ERROR ;S2 points to error message ASCIZ /Illegal format for PLOT file / NOEOP: JSP S2,ERROR ASCIZ /Incomplete, PLOT(X,Y,999) not called / EMPTY: JSP S2,ERROR ASCIZ /Plot file was empty / OPRABT: JSP S2,ERROR ASCIZ /Plot aborted by OPR / ;Exit from TOLP DONE0: MOVEI S2,0 ;No errors detected ERROR: PUSH P,S2 ;Save error flag MOVEI T3,PEN.UP ;Raise the pen MOVEM T3,PLOTI(J) PUSHJ P,EXPLOT ;At current position POP P,S2 IFN FORTRA,< MOVE L,SAVEL ;Restore FORTRAN arg pointer SETZM @1(L) ;Clear error flag DONE1: JUMPE S2,DONE2 ;Leave ITEXT unchanged if no error ;Copy ASCIZ error message to user's FORTRAN array XMOVEI T1,@2(L) ;Get addr of array or descriptor LDB T2,[ACPNTR 2(L)] ;Get type of argument CAIE T2,ACTYPE(CHARACT) ;CHARACTER expression? JRST NUMARY ;No, numeric array DMOVE T1,0(T1) ;Get byte pointer and count JRST COPYM0 ;(FORTRAN-77 works on KL-10's only) NUMARY: HRLI T1,(POINT 7,) ;Point to the INTEGER array MOVEI T2,^D80 ;80 bytes COPYM0: MOVE T3,T2 ;Save original byte count HRLI S2,(POINT 7,) ;Source byte pointer COPYMS: ILDB S1,S2 ;Get a byte JUMPE S1,COPYDN ;Loop till after null at end of ASCIZ IDPB S1,T1 ;Store in ITEXT array SOJG T2,COPYMS ;Count chars and loop COPYDN: SUB T3,T2 ;Number of bytes transferred IDIVI T3,5 ;Make into word count MOVEM T3,@1(L) ;Nonzero for error flag MOVEI S1," " ;Blank out rest of array JUMPLE T2,DONE2 COPYD1: IDPB S1,T1 ;Store blanks at end of ITEXT SOJG T2,COPYD1 > ;End of IFN FORTRA ;Exit with error flag in S2 DONE2: MOVE P1,SAVEP1(J) ;Restore P1 POPJ P, ;Return from TOLP SUBTTL Format of a .PLT file ; !===============================================================! ; ! PLOTTER MODE -- 18 BIT ! ; ! ! ; ! In 18 bit mode, each halfword from the disk has 9 bits of ! ; ! delta Y and 9 bits of delta X movement. If the delta Y part ! ; ! is negative zero, then the X part is an op-code (such as to ! ; ! raise or lower the pen). The only exception is in LONG mode, ! ; ! where the deltas come in halfword pairs. The first of the ! ; ! pair is 16 bits of delta Y with 1 bit pen-down information ! ; ! (the OPCODE bit always zero), and the second byte is 18 bits ! ; ! of delta X. At 400 steps per inch, max X is 327 inches, and ! ; ! max Y is 81 inches (27.0 by 6.75 feet) ! ; ! ! ; !===============================================================! ; ; ! SGNY ! ABS(Delta Y) ! SGNX ! ABS(Delta X) ! ;SHORT mode ; !=1B18=!=====377B26=====!=1B27=!====377B35====! ; ; ! 1 ! 0 ! Operation code ! ;OPCODE ; !=1B18=!=====377B26=====!=======777B35========! ; ; ! 0 ! PEN ! SGNY ! ABS(Delta Y) ! ;1st LONG byte (Y) ; !=1B18=!=1B19=!=1B20=!========77777B35========! ; ; ! SGNX ! ABS(Delta X) ! ;2nd LONG byte (X) ; !=1B18=!=====================377777B35========! ;Definitions for Plot Data (PD.xxx) PD.SYS==400000 ;Short mode Y sign PD.SYM==377000 ;Short mode Y magnitude PD.SXS== 400 ;Short mode X sign PD.SXM== 377 ;Short mode Y magnitude PD1000= 1000 ;IDIVI by this to separate DY and DX PD.LSH== -9 ;After IDIVI, Y is shifted this much PD.OPC==400000 ;OPCODE if PD.SYM is zero PD.LPD==200000 ;Long mode pen down (in 1st word) PD.LYS==100000 ;Long mode Y sign (in 1st word) PD.LYM== 77777 ;Long mode Y magnitude (in 1st word) PD.LXS==400000 ;Long mode X sign (in 2nd word) PD.LXM==377777 ;Long mode X magnitude (in 2nd word) ;Bits from optional Plot Flag byte (PF.xxx) PF.400==200000 ;Plot flag - using 400 increments per inch PF.PEN==100000 ;Plot flag - using more than one pen PF.OPR== 40000 ;Plot flag - OPRTXT routine present PF.HDR== 20000 ;Plot flag - header/trailer in ASCIZ PD.FLG==PF.400!PF.PEN!PF.OPR!PF.HDR ;All defined flags %D400=^D400 ;400 increments per inch SUBTTL Main input loop ;Here to interpret each new halfword from the input file PLTME: PUSHJ P,GETHLF ;Go get a half word JRST ATEOF ;End of file PLTME1: TRNN T1,PD.SYM ;Does Y look like -infinity? TRZN T1,PD.OPC ;Yes, was the OPCODE bit set? JRST PLT ;No, plot the line segment and loop to PLTME CAIL T1,PLTMAX ;Skip if the function is valid JSP S1,ILLFMT ;Illegal opcode, go die PUSHJ P,@PLTFNC(T1) ;Go do the right thing JRST PLTME ;And go for more ;End of file processing ATEOF: CAMN T1,[-2] ;Abort? JRST OPRABT ;Yes, OPR aborted plot TXNN P1,F.MOVE ;Any movements with the pen down? JRST EMPTY ;Error, plot file was empty TXNN P1,F.EOP ;End-Of-Plot opcode seen? JRST NOEOP ;No, complain JRST DONE0 ;Yes, plot finished normally (S2=0) SUBTTL Process halfwords PLT: TXNE P1,F.LONG ;Long mode? JRST PLT0 ;Yes, 2 halfwords per move ;Short mode - each halfword is 9 bits of Y and 9 bits of X IDIVI T1,PD1000 ;Put DY into T1, DX into T2 TRZE T1,PD.SYS_PD.LSH;If the Y sign bit is on, MOVNS T1 ; negate the magnitude TRZE T2,PD.SXS ;If the X sign bit is on, MOVNS T2 ; negate the magnitude JRST PLT1 ;Go update X & Y ;Long mode - Y is in this halfword, X is in the next PLT0: TRZE T1,PD.LPD ;If the pen is to be down, TXOA P1,F.DOWN ; set the pen down flag, TXZ P1,F.DOWN ; else clear it MOVE T2,T1 ;Save DY PUSHJ P,GETHLF ;Get next byte JRST ATEOF ;Should not get EOF here EXCH T1,T2 ;Get DX & DY in the right place TRZE T1,PD.LYS ;If the Y sign bit is on, MOVNS T1 ; use the negative TRZE T2,PD.LXS ;Same for X MOVNS T2 ; ... MOVM S1,T2 ;Get ABS(X) MOVM S2,T1 ;Get ABS(Y) CAMG S1,MAXINC(J) ;Very large delta X? CAMLE S2,MAXINC(J) ; or delta Y? PUSHJ P,TOOBIG ;Yes, trigger DDT breakpoint ;Calculate new position based on delta-X and delta-Y PLT1: ADDM T2,CUR.X(J) ;Add incremental to X position ADDM T1,CUR.Y(J) ;Make new Y ;Conditionally ignore the header stored in the PLT file TXNE P1,F.HEAD ;In the header? TXNE P1,F.DOHD ;And header is wanted? TRNA ;Continue JRST PLTME ;Do not plot the header TXNE P1,F.TRAL ;In the trailer? TXNE P1,F.DOTR ;And trailer wanted? TRNA ;Continue JRST PLTME ;Do not plot the trailer PAGE ;Continued on next page ;Set the pen up/down code based on F.DOWN MOVEI T1,PEN.UP ;Assume movement with the pen up TXNN P1,F.DOWN ;OK? JRST PLT2 ;Yes MOVEI T1,PEN.DN ;No, pen down this move TXNE P1,F.PLOT ;In the body of the plot? TXO P1,F.MOVE ;Yes, at least 1 move with the pen down PLT2: MOVEM T1,PLOTI(J) ;Store function code PUSHJ P,EXPLOT ;Move the pen ;Pen-up lasts for 1 move in short mode, and is recalculated in long mode TXNN P1,F.V11 ;Version 11? TXO P1,F.DOWN ;SHORT-UP lasts for 1 move in version 12 JRST PLTME ;Loop back for more data ;Here when long-mode has an unreasonable movement ;This routine is here only for using DDT on the TEK program TOOBIG: MOVE S1,T2 ;Get X (with sign) FSC S1,233 ;To f.p. FDVR S1,[INCS] MOVE S2,T1 ;Get Y (with sign) FSC S2,233 FDVR S2,[INCS] CLIPIT::CAM S1,S2 ;Put a DDT breakpoint here POPJ P, ;This command string works for DDT version 41 or later $FS1S2: ASCIZ ~F S1/ S2/~ ;Use $FS1S2>CLIPIT$B SUBTTL Opcode dispatch and handlers PLTFNC: SHTUP ; 0 - short mode - pen up SHTDWN ; 1 - short mode - pen down LNGUP ; 2 - long mode - pen up LNGDWN ; 3 - long mode - pen down EOP ; 4 - end-of-plot EOH ; 5 - end-of-header (or start-of-trailer) MSGOPR ; 6 - message to the operater PLTPAS ; 7 - pause output the plotter (no-op in TEK) PEN1 ;10 - use pen #1 PEN2 ;11 - use pen #2 PEN3 ;12 - use pen #3 PEN4 ;13 - use pen #4 PEN5 ;14 - use pen #5 PEN6 ;15 - use pen #6 PEN7 ;16 - use pen #7 PEN8 ;17 - use pen #8 TEXT ;20 - use hardware text generator DELAY ;21 - pause graphics terminal for a few seconds REPEAT 0,< COLOR ;22 - RGB color specifier > ;End of REPEAT 0 PLTMAX==.-PLTFNC ;Highest value + 1 ;400000 Short mode, pen up ;400001 Short mode, pen down SHTUP: TXZA P1,F.DOWN ;Clear pen down flag SHTDWN: TXO P1,F.DOWN ;Set the pen down flag TXZ P1,F.LONG ;Clear long mode flag POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) ;400002 Long mode, pen up ;400003 Long mode, pen down LNGUP: ;Use PD.LPD in next byte for pen up/down status LNGDWN: TXO P1,F.LONG ;Set long mode flag POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) ;400004 End of plot EOP: TXO P1,F.EOP ;End of plot seen POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) PAGE ;400005 End of header, or start of trailer EOH: TXZN P1,F.HEAD ;During the header? JRST SOT ;No, start of trailer TXO P1,F.PLOT ;Yes, end of header, start of plot TXNN P1,F.DOHD ;If header was plotted TXNE P1,F.V11 ; or version 11 POPJ P, ;Keep X and Y the same SETZM CUR.X(J) ;Version 12, reset X position to start plot SKIPE S1,CUR.Y(J) ;Y position should be zero EOHYER: JFCL S1 ;End of header Y error POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) SOT: MOVEI T1,PEN.UP ;Raise pen, but stay PUSHJ P,EXPLOT ; at current position TXO P1,F.TRAL ;Start of trailer TXZ P1,F.PLOT ;End of body of plot TXNE P1,F.V11 ;Version 11? POPJ P, ;Yes, position is unpredictable SKIPE S1,CUR.Y(J) ;Or Y position zero? SOTYER: JFCL S1 ;Start of Trailer Y error POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) ;400006 Message for the OPR MSGOPR: PUSHJ P,GETHLF ;Go get the word count of the message JRST BADEOF ;Bad plot file MOVE T2,T1 ;Copy word count IMULI T1,5 ;Convert to a byte count MOVEM T1,ICOUNT(J) ;Save for a while MOVEI T3,MESAGE(J) ;Set index pointer HRLI T3,-MSGMAX ;AOBJN pointer MSGOP0: PUSHJ P,GETWRD ;Go get a word JRST BADEOF ;Bad plot file SKIPGE T3 ;More than we can handle? MOVEM T1,(T3) ;No, store it AOBJN T3,.+1 ;Increment pointer SOSG T2,MSGOP0 ;Get rest of message PUSHJ P,OPRTX ;Send message via OPRTXT POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) ;Unexpected EOF BADEOF: POP P,(P) ;Dump the return for PUSHJ P,@PLTFNC(T1) JRST ATEOF ;Ignore this OPCODE, finish up ;400007 Pause, wait for OPR intervention PLTPAS: MOVEI T1,0 ;Zero seconds means indefinately PUSHJ P,PAUSE ;Pause the plotter POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) PAGE ;400010-400017 Set pen number, 1 to 8 PEN1: PEN2: PEN3: PEN4: PEN5: PEN6: PEN7: PEN8: SUBI T1,7 ;Get pen number, 1 to 8 EXCH T1,PENSAV(J) ;Save the new pen number SUB T1,PENSAV(J) ;Find how many pens over to move IMULI T1,PENSEP ;Find how many plot increments that is TXNE P1,F.V11 ;If version 11 (which has only pens 1-3), ADDM T1,CUR.Y(J) ; cancel the next 0.75 inch Y offset PUSHJ P,NEWPN ;Change pen POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) ;400020 Use hardware character generator ;1st HW BYTE(9)DIR,CNT ;DIR = 0 to 359 degrees, CNT = 1 to 511 bytes ;2nd HW BYTE(18)HITE ;HITE = Size in increments ;rest BYTE(7)TEXT ;TEXT = Up to 102 words of text TEXT: PUSHJ P,GETHLF ;Get direction and number of chars JRST BADEOF IDIVI T1,1000 ;Separate direction from count MOVEM T1,ANGLE(J) ;Store integer degrees MOVEM T2,ICOUNT(J) ;Store byte count ADDI T2,4 ;Round up IDIVI T2,5 ;Make into word count PUSHJ P,GETHLF ;Get size JRST BADEOF MOVEM T1,HEIGHT(J) ;Save size in increments (integer) MOVEI T4,MESAGE(J) ;Point to message area HRLI T4,-MSGMAX ;AOBJN pointer TEXT1: PUSHJ P,GETWRD ;Get next word JRST BADEOF SKIPGE T4 ;If not too much, MOVEM T1,(T4) ; store word of text AOBJN T4,.+1 ;Point to next word in message area SOJG T2,TEXT1 ;Get all PUSHJ P,TITLEX ;Call external subroutine POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) ;400021 Delay if going to graphics terminal DELAY: PUSHJ P,GETHLF ;Get number of seconds JRST BADEOF ;Error-end of file PUSHJ P,PAUSE ;T1 has number of seconds to delay POPJ P, ;Return from PUSHJ P,@PLTFNC(T1) REPEAT 0,< ;400022 Get 18 bits of RGB data COLOR: PUSHJ P,GETHLF ;Get next halfword JRST BADEOF ;T1 gets BYTE(6)RED,GREEN,BLUE POPJ P, ;Ignore it for now > ;End of REPEAT 0 SUBTTL Input routines, GETWRD and GETHLF ;Routine to get a 36 bit word from 2 consecutive halfwords. ;Note: The 2 halfwords might not be in the same fullword in the file GETWRD: PUSHJ P,GETHLF ;Get first half POPJ P, ;Error, T1 has -1 or -2 HRLM T1,(P) ;Save on stack PUSHJ P,GETHLF ;Get 2nd half POPJ P, ;Error HLL T1,(P) ;Combine the 2 halves CPOPJ1: AOS (P) ;Make for skip return CPOPJ: POPJ P, ;Routine to get an 18 bit halfword from the input file ;CALL: PUSHJ P,GETHLF ; JRST ATEOF or JRST BADEOF ; *good return* Data in T1 GETHLF: SKIPL INDATA(J) ;Is the sign bit set? JRST READWD ;No, call external routine to read a word HRRZS T1,INDATA(J) ;Yes, clear sign bit and return halfword in T1 JRST CPOPJ1 ;Give skip return ;Interface for subroutine READER(INDATA) IFN FORTRA,< -1,,0 LREADR: INTEGER TEMP1 ;Word as 36-bit integer READWD: MOVEI L,LREADR > ;End of IFN FORTRA IFE FORTRA,< READWD: > MOVEM P1,FLAGS(J) MOVE P1,SAVEP1(J) PUSH P,J PUSHJ P,@INPRTN(J) ;Read one word into T1 POP P,J MOVEM P1,SAVEP1(J) MOVE P1,FLAGS(J) IFN FORTRA, MOVEM T1,INDATA(J) ;Store it CAME T1,[-1] ;Did READER return EOF marker? CAMN T1,[-2] ; or ABORT marker? POPJ P, ;Yes, give error return HRROM T1,INDATA(J) ;Set sign bit for next time HLRZS T1 ;Put halfword in RH JRST CPOPJ1 ;Give skip return SUBTTL Interface to external subroutines ;Interface to subroutine PLOT(XPOS,YPOS,IC) IFN FORTRA,< -3,,0 LPLOT: REAL TEMP1 ;XPOS REAL TEMP2 ;YPOS INTEGER TEMP3 ;IC EXPLOT: MOVE T1,CUR.X(J) ;Get X increments IDIV T1,MAXINC(J) ;Wraparound on the TEK screen FSC T2,233 ;Convert to FP increments FDVR T2,[INCS] ;Convert to FP inches MOVEM T2,TEMP1 SKIPE T1 ;If X was clipped, CLIPX: CAM T1,TEMP1 ; put a DDT breakpoint here MOVE T1,CUR.Y(J) ;Same for Y IDIV T1,MAXINC(J) ;Wraparound on the TEK screen FSC T2,233 FDVR T2,[INCS] MOVEM T2,TEMP2 SKIPE T1 CLIPY: CAM T1,TEMP2 MOVE T1,PLOTI(J) MOVEM T1,TEMP3 XMOVEI L,LPLOT ;Point to FORTRAN args > ;End of FORTRA IFE FORTRA,< EXPLOT: DMOVE T1,XORIG(J) ;Get SPROUT's offsets ADD T1,CUR.X(J) ;Position in increments ADD T2,CUR.Y(J) MOVE T3,PLOTI(J) ;Pen up/down code > ;End of IFE FORTRA MOVEM P1,FLAGS(J) MOVE P1,SAVEP1(J) PUSH P,J PUSHJ P,PLOT## POP P,J MOVEM P1,SAVEP1(J) MOVE P1,FLAGS(J) POPJ P, ;Interface to subroutine NEWPEN(IPEN,IERR) IFN FORTRA,< -2,,0 LNEWPN: INTEGER TEMP1 ;IPEN INTEGER TEMP2 ;IERR > ;End of IFN FORTRA NEWPN: MOVE S1,PENSAV(J) ;Get new pen number IFN FORTRA,< MOVEM S1,TEMP1 MOVEI L,LNEWPN > ;End of IFN FORTRA MOVEM P1,FLAGS(J) MOVE P1,SAVEP1(J) PUSH P,J PUSHJ P,NEWPEN## POP P,J MOVEM P1,SAVEP1(J) MOVE P1,FLAGS(J) POPJ P, ;Interface to subroutine OPRTXT(MESAGE,NCHAR) OPRTX: MOVE S1,ICOUNT(J) ;Get number of characters in message MOVEI S2,MESAGE(J) ;Address of string MOVEM P1,FLAGS(J) MOVE P1,SAVEP1(J) PUSH P,J PUSHJ P,OPRTXT## POP P,J MOVEM P1,SAVEP1(J) MOVE P1,FLAGS(J) POPJ P, ;Interface to subroutine PAUSEP(ISEC) PAUSE: MOVE S1,T1 ;Put seconds in right AC MOVEM P1,FLAGS(J) MOVE P1,SAVEP1(J) PUSH P,J PUSHJ P,PAUSEP## POP P,J MOVEM P1,SAVEP1(J) MOVE P1,FLAGS(J) POPJ P, ;Interface to subroutine TITLE(XSTART,YSTART,HEIGHT,MESAGE,ANGLE,ICOUNT) TITLEX: MOVE T1,HEIGHT(J) ;Get args MOVEI T2,MESAGE(J) MOVE T3,ANGLE(J) MOVE T4,ICOUNT(J) MOVEM P1,FLAGS(J) MOVE P1,SAVEP1(J) PUSH P,J PUSHJ P,TITLE## POP P,J MOVEM P1,SAVEP1(J) MOVE P1,FLAGS(J) POPJ P, SUBTTL Data area EXTERN TOLPBF,J$$END ;For .ASSIGN DEFINE LP(NAME,SIZE),< NAME=TOLPBF+<..=J$$.> J$$.==J$$.+SIZE ..==..> J$$.==0 ;From calling program LP SAVEP1, 1 ;Preserve P1 LP FLAGS, 1 ;Flags (in P1) LP INPRTN, 1 ;Addr of input routine LP MAXINC, 1 ;Maximum size before wraparound ;For subroutine PLOT LP PLOTX, 1 ;X coordinate in inches (floating point) LP PLOTY, 1 ;Y coord LP PLOTI, 1 ;Function code to PLOT, 2 or 3 ;Current pen status LP CUR.X, 1 ;Current X position (integer increments) LP CUR.Y, 1 LP XORIG, 2 ;Offset provided by SPROUT YORIG=XORIG+1 LP PENSAV, 1 ;Current pen number ;For GETWRD LP INDATA, 1 ;Word read from input file LP INFLAG, 1 ;Input file flag bits ;For TITLE and OPRTXT MSGMAX=^D300/5 ;Max chars in message to OPRTXT LP ICOUNT, 1 ;Temporary integer LP ANGLE, 1 ;Direction for TITLE LP HEIGHT, 1 ;Size for TITLE LP MESAGE, MSGMAX ..==J$$. .ASSIGN TOLPBF,J$$END,J$$. ;TOLPBF=J$$END, J$$END=J$$END+J$$. TOLP..=:J$$END-1 ;Last data loc used by this routine PURGE .. IFN FORTRA,< SAVEL: BLOCK 1 TEMP1: BLOCK 1 TEMP2: BLOCK 1 TEMP3: BLOCK 1 TEMP4: BLOCK 1 > LITS: END