By far, the most ubiquitous computer graphics device in the U.S. has been the CalComp Drum Plotter. Equally popular has been the CalComp Basic Software Package (copy right by California Computer Products, Inc.), which consists of 6 subroutines callable from a high level language such as FORTRAN or PL/1. When the computer driven microfilm recorders such as the Stromberg DatagraphiX 4020 became available, many prospective users were discouraged at the prospect of a major reprogramming effort. The following is a description of two FORTRAN IV subroutines that will efficiently translate a CalComp program into an SD 4020 output tape. When submitted behind an existing plotter program, they accomplish the conversion process without altering any source code at all.
The CalComp Software is based on an inverted pyramidal hierarchical structure resting on the subroutine PLOT (see Fig. 1)
All calls develop a line or series of line strokes that eventually call PLOT with 3 arguments. (A note of warning: In SYMBOL, register zero may have to be reset to one after PLOT is called. It expects PLOT to be in Assembly Language, which leaves register zero intact.) These specify the X and Y coordinates of a point, and a code to indicate whether the pen should be lowered or lifted. Thus if the PLOT subroutine were replaced with another subroutine that would field all pen commands and remember the beginning and ending points of a line stroke, it would call another routine to encode this line in 4020 form. This is a far more efficient scheme than translating an output Calcomp tape, which is chain encoded into very small discrete steps of several thousandths of an inch in length. Furthermore, most computer operating systems will permit the inclusion of two subroutines by the same name (in this case, PLOT) in a source module; the latter one will overlay the former and take precedence. This is essential to our desired operation. As a matter of fact this technique can be used to translate Calcomp Programs to drive any graphical device. The author uses it to view plots rapidly on an IBM 2250 graphics display unit.
The new PLOT subroutine must control 3 other vital conditions: the beginning of a tape, the end of a tape, and the advance of the microfilm roll. A call to PLOTS (an entry point within the original PLOT) should demand a RESET condition in the 4020. A value of 999 for the PEN parameter (third argument of PLOT call) should spill the buffer and place an End File on the tape. And finally, a value of -3 for the PEN parameter which requests a new origin in the original PLOT subroutine, will arbitrarily be treated as a request for a new frame of film. All of these functions are performed by setting a code number, and calling an all FORTRAN subroutine VECTOR, described in the next section.
The new PLOT should also allow specifications of full screen boundaries in terms of inches. This was done by adding an entry point called BOUNDS (XL, YB, XR, YT) where:
(XL,YB) defines the lower left corner, and
(XR.YT) defines the upper right corner.
The default values are (-1.0, -1.5) for lower left, and (11.0, 10.5) for upper right. These values were chosen to give a twelve inch square area which allows room for lettering below or to the left of the origin. This call can also be used to reset the origin; e.g. CALL BOUNDS (-5.0, -5.0, 5.0, 5.0) gives a 10 inch square plotting area with the origin at the center. The standard call to the entry point FACTOR(FACT) can still be invoked to multiply all coordinates by FACT. Using the parameters given in BOUNDS and FACTOR, PLOT normalizes all coordinates to a square of size 0 to 1023 in both X and Y directions. Thus, 4 fixed point co-ordinate values and one function code are passed in each call to VECTOR for conversion.
The only generally available software for the SD 4020 has been the SCORS package written by the North American Aviation Co. This is a very comprehensive system that is designed for producing graphs and controlling text, but is obviously over-engineered for simple line drawing tasks. As a matter of fact, in order to plot a line under SCORS, no less than 10 different subroutines were involved! As each subroutine is linked, all registers are stored and eventually reloaded, so a great deal of CPU time was needlessly lost. By putting all this logic and encoding within VECTOR, a typical straight line plotting program takes only 60% of the time previously required.
Only 3 commands in the 4020 instruction set are needed. RESET performs simultaneously ADVANCE FILM, STOP TYPE, and EXPOSE HEAVY commands, at the beginning of a run. ADVANCE FILM, is also needed by itself. Whenever either of these two control operations is requested, a short length record is written to force an inter-record gap. This allows a time delay in case a 4020 installation does not have an F-53 input buffer. It also permits compatibility with a CII 120 microfilm recorder.
The other 4020 command needed is DRAW VECTOR. (See Fig. 2).
The command is built in FORTRAN using multiplication by powers of 2. This is somewhat time consuming itself, and could be avoided by a left shift assembly language routine. Unfortunately, the largest vector possible with this bit structure is 63 raster units long for both X and Y coordinates. A longer line, then, is broken down into smaller lengths with repetitive DRAW VECTOR commands. The 2 Op Code bits are always 1, and the sign bits appear as 1 if in a positive sense, 0 if negative.
Since the total command contains 36 bits, it is written on a 7 track tape as 6 contiguous 6 bit (plus parity) characters This arrangement works out on a 36 bit word computer in fixed point arithmetic, but the left most bit (which must always be 1 for DRAW VECTOR) is treated as a sign bit. On an IBM 7094, only the sign bit is flipped to indicate negative numbers, so the word is negated, and 2**34 is added for the Op Code portion. On a 36 bit word UNIVAC 1108, negative numbers are handled in one's complement form, so a negative (2**34 - 1) is added. A CDC 3800 has 48 bits, so the sign bit is left positive (zero), but a right adjusted format of 6 characters must be specified (FORMAT(170R6)).
The IBM 360 has a 32 bit word (4 eight bit bytes), so that a full command will not fit. An optional convert feature on some machines will strip off 6 contiguous bits for each character, but this leaves an awkward fraction of a word to deal with. To allow compatibility with 360 computers without the convert feature, the standard truncation of 8 bit bytes to 6 bit characters was assumed. Each byte is padded with 2 leading zeros which are not used. (See Fig. 3).
With the above structure, a command is nested within 3 half words so that a modest sized 510 half word array is required to store 170 commands, which fill a small F-53 buffer.
It is my feeling that Graphics should be treated as an ancillary function to computer applications. It should not become a stumbling block for the novice who wants effective pictorial output for a useful program. If a programmer is already familiar with CalComp plotting commands, there is no reason for him to master a new language simply to take advantage of the convenience of microfilm.
SUBROUTINE PLOT(X, Y, IPEN) C THIS SUBROUTINE OVERLAYS THE PLOT SUBROUTINE IN THE CALCOMP C PACKAGE AND TRANSLATES THE OUTPUT INTO CODE FOR THE STROMBERG C DATAGRAPHIX 4020. IT CALLS ON VECTOR TO ENCODE THE COMMANDS. C WRITTEN BY S.E.ANDERSON APPLIED PHYSICS LAB. JULY 1970 C REQUIRES PATCH TO SYMBOL...LA 0,1 AFTER SYMB1030 IN SOURCE DECK C USE CALL PLOTS(...) TO INITIALIZE TAPE. C USE CALL BOUNDS (XXL,YYB,XR,XT) TO SPECIFY LOWER LEFT CORNER C (XXL,YYB) AND UPPER CORNER (XR,YT) OF SCREEN C USE IPEN=-3 TO ADVANCE FRAME C USE IPEN=999 TO TERMINATE TAPE GO TO 100 ENTRY PLOTS(IBLF,NLCC,LDEV) C RESET AT BEGINNING OF RUN CALL VECTOR(0,0,0,0,3) C SET UP CONSTANTS FCT=1. XMLT=85.3 YMLT=85.3 XL=-1.0 YB=-1.5 C START WITH 5 BLANK FRAMES OF FILM... DO 9991 J=1,5 9991 CALL VECTOR(0,0,0,0,2) GO TO 999 ENTRY WHERE(RXPAGE, RYPAGE, RFACT) RXPAGE=X RYPAGE=Y RFACT=FCT GO TO 999 ENTRY OFFSET(XCFF,XFCT,YCFF,YFCT) GO TO 999 ENTRY FACTCR(FACT) FCT=FACT GO TO 999 ENTRY BOUNDS(XXL,YYB,XR,YT) XL=XXL YB=YYB XMLT=1023./(XR-XL) YMLT=1023./(YT-YB) GO TO 999 100 IF(IPEN-99) 200,104,104 C END OF FORTRAN PROGRAM C EXECUTE BUFFER CONTENTS AT END OF RUN. 104 CALL VECTOR(0,0,0,0,4) GO TO 999 C PLOT A LINE... 200 IX1=IX2 IY1=IY2 IF(FCT.EQ.1.)GOTO 201 X=X*FCT Y=Y*FCT 201 IX2=(X-XL)*XMLT IY2=(Y-YB)*YMLT IF(IPEN-2)400,202,999 C IF IPEN=-3 CALL FOR A NEW FILM FRAME C DISREGARD THE X,Y CO-ORDINATES 400 CALL VECTOR(0,0,0,0,2) GOTO 999 C DRAW LINE 202 CALL VECTOR(IX1,IY1,IX2,IY2,1) 999 RETURN END
SUBROUTINE VECTOR(IX1,IY1,IX2,IY2,ICODE) C IBM 360 VERSION (32 BIT WORD) C THIS FORTRAN SUBROUTINE CREATES A 7 TRACK TAPE FOR THE 4020 C STROMBERG DATAGRAPHIX MICROFILM RECORDER. IT ACCEPTS ONLY C LINE DRAWING AND FRAME ADVANCE COMMANDS (NO CHARACTERS). C WRITTEN BY S.E.ANDERSON APPLIED PHYSICS LAB. JULY 1970 C IT DRAWS A LINE FROM (IX1,IY1) TO (IX2,IY2) C WHERE X AND Y RANGE FROM 0 TO 1023 C ICODE=1 FOR LINES C ICODE=2 FOR FRAME ADVANCE C ICODE=3 FOR RESET (INITIALIZES 4020) C ICODE=4 FOR END OF TAPE DIMENSION J(4) INTEGER*2 IBFR(510)ISGNX=1 ISGNY=1 IRET=1 GO TO (101,102,103,104),ICODE C FRAME CMND. 102 IHW1=9728 IF(IX.GT.4) GO TO 200 IBFR(IX)=2560 IX=IX+3 GO TO 102 C RESET CMND 103 IHW1=11776 IBFR(1)=2560 IBFR(4)=2560 IX=7 GO TO 200 C STOP TYPE CMD 104 IF(IX-1)208,208,204 C VECTOR CMND C TRUNCATE LINES AT BORDERS 101 J(1)=IX1 J(2)=IY1 J(3)=IX2 J(4)=IY2 DO 400 I=1,4 IF(J(I).LT.0) J(I)=0 IF(J(I).GT.1023) J(I)=1023 400 CONTINUE C INVERT Y COORDINATES IXD=J(1) IYD=1023-J(2) IDX=J(3)-J(1) IDY=J(2)-J(4) IF(IDY)418,416,420 C IGNORE ZERO LENGTH LINES 416 IF(IDX)422,999,424 C CASE WHERE Y COMPONENT IS NEGATIVE 418 IDY=-IDY ISGNY=-1 420 IF(IDX)422,424,424 C CASE WHERE X COMPONENT IS NEGATIVE 422 IDX=-IDX ISGNX=-1 424 IF(IDX-IDY)128,120,120 C CASE WHERE IDX GE IDY 120 TAN=FLOAT(IDY)/FLOAT(IDX) IXC=63 IYC=63.0*TAN IXCS=IXC*ISGNX IYCS=IYC*ISGNY N=IDX/63 IF(N)125,125,123 123 IRET=2 DO 124 I=1,N GO TO 199 126 IXD=IXD+IXCS 124 IYD=IYD+IYCS 125 IXC=IDX-N*63 IYC=FLOAT(IXC)*TAN IRET=1 GO TO 199 C CASE WHERE IDY GE IDX 128 CCT=FLOAT(IDX)/FLOAT(IDY) IXC=63.0*CCT IYC=63 IXCS=IXC*ISGNX IYCS=IYC*ISGNY N=IDY/63 IF(N)131,131,129 129 IRET=3 DO 130 I=1,N GO TO 199 132 IXD=IXD+IXCS 130 IYD=IYD+IYCS 131 IYC=IDY-N*63 IXC=FLOAT(IYC)*CCT IRET=1 C BUILD 4020 LINE COMMAND in 3 HALF WORDS 199 IDXA=IXC/4 IDXB=IXC-ICXA*4 IXA=IXD/64 IXB=IXC-IXA*64 IDYA=IYC/4 IDYB=IYC-IDYA*4 IYA=IYC/64 IYB=IYC-IYA*64 IHW1=12288+IDXA*256+IDXB*16+IXA IHW2=IXB*256+32*((ISGNX+1)/2)+16*(-(ISGNY-1)/2)+ICYA C LOAD A 6 BYTE COMMAND INTO BUFFER 200 IBFR(IX)=IHW1 IBFR(IX+1)=IHW2 IBFR(IX+2)=IHW3 IX=IX+3 202 IF(ICODE.EQ.1).AND.((IX.LT.511))GO TO 210 204 IXM1=IX-1 WRITE(10,206) (IBFR(M), M=1,IXM1) 206 FORMAT(255A2,255A2) IX=1 IF(ICODE-4)210,208,210 208 END FILE 10 210 GO TO (999,126,132),IRET 999 RETURN END