@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            GRA021
~D10
~MMANCHESTER UNIVERSITY - CONFIDENTIAL
~
~
                                                          ISSUE 11~
~V9 -1
~P
~V9 1
~YGRA021
~V2 -6
~M~OGRAPHICS UTILITIES IMPLEMENTATION DESCRIPTION~
~
~M~OSection 2 Version 1~
~S1~OSection 2.1 Core Graphics Kernel~
~S1~O1. General Description~
~BThis module known as 'the Kernel' organises device control for the
Core Graphics System.  The kernel receives graphical commands for
"ideal" devices from the Core and translates them into procedure calls
on specific device drivers each of which exists as a separate module.
These calls form a device independent procedural interface which is
described later.  The Core Kernel supports five graphical output
devices:~
~
~MGenisco raster scan display (GRA111)
~NMotorola MC68000 raster scan display (GRA121)
~NBenson Pen plotter (GRA131)
~NHewlett Packard (HP) Pen Plotter (GRA141)
~NVIP Colour Graphics Interface (GRA161).
~S1~O2. Interfaces
~
~
Other modules used~
   Section GRA011 (Device independent Core)~
Hardware registers used~
   None.~
Interface procedures~
   DRIVER (INTEGER.ARRAY, REAL.ARRAY, SURF, ERROR)~
   DEFINE.DEV (DEV.NO, DEV.TYPE, PROCESS.NAME)OUTPUT.STREAM.NO~
Interface variables~
   None.~
~S1~O2.1 Hardware interface
~S1~O2.2 Software interface
~BThe software interface is provided by the following procedures.~
~
1) DRIVER (ADDR [$IN], ADDR [$RE], $IN, $IN)~
~BThis procedure forms the entire interface between the core and the
kernel.  The first parameter gives the address of a vector of integers
(IVEC), assumed to have the following format:~
~
IVEC [0] - total length of IVEC and RVEC~
IVEC [1] - op. code~
IVEC [2] - number of integer parameters~
IVEC [3] - number of real parameters~
IVEC [4] to IVEC [3 + IVEC [2]] - integer params~
~BThe second parameter is the address of a vector of reals (RVEC). This is assum
ed
to contain a number of real parameters, specified by IVEC [3], starting at
RVEC [0].~
~BThe opcodes and their respective functions are as follows.
Functions marked '*' are not implemented in the Kernel due to lack
of device capability. For example no intensity devices are available, nor
devices with the facility to store and manage picture segments.
~
~
   OP.CODE          FUNCTION~
~
    1              Polymarker~
    3              Polyline~
    5              Polygon~
    7              Text~
    8              Move~
    9              * Image transformation~
   10              * Highlighting~
   11              * Visibility~
   12              * Detectability~
   13              New frame~
   14              * Delete segment~
   15              * Delete all segments~
   16              * Set immediate visibility~
   17              * Make picture current~
   18              * Begin batch of updates~
   19              * End batch of updates~
   20              * Create retained segment~
   21              * Create temporary segment~
   22              * Close retained segment~
   23              * Close temporary segment~
   24              * Rename segment~
   25              Initialise device driver (and Kernel)~
   26              Terminate device driver~
   27              Initialise view surface~
   28              Terminate view surface~
   29              Set NDC Space~
   30              Inquire device capabilities~
   31              Set colour~
   32              Set background colour~
   33              * Set intensity~
   34              * Set background intensity~
   35              * Set colour index~
   36              * Set background index~
   37              * Define colour indices~
   38              * Define intensity indices~
   39              * Inquire colour indices~
   40              * Inquire intensity indices~
   41              Set line style~
   42              Inquire line style~
   43              Set line width~
   44              Set pen~
   45              * Inquire density~
   46              * Set character font~
   47              Set character size~
   48              * Set character space~
   49              * Set string rotation~
   50              Set character path~
   51              * Set character justification~
   52              * Set character extent~
   53              Set marker symbol~
   54              * Set pick id~
   55              * Set all attributes~
   56              * Set polygon edge style~
   57              * Set polygon interior style~
   58              * Set pixel array colours~
   59              * Set pixel array intensities~
   60              * Set pixel array indices~
   61              * Write raster colours~
   62              * Write raster intensity~
   63              * Write raster indices~
   64              * Read raster colours~
   65              * Read raster intensities~
   66              * Read raster indices~
   67              * Escape~
   68              * Inquire escape~
   69              * Alpha mode~
   70              * Set output unit~
~BP3 specifies the currently selected view surface and must always be
correctly set and passed with any call on DRIVER.  P4 is ignored.
~BThis procedure makes procedure calls on the currently selected
device drivers.  These calls conform to a device independent
procedural interface for device control.  In the following description
of this interface the letters "DEV" in each procedure name represent a
general device type.  In practise the actual procedure names for
specific devices are obtained from a datavec of procedure names
indexed by device type.~
~T% 30
~
~
1) DEV.INIT ()~IFor initialising a device.~
~
2) DEV.TERM ()~IFor deallocating a device.~
~
3) DEV.NEW.FRAME ()~IFor moving a to a new frame.~
~
4) DEV.LINE (X1, Y1, X2, Y2)~IFor drawing a line from X1, Y1 to
X2, Y2.~
~
5) DEV.TEXT (X1, Y1, STRING,~
             LENGTH)~IFor output of a text string of LENGTH
characters at X1, Y1.~
~
6) DEV.MARKER (X1, Y1,~
               MARKER)~IFor output of a marker at X1, Y1.~
~
7) DEV.ATTR (NUMBER)~IFor setting the attribute specified by
NUMBER as shown below.  The values of the attributes are
maintained as a set of variables and if the device is
capable of implementing the specified attribute the action
taken will be determined by the appropriate variable.~
~
~T% 10 30
~
ATTRIBUTE%DESCRIPTION~
%1%set line style~
%2%set line width~
%3%set character size~
%4%set string rotation~
%5%set charater font~
%6%set pens~
%7%set colour~
%8%set colour index~
%9%set intensity~
%10%set marker symbol~
%11%set polygon edge style~
%12%set polygon interior style~
%13%set segment highlighting~
%14%set segment visibility~
%15%set segment detectability~
%16%set image transformation~
~
~T% 30
~
8) DEV.REPORT (INTEGER.ARRAY,~
               REAL.ARRAY)~IFor obtaining a list of a device's attributes.~
~
~
2) DEFINE.DEV ($IN, $AD [$LO8], $LO64)I
~BThis defines a viewsurface number (P1) to be of device type P3 (see
below) and defines an output stream returned as the result to process P2 if spec
ified.
P3 will be irrelevant for devices driven by system commands
(e.g. Genisco) but will be used for devices controlled via a process.
Device types currently catered for are~
~3
~T% 10
~
%KERNEL~
%GENISCO~
%BENSON       (Benson Plotter)~
%MOTOROLA     (Raster Scan display)~
%HP           (Hewlett Packard Plotter)~
%VIP          (VIP Colour Graphics Interface)~
~0
~BDevice type KERNEL allows a viewsurface to be set up which looks
like another KERNEL interface.
~S1~O3. Implementation~
~S1~O3.1 Outline of Operation~
~BThe interface procedure DRIVER decodes core commands according to
OPCODE and breaks them down into two classes.
~
~T% 30
~
1) Control commands~IThese commands do not cause graphical output
to occur as they are mainly concerned with the
setting of global graphical attributes, such as colour.
~BAttributes are described in various forms and a set of variables is
maintained in this module to define those currently selected.  These
variables are imported as required by each device driver and it's
DEV.ATTR procedure uses them to implement the required attribute
either through the hardware, if the facility exists or by some
software technique.
~BFor readability and structure, the processing of control commands is
partitioned into five sections. Opcodes 1, 3, 5 and 7 are dealt with
separately. Those with a value >= 8 are converted into internal
values by subtrcting eight, putting them in the range 0 to 62. This new
value is then tested and the appropriate processing routine invoked as
follows:
~3
~
~
           OP.CODE  RANGE                  PROCESSING ROUTINE~
~
     (mapped)      (true value)~
~
      0..9             8..17               PROCESS.OPCODES.1~
     10..19           18..27               PROCESS.OPCODES.2~
     20..29           28..37               PROCESS.OPCODES.3~
     30..39           38..47               PROCESS.OPCODES.4~
     40..49           48..57               PROCESS.OPCODES.5~
~0
~
~
Within each processing routine, the opcode value is further mapped to
enable use of the ALTERNATIVE statement. For example, in
PROCESS.OPCODES.2, 10 is subtracted, yielding values in the range 0 to 9.
~
~
2) Graphical commands~IThese commands request initialisation and selection
of graphics devices, and graphical input and output operations. The kernel
calls the device driver procedures for the currently selected device.~
~BA mapping function is used to convert graphical command opcodes  into a contig
uous
number range to enable efficient use of the ALTERNATIVE statement. Specifically,
opcodes causing device output are mapped as follows :~
~
~
    OP.CODE from interface                 mapped op.code~
~
            1  (marker)                          0~
            3  (line)                            1~
            5  (polygon)                         2~
            7  (text)                            3~
            13 (new.frame)                       4~
            25 (init.surf)                       5~
            26 (term.surf)                       6~
~0
~BEach of these graphical commands is dealt with by a separate procedure.
~
~
   DEVICE.LINE (X.ARRAY, Y.ARRAY, N)~
   DEVICE.TEXT (X, Y, STRING, N)~
   DEVICE.MARKER (X.ARRAY, Y.ARRAY, N)~
   DEVICE.POLYGON (X.ARRAY, Y.ARRAY, N)~
   DEVICE.NEW.FRAME ()~
   DEVICE.INIT ()~
   DEVICE.TERM ()~
~
~
Each of these procedures generates a procedure call on the selected
device driver via the interface described earlier.
~BThe KERNEL option of device type is implemented as for any other
device but for the moment the procedures in its device driver are
nulls.
~S1~O3.2 Data Structures~
~T% 30
~
~
DEVICE.TYPE~IAn array with one entry per graphic
output device type in a MUSS system.  Each entry contains the
generic type of the device, such as GENISCO, BENSON.~
~
DEVICE.IDENTITY.TABLE (DIT)~IAn array with one entry for each defined
viewsurface.  Each entry has the following fields~
~
   DEV.TYPE~Ian index in the device type table.~
   DEV.SPN~Ithe SPN of the process linked to this
viewsurface.~
   DEV.PID~Ithe PID of the process linked to this
viewsurface.~
   SELECTED~Ia flag indicated that this device is selected.~
~
~
The following variables hold the current values of attributes required
by the device drivers.~
~
LINEWIDTH~IThe current LINEWIDTH in NDC coords.~
C.LINE.STYLE~IThe current LINESTYLE value.~
CHARSZ.WIDTH~IThe current character width value.~
CHARSZ.HEIGHT~IThe current character height value.~
PEN~IThe current PEN value.~
C.FONT~IThe current character FONT value.~
C.CHAR.PATH~IThe current CHARPATH value.~
C.MARKER~IThe current MARKER.SYMBOL value.~
C.LINE.INDEX~IThe current LINE.INDEX value.~
C.TEXT.INDEX~IThe current FILL.INDEX value.~
POLY.INT~IThe current polygon INTERIOR.STYLE value.~
POLY.EDGE~IThe current EDGE.STYLE value.~
BACK.INDEX~IThe current BACKGROUND.INDEX value.~
~
CP.X~IThe x-component of the current position.~
CP.Y~IThe y-component of the current position.~
CP.Z~IThe z-component of the current position.~
~
NDC.SCALE~IThe scaling factor used when converting NDC to device coordinates.~
~S1~O3.3 Special Notes~
~
   None.~
~S1~O4. Compile Jobs
~X%`
~S1~O4.1 Compile Job for VAX.
~
::BEGIN COMP PRIVATE KERNEL FOR VAX~
OPENDIR UTIL ITIES~
MUSL 0 KERNEL %405 64~
**TLSEG 0 0	%170000 -1 2~
**TLSEG 1 0 0 -3 0~
**TLSEG 2 0	%300000 -2 12~
**TLSEG 3 %10000 %110000 -3 12~
**TLLOAD 1 6~
**TLLOAD 2 7~
**TLLOAD 3 8~
*INFORM %2400;~
$PS KERNEL.INIT(); $PS GEN.INIT (); $PS BENSON.INIT ();~
$PS M68.INIT (); $PS HP.INIT (); $PS VIP.INIT ();~
$PS KERNEL.TERM(); $PS GEN.TERM (); $PS BENSON.TERM ();~
$PS M68.TERM (); $PS HP.TERM (); $PS VIP.TERM ();~
$PS KERNEL.NEW.FRAME (); $PS GEN.NEW.FRAME (); $PS BENSON.NEW.FRAME ();~
$PS M68.NEW.FRAME(); $PS HP.NEW.FRAME (); $PS VIP.NEW.FRAME ();~
$PS KERNEL.LINE($RE,$RE,$RE,$RE); $PS GEN.LINE ($RE, $RE, $RE, $RE);~
$PS BENSON.LINE ($RE, $RE, $RE, $RE); $PS M68.LINE ($RE, $RE, $RE, $RE);~
$PS HP.LINE ($RE, $RE, $RE, $RE); $PS VIP.LINE ($RE, $RE, $RE, $RE);~
$PS KERNEL.TEXT($RE, $RE, $AD [$LO8], $IN);~
$PS GEN.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS BENSON.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS M68.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS HP.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS VIP.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS KERNEL.MARKER ($RE, $RE, $LO8); $PS GEN.MARKER ($RE, $RE, $LO8);~
$PS BENSON.MARKER ($RE, $RE, $LO8); $PS M68.MARKER ($RE, $RE, $LO8);~
$PS HP.MARKER ($RE, $RE, $LO8); $PS VIP.MARKER ($RE, $RE, $LO8);~
$PS KERNEL.ATTR ($IN); $PS GEN.ATTR ($IN); $PS BENSON.ATTR ($IN);~
$PS M68.ATTR ($IN); $PS HP.ATTR ($IN); $PS VIP.ATTR ($IN);~
$PS KERNEL.REPORT ($AD [$RE], $AD [$IN32]);~
$PS GEN.REPORT ($AD [$RE], $AD [$IN32]);~
$PS BENSON.REPORT ($AD [$RE], $AD [$IN32]);~
$PS M68.REPORT ($AD [$RE], $AD [$IN32]);~
$PS HP.REPORT ($AD [$RE], $AD [$IN32]);~
$PS VIP.REPORT ($AD [$RE], $AD [$IN32]);~
MODULE (DEV.INIT, DEV.TERM, DEV.NEW.FRAME, DEV.LINE,~
   DEV.TEXT, DEV.MARKER, DEV.ATTR, DEV.REPORT, DEV.NAME, DRIVE.PROCESS, DEVS,~
   DEV.INIT.PS,DEV.TERM.PS,DEV.NEW.FRAME.PS,DEV.LINE.PS,~
   DEV.TEXT.PS,DEV.MARKER.PS,DEV.ATTR.PS,DEV.REPORT.PS);~
$LI DEVS = 6;~
-> ROUND;
*GLOBAL 1;
$DA DEV.NAME ($LO64)~
"KER"~
"GEN"~
"BEN"~
"MOT"~
"HPP"~
"VIP"~
END~
$DA DRIVE.PROCESS($IN32)~
%200~
0~
%200~
0~
%200~
%8300~
END~
$PS DEV.INIT.PS (); $PS DEV.TERMPS ();~
$PS DEV.NEW.FRAME.PS ();~
$PS DEV.LINE.PS ($RE, $RE, $RE, $RE);~
$PS DEV.TEXT.PS ($RE, $RE, $AD [$LO8], $IN);~
$PS DEV.MARKER.PS ($RE, $RE, $LO8);~
$PS DEV.ATTR.PS ($IN);
$PS DEV.REPORT.PS ($AD [$RE], $AD [$IN32]);~
$DA DEV.INIT ($AD DEV.INIT.PS)~
KERNEL.INIT~
GEN.INIT~
BENSON.INIT~
M68.INIT~
HP.INIT~
VIP.INIT~
END
$DA DEV.TERM ($AD DEV.TERM.PS)~
KERNEL.TERM~
GEN.TERM~
BENSON.TERM~
M68.TERM~
HP.TERM~
VIP.TERM~
END
$DA DEV.NEW.FRAME ($AD DEV.NEW.FRAME.PS)~
KERNEL.NEW.FRAME~
GEN.NEW.FRAME~
BENSON.NEW.FRAME~
M68.NEW.FRAME~
HP.NEW.FRAME~
VIP.NEW.FRAME~
END
$DA DEV.LINE ($AD DEV.LINE.PS)~
KERNEL.LINE~
GEN.LINE~
BENSON.LINE~
M68.LINE~
HP.LINE~
VIP.LINE~
END~
$DA DEV.TEXT ($AD DEV.TEXT.PS)~
KERNEL.TEXT~
GEN.TEXT~
BENSON.TEXT~
M68.TEXT~
HP.TEXT~
VIP.TEXT~
END~
$DA DEV.MARKER ($AD DEV.MARKER.PS)~
KERNEL.MARKER~
GEN.MARKER~
BENSON.MARKER~
M68.MARKER~
HP.MARKER~
VIP.MARKER~
END~
$DA DEV.ATTR ($AD DEV.ATTR.PS)~
KERNEL.ATTR~
GEN.ATTR~
BENSON.ATTR~
M68.ATTR~
HP.ATTR~
VIP.ATTR~
END~
$DA DEV.REPORT ($AD DEV.REPORT.PS)~
KERNEL.REPORT~
GEN.REPORT~
BENSON.REPORT~
M68.REPORT~
HP.REPORT~
VIP.REPORT~
END;~
*GLOBAL 0;
ROUND:
*END~
FLIP MU6S:GRA021 1~
GRA02~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA111 1~
GRA11~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA121 1~
GRA12~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA131 1~
GRA13~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA141 1~
GRA14~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA151 1~
GRA15~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA161 1~
GRA16~
DI 4 0~
MUSL 0 0 %800~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
STOP~
::END COMP~
~
~
~

~S1~O4.2 Cross Compile Job.~
~
~
::BEGIN CROSS COMPILE THE KERNEL~
DO 0 KRN\?LOG %200 %20000~
LIB MTLX\~
LIB MSLX~
LIB L2X\~
LIB LDIR\?~
OPENDIR MUSMC~
MUSL 0 BKRN\? %405 64          *FOR MC3**FOR MC7*~
MUSL 0 BKRN\? %705 64          *FOR MC5**FOR MC5G*~
**TLSEG 0 0 %FFFFFF -1 2      *FOR MC3*~
**TLSEG 0 0 %280000 -1 2      *FOR MC5*~
**TLSEG 0 0 %FFFFFF -1 2      *FOR MC5G*~
**TLSEG 0 0 %FFFFFF -1 2      *FOR MC7*~
**TLSEG 1 0 0 -3 0~
**TLSEG 2 0 %300000 -2 12~
**TLSEG 3 %10000 %110000 -3 12      *FOR MC3*~
**TLSEG 3 %10000 %F80000 -3 12      *FOR MC5*~
**TLSEG 3 %10000 %FFFFFF -3 12      *FOR MC5G*~
**TLSEG 3 %10000 %FFFFFF -3 12      *FOR MC7*~
**TLLOAD 1 6~
**TLLOAD 2 7~
**TLLOAD 3 8~
*INFORM %2400;~
$PS KERNEL.INIT(); $PS GEN.INIT (); $PS BENSON.INIT ();~
$PS M68.INIT (); $PS HP.INIT (); $PS VIP.INIT ();~
$PS KERNEL.TERM(); $PS GEN.TERM (); $PS BENSON.TERM ();~
$PS M68.TERM (); $PS HP.TERM (); $PS VIP.TERM ();~
$PS KERNEL.NEW.FRAME (); $PS GEN.NEW.FRAME (); $PS BENSON.NEW.FRAME ();~
$PS M68.NEW.FRAME(); $PS HP.NEW.FRAME (); $PS VIP.NEW.FRAME ();~
$PS KERNEL.LINE($RE,$RE,$RE,$RE); $PS GEN.LINE ($RE, $RE, $RE, $RE);~
$PS BENSON.LINE ($RE, $RE, $RE, $RE); $PS M68.LINE ($RE, $RE, $RE, $RE);~
$PS HP.LINE ($RE, $RE, $RE, $RE); $PS VIP.LINE ($RE, $RE, $RE, $RE);~
$PS KERNEL.TEXT($RE, $RE, $AD [$LO8], $IN);~
$PS GEN.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS BENSON.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS M68.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS HP.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS VIP.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS KERNEL.MARKER ($RE, $RE, $LO8); $PS GEN.MARKER ($RE, $RE, $LO8);~
$PS BENSON.MARKER ($RE, $RE, $LO8); $PS M68.MARKER ($RE, $RE, $LO8);~
$PS HP.MARKER ($RE, $RE, $LO8); $PS VIP.MARKER ($RE, $RE, $LO8);~
$PS KERNEL.ATTR ($IN); $PS GEN.ATTR ($IN); $PS BENSON.ATTR ($IN);~
$PS M68.ATTR ($IN); $PS HP.ATTR ($IN); $PS VIP.ATTR ($IN);~
$PS KERNEL.REPORT ($AD [$RE], $AD [$IN32]);~
$PS GEN.REPORT ($AD [$RE], $AD [$IN32]);~
$PS BENSON.REPORT ($AD [$RE], $AD [$IN32]);~
$PS M68.REPORT ($AD [$RE], $AD [$IN32]);~
$PS HP.REPORT ($AD [$RE], $AD [$IN32]);~
$PS VIP.REPORT ($AD [$RE], $AD [$IN32]);~
MODULE (DEV.INIT, DEV.TERM, DEV.NEW.FRAME, DEV.LINE,~
   DEV.TEXT, DEV.MARKER, DEV.ATTR, DEV.REPORT, DEV.NAME, DRIVE.PROCESS, DEVS,~
   DEV.INIT.PS,DEV.TERM.PS,DEV.NEW.FRAME.PS,DEV.LINE.PS,~
   DEV.TEXT.PS,DEV.MARKER.PS,DEV.ATTR.PS,DEV.REPORT.PS);~
$LI DEVS = 6;~
-> ROUND;
*GLOBAL 1;
$DA DEV.NAME ($LO64)~
"KER"~
"GEN"~
"BEN"~
"MOT"~
"HPP"~
"VIP"~
END~
$DA DRIVE.PROCESS($IN32)~
%200~
0~
%200~
0~
%200~
%8300~
END~
$PS DEV.INIT.PS (); $PS DEV.TERMPS ();~
$PS DEV.NEW.FRAME.PS ();~
$PS DEV.LINE.PS ($RE, $RE, $RE, $RE);~
$PS DEV.TEXT.PS ($RE, $RE, $AD [$LO8], $IN);~
$PS DEV.MARKER.PS ($RE, $RE, $LO8);~
$PS DEV.ATTR.PS ($IN);
$PS DEV.REPORT.PS ($AD [$RE], $AD [$IN32]);~
$DA DEV.INIT ($AD DEV.INIT.PS)~
KERNEL.INIT~
GEN.INIT~
BENSON.INIT~
M68.INIT~
HP.INIT~
VIP.INIT~
END
$DA DEV.TERM ($AD DEV.TERM.PS)~
KERNEL.TERM~
GEN.TERM~
BENSON.TERM~
M68.TERM~
HP.TERM~
VIP.TERM~
END
$DA DEV.NEW.FRAME ($AD DEV.NEW.FRAME.PS)~
KERNEL.NEW.FRAME~
GEN.NEW.FRAME~
BENSON.NEW.FRAME~
M68.NEW.FRAME~
HP.NEW.FRAME~
VIP.NEW.FRAME~
END
$DA DEV.LINE ($AD DEV.LINE.PS)~
KERNEL.LINE~
GEN.LINE~
BENSON.LINE~
M68.LINE~
HP.LINE~
VIP.LINE~
END~
$DA DEV.TEXT ($AD DEV.TEXT.PS)~
KERNEL.TEXT~
GEN.TEXT~
BENSON.TEXT~
M68.TEXT~
HP.TEXT~
VIP.TEXT~
END~
$DA DEV.MARKER ($AD DEV.MARKER.PS)~
KERNEL.MARKER~
GEN.MARKER~
BENSON.MARKER~
M68.MARKER~
HP.MARKER~
VIP.MARKER~
END~
$DA DEV.ATTR ($AD DEV.ATTR.PS)~
KERNEL.ATTR~
GEN.ATTR~
BENSON.ATTR~
M68.ATTR~
HP.ATTR~
VIP.ATTR~
END~
$DA DEV.REPORT ($AD DEV.REPORT.PS)~
KERNEL.REPORT~
GEN.REPORT~
BENSON.REPORT~
M68.REPORT~
HP.REPORT~
VIP.REPORT~
END;~
*GLOBAL 0;
ROUND:
*END~
FLIP MU6S:GRA021 1~
GRA02~
DI 4 0~
MUSL 0 0 MSLMMODE~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA111 1~
GRA11~
DI 4 0~
MUSL 0 0 MSLMMODE~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA121 1~
GRA12~
DI 4 0~
MUSL 0 0 MSLMMODE~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA131 1~
GRA13~
DI 4 0~
MUSL 0 0 MSLMMODE~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA141 1~
GRA14~
DI 4 0~
MUSL 0 0 MSLMMODE~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA151 1~
GRA15~
DI 4 0~
MUSL 0 0 MSLMMODE~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP MU6S:GRA161 1~
GRA16~
DI 4 0~
MUSL 0 0 MSLEMODE~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
STOP~
::END CROSS COMPILE~
~Y
~V9 -1
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H               GRA021
~V9 -1
~F
@TITLE GRA02(1,11)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
GRA02 MASTER
@BOX 2.0
@BOX 3.0
@BOX 4.0
PROCEDURES IN MODULE :
   DRIVER
   DEFINE DEVICE
@BOX 5.0
@BOX 6.0
END
@BOX 1.1
#GRA02/1
MODULE (DRIVER,DEF.DEV,DEBUG,CC.IND,C.RED,C.BLUE,C.GREEN,
   C.LINE.INDEX,C.LINE.STYLE,C.TEXT.INDEX,C.CHARPATH,C.FONT,
   NDC.WIDTH,NDC.HEIGHT,NDC.SCALE,PW0,PW1,PW2,PW3,PW4,PW5,PW6,
   SYS14.SEG.SIZE,GR.MAPPED.SEG,PTR,
   BLOCK.NO,OLD.SEG.NO,OLD.OUTPUT.STREAM,C.COLOUR,PEN,TXSIN,TXCOS,PLT.X,PLT.Y,
   RES.VERT,RES.HORIZ,CHARSZ.WIDTH,CHARSZ.HEIGHT,INTENSITY, C.LINEWIDTH, C.MARKE
R,
   FIRST.DD, A4, A4Q, LANSP, VP.XMIN,VP.YMIN,VP.XMAX,VP.YMAX,
   A4W.NDC, A4H.NDC, WNDW.XMIN,WNDW.YMIN,WNDW.XMAX,WNDW.YMAX);
@BOX 2.1
*GLOBAL 6;
$AD PW0, PW1, PW2, PW3, PW4, PW5, PW6;
$LO64 PWW0, PWW1, PWW2, PWW3, PWW4;
*GLOBAL 7;
$LI/$RE A4W =21.0, A4H =29.7;
$LI/$IN32 NONE=-1, INIT.VALUE=3, TERM.VALUE=4;
$LI/$IN32 SYS14.SEG.SIZE = %10000, GR.MAPPED.SEG = 0;
$IN32 PTR, BLOCK.NO, OLD.SEG.NO, PICK.ID,CUR.OUT;
$IN32 C.COLOUR, COLOR.INDEX.TYPE,COLOR.INDEX,INTEN.TYPE;
$IN32 C.DEV, OLD.OUTPUT.STREAM,CC.IND,C.RED,C.BLUE,C.GREEN;
$IN32 BACK.INDEX, C.LINESTYLE, PEN, C.FONT, POLY.EDGE, POLY.INT,
    C.LINE.INDEX, C.TEXT.INDEX, C.CHARPATH ;
$RE INTENSITY, VP.XMIN,VP.YMIN,VP.XMAX,VP.YMAX;
$RE WNDW.XMIN, WNDW.YMIN, WNDW.XMAX, WNDW.YMAX, LINEWIDTH;
$RE A4W.NDC, A4H.NDC, NDC.SCALE, TX.SIN, TX.COS, PLT.X, PLT.Y;
$LI / $LO8 DASHED = 2, CR = %0D, LF = %0A;
$IN32 MAX.INDEX, SEG.NAM, HILIGHT, VISIB, DETECT;
$RE RES.VERT, RES.HORIZ, SX,SY,SZ,TX,TY,TZ,AX,AY,AZ;
$LO8 [100] STRING;
$RE X.CP, Y.CP, Z.CP,  COL1, COL2, COL3;
$RE C.LINEWIDTH, CHARSZ.WIDTH, CHARSZ.HEIGHT, CHAR.ROT, NDC.WIDTH, NDC.HEIGHT;
$IN32 C.MARKER, FIRST.DD,A4,A4Q,  LANSP, SELECTED.DEVICE,SELECTED.SURFACE;
$IN32 [DEVS] D.INIT;
TYPE DEV.ID.TYPE IS
            $IN32 DEV.NO, DEV.SPN, DEV.PID, D.TYPE, D.MODE, OSTR
            $LO8 SELECTED;
DEV.ID.TYPE [DEVS] DEV.ID;
*GLOBAL 0;
@BOX 3.1
@BOX 4.1
LSPEC DEBUG (ADDR [$IN32], ADDR [$RE], $IN, $IN);
LSPEC DRIVER (ADDR [$IN32], ADDR [$RE], $IN, $IN);
LSPEC DEF.DEV($IN32, $AD[$LO8], $LO64)/$IN32;
::LSPEC INIT.CORE.STR ($AD[$LO8], $LO64)/$IN32;
::LSPEC A4.FRAME ($IN32, $IN32);
::LSPEC A4.FRAME1 ($IN32, $IN32, $IN32, $IN32);
:: LSPEC AQ.FRAME ($IN32, $IN32);
::LSPEC TERM.STR ();
::LSPEC NEW.FRAME ();  :: For DRAW command
::LSPEC LINE.ABS.2 ($RE, $RE); :: For DRAW temporarily
::LSPEC LINE.REL.2 ($RE, $RE); :: For DRAW temporarily
::LSPEC MOVE.ABS.2 ($RE, $RE); :: For DRAW temporarily
::LSPEC MOVE.REL.2 ($RE, $RE); :: For DRAW temporarily
::LSPEC TEXT ($AD [$LO8], $IN32); :: For DRAW temporarily
::LSPEC SET.CHAR.SIZE($RE, $RE); :: For DRAW temporarily
#GRA02.0
#GRA02.1
#GRA02.2
::#GRA02.3
::#GRA02.4
::#GRA02.4.1
::#GRA02.6
::#GRA02.7
::#GRA02.8
::#GRA02.9
::#GRA02.10
::#GRA02.11
::#GRA02.12
::#GRA02.13
@BOX 5.1
@BOX 6.1
*END
@END
@TITLE GRA02/1(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
EXTERNAL SPECIFICATION
@BOX 2.0
LSPEC & PSPEC
@BOX 3.0
END
@BOX 1.1
::EXTERNAL SPEC
@BOX 2.1
::$LS INIT ($AD[$IN], $AD[$IN], $AD[$IN])/$IN16;
::$LS TERM ()/$IN16;
::$LS NITSRF ($AD[$IN], $AD[$IN], $AD[$IN])/$IN16;
::$LS TRMSRF ($AD[$IN])/$IN16;
::$LS SELSRF ($AD[$IN])/$IN16;
::$LS DELSRF ($AD[$IN])/$IN16;
::$LS SWINDO ($AD[$RE], $AD[$RE], $AD[$RE], $AD[$RE])/$IN16;
::$LS SNDCS2 ($AD[$RE],$AD[$RE])/$IN16;
::$LS SVPRT2 ($AD[$RE], $AD[$RE], $AD[$RE], $AD[$RE])/$IN16;
::$LS SCHPTH ($AD[$IN])/$IN16;
::$LS CRRSEG ($AD[$IN32])/$IN16;
::$LS CLRSEG ()/$IN16;
::$LS CRTSEG ()/$IN16;
::$LS CLTSEG ()/$IN16;
::$LS NEWFRM ()/$IN16;
::$LS LINA2 ($AD[$RE], $AD[$RE])/$IN16;
::$LS LINR2 ($AD[$RE], $AD[$RE])/$IN16;
::$LS MOVA2 ($AD[$RE], $AD[$RE])/$IN16;
::$LS MOVR2 ($AD[$RE], $AD[$RE])/$IN16;
::$LS TEXTT ($AD[$LO8], $IN, $AD[$IN])/$IN16;
::$LS SCHSIZ ($AD[$RE], $AD[$RE])/$IN16;
::$LS SCHPRE ($AD[$IN])/$IN16;
::$LS SNDCS3 ($AD[$RE], $AD[$RE], $AD[$RE])/$IN16;
::$LS SVPRT3 ($AD[$RE],$AD[$RE],$AD[$RE],$AD[$RE],$AD[$RE],$AD[$RE])/$IN16;
::$LS MNTOW3 ($AD[$RE],$AD[$RE],$AD[$RE],$AD[$RE],$AD[$RE],$AD[$RE])/$IN16;
::$LS MOVA3 ($AD[$RE], $AD[$RE], $AD[$RE])/$IN16;
::$LS LINA3 ($AD[$RE], $AD[$RE], $AD[$RE])/$IN16;

LSPEC CREATE.SEGMENT ($IN, $AD);
LSPEC MAP ($IN, $IN, $IN);
LSPEC CURRENT.OUTPUT () / $IN;
LSPEC DEFINE.OUTPUT ($IN, ADDR [$LO8], $IN32, $IN32) / $IN;
LSPEC SELECT.OUTPUT ($IN);
LSPEC OUTI($IN32, $IN);
LSPEC OUTREAL($RE64,$IN,$IN);
LSPEC NEWLINES($IN);
LSPEC CAPTION ($AD[$LO8]);
LSPEC BREAK.OUTPUT ($IN);
LSPEC O.SIZE ()/ $IN32;
LSPEC END.OUTPUT ($IN, $IN);

$PS DEV.INIT.PS();
$PS DEV.TERM.PS();
$PS DEV.NEWFRAME.PS();
$PS DEV.LINE.PS($RE,$RE,$RE,$RE);
$PS DEV.TEXT.PS($RE,$RE,$AD[$LO8],$IN);
$PS DEV.MARKER.PS($RE,$RE,$LO8);
$PS DEV.ATTR.PS($IN);
$PS DEV.REPORT.PS($AD[$RE], $AD[$IN32]);
$IM $LI DEVS;
$LO64 [DEVS] DEV.NAME;
$IN32 [DEVS] DRIVE.PROCESS;
$AD DEV.INIT.PS [DEVS] DEV.INIT;
$AD DEV.TERM.PS [DEVS] DEV.TERM;
$AD DEV.NEWFRAME.PS [DEVS] DEV.NEWFRAME;
$AD DEV.LINE.PS [DEVS] DEV.LINE;
$AD DEV.TEXT.PS [DEVS] DEV.TEXT;
$AD DEV.MARKER.PS [DEVS] DEV.MARKER;
$AD DEV.ATTR.PS [DEVS] DEV.ATTR;
$AD DEV.REPORT.PS [DEVS] DEV.REPORT;
@BOX 3.1
@END
@TITLE GRA02.0(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.1
PROC DEBUG (PARRAY, RARRAY, SEL.SURF, DUM1);
$IN I;
@BOX 2.1
CAPTION (%"PARRAY LENGTH - ");
OUT.I (PARRAY ^[0], 0); NEWLINES (1);
CAPTION (%"OPCODE - ");
OUT.I (PARRAY ^[1], 0); NEWLINES (1);
CAPTION (%"NO. OF INTEGER PARAMS - ");
OUT.I (PARRAY ^[2], 0); NEWLINES (1);
CAPTION (%"NO. OF REAL PARAMS - ");
OUT.I (PARRAY ^[3], 0); NEWLINES (1);
CAPTION (%"INTEGER PARAMETERS -- "); NEWLINES (2);
FOR I < PARRAY ^[2] DO
   OUT.I (PARRAY ^[I + 4], 0); NEWLINES (1);
OD
NEWLINES(2);
FOR I<PARRAY^[3] DO
   OUTREAL(RARRAY^[I],7,2);
   NEWLINES(1);
OD;
@BOX 3.1
END
@END
@TITLE GRA02.1(1,10)
@COL 1S-7R-6R-2T-3R-4F
@COL 5R
@ROW 3-5
@FLOW 1-7-6-2YES-5-4
@FLOW 2NO-3-4
@BOX 1.0
DRIVER (INTEGER.VECTOR, REAL.VECTOR)
@BOX 2.0
IS OP-CODE A DEVICE DRVER COMMAND ?
@BOX 3.0
PROCESS ATRIBUTE COMMAND
[GRA02.3]
@BOX 4.0
END
@BOX 5.0
PROCESS DEVICE DRIVER COMMAND
[GRA02.2]
@BOX 6.0
MAP OP.CODE TO INTERNAL VALUE
@BOX 7.0
INTERNEL PROCS
@BOX 1.1
PROC DRIVER (I.VEC, R.VEC, SEL.SURF, DUM1);
DATAVEC OP.CODE.MAP ($LO8)
8 0 8 1 8 2 8 3 8 8 99 99 99 4
99 99 99 99 99 99 99 99 99 99 99
5 6 7
END
$ADDEV.INIT.PS DEV.INIT.P;
$ADDEV.TERM.PS DEV.TERM.P;
$ADDEV.NEWFRAME.PS DEV.NEWFRAME.P;
$ADDEV.LINE.PS DEV.LINE.P;
$ADDEV.TEXT.PS DEV.TEXT.P;
$ADDEV.MARKER.PS DEV.MARKER.P;
$ADDEV.ATTR.PS DEV.ATTR.P;
$ADDEV.REPORT.PS DEV.REPORT.P;
$IN32 OP.CODE, I;
@BOX 2.1
IF OP.CODE =< 8
@BOX 3.1
#GRA02.1.1
@BOX 4.1
END
@BOX 5.1
ALTERNATIVE OP.CODE FROM
   DEVICE.MARKER (RVEC, IVEC);
   DEVICE.LINE (RVEC, IVEC);
   DEVICE.POLYGON (RVEC, IVEC);
   DEVICE.TEXT (RVEC, IVEC);
   DEVICE.NEW.FRAME ();
   IF IVEC ^[2] = 2 THEN
    I.VEC^[5] =>I;
    DEVICE.INIT (I);
   ELSE INIT.KERNEL ()
   FI;
   BEGIN   END;
   BEGIN
     I.VEC^[6]=>I;
     I.VEC^[4]=>D.TYPE OF DEV.ID[I];
     I.VEC^[5]=>D.MODE OF DEV.ID[I];
   END;
   BEGIN  END
END
@BOX 6.1
IVEC ^[1] => OP.CODE;
::OUTI (OP.CODE, 8); NEWLINES (1);
IF OP.CODE < 27 THEN
   IF OP.CODE.MAP [OP.CODE] /= 99 THEN
      OP.CODE.MAP [OP.CODE] => OP.CODE
   FI
FI;
@BOX 7.1
PSPEC INIT.KERNEL ();
PSPEC GET.STRING ($AD[$RE],$AD[$IN32])/$IN;
PSPEC DEVICE.MARKER ($AD[$RE],$AD[$IN32]);
PSPEC DEVICE.LINE ($AD[$RE],$AD[$IN32]);
PSPEC DEVICE.POLYGON ($AD[$RE],$AD[$IN32]);
PSPEC DEVICE.TEXT ($AD[$RE],$AD[$IN32]);
PSPEC DEVICE.NEWFRAME ();
PSPEC DEVICE.INIT ($IN32);
PSPEC DEVICE.TERM ($AD[$IN32]);
PSPEC PROCESS.OPCODES.1 ($AD[$RE],$AD[$IN32],$IN32);
PSPEC PROCESS.OPCODES.2 ($AD[$RE],$AD[$IN32],$IN32);
PSPEC PROCESS.OPCODES.3 ($AD[$RE],$AD[$IN32],$IN32);
PSPEC PROCESS.OPCODES.4 ($AD[$RE],$AD[$IN32],$IN32);
PSPEC PROCESS.OPCODES.5 ($AD[$RE],$AD[$IN32],$IN32);
PSPEC DEVICE.SEL ($AD [$IN32]);
PSPEC DEVICE.DEL ($AD [$IN32]);
PSPEC FAULT($IN32,$IN32);
#GRA02.1.0
#GRA02.1.2
#GRA02.1.3
#GRA02.1.4
#GRA02.1.5
#GRA02.1.6
#GRA02.1.7
#GRA02.1.8
#GRA02.1.9
#GRA02.1.11
#GRA02.1.12
#GRA02.1.13
#GRA02.1.14
#GRA02.1.15
#GRA02.1.16
#GRA02.1.17
#GRA02.1.18
@END
@TITLE GRA02.1.0(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
INITIALISE KERNEL ()
@BOX 2.0
INITIALISE VARIABLES
@BOX 3.0
SET UP DEVICE TABLE
@BOX 4.0
END
@BOX 1.1
PROC INIT.KERNEL ;
 $IN32 I;
@BOX 2.1
1.0 => NDC.HEIGHT => NDC.WIDTH;
0.0025 => CHARSZ.WIDTH => CHARSZ.HEIGHT;
1 => BACK.INDEX => C.LINESTYLE => PEN => C.FONT => POLY.EDGE
  => POLY.INT => C.LINE.INDEX => C.TEXT.INDEX => C.CHARPATH;
0.0 => X.CP => Y.CP;
NONE => SELECTED.DEVICE => SELECTED.SURFACE;
@BOX 3.1
FOR I<DEVS DO
   TERM.VALUE=> D.INIT[I];
   SELECT DEV.ID [I];
    0 =>SELECTED;
    IF OSTR =<0 THEN
        CURRENT.OUTPUT() =>OSTR;
    FI
OD;
@BOX 4.1
END
@END
@TITLE GRA02.1.1(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
::PROCESS ATTRIBUTE COMMANDS
@BOX 2.0
ADJUST OP.CODE
@BOX 3.0
PROCESS OPCODE
@BOX 4.0
END
@BOX 1.1
BEGIN
@BOX 2.1
OP.CODE - 8 => OP.CODE;
@BOX 3.1
IF OP.CODE < 10 THEN
   PROCESS.OPCODES.1 (RVEC, IVEC, OPCODE)
ELSE
   IF OP.CODE < 20 THEN
      PROCESS.OPCODES.2 (RVEC, IVEC, OPCODE)
   ELSE
      IF OP.CODE < 30 THEN
         PROCESS.OPCODES.3 (RVEC, IVEC, OP.CODE)
      ELSE
         IF OP.CODE < 40 THEN
            PROCESS.OPCODES.4 (RVEC, IVEC, OP.CODE)
         ELSE
            PROCESS.OPCODES.5 (RVEC, IVEC, OP.CODE)
         FI
      FI
   FI
FI;
@BOX 4.1
END
@END
@TITLE GRA02.1.2(1,10)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
GET STRING (RVEC, IVEC) LENGTH
@BOX 2.0
OBTAIN WORD AND CHARACTER COUNT FROM IVEC
@BOX 3.0
DECODE ALL BUT THE LAST WORD AND STORE
THE CHARACTERS IN THE GLOBAL "STRING"
@BOX 4.0
DECODE THE FINAL WORD
@BOX 5.0
END
@BOX 1.1
PROC GET.STRING (RVEC, IVEC);
$IN32 EXTRA, I, NO.WORDS, NO.CHARS, PTR;
$IN32 WORD;
$LO32 MASK;
@BOX 2.1
IVEC ^[2] - 1 => NO.WORDS;
IVEC ^[4] => NO.CHARS=>GET.STRING;
NO.WORDS * 4 - NO.CHARS => EXTRA;
-1 => PTR;
FOR I< NO.WORDS - 1 DO
   IVEC ^[I + 5] => WORD;
   WORD & %FF000000->>24 => STRING [1 +> PTR];
   WORD & %00FF0000->>16 => STRING [1 +> PTR];
   WORD & %0000FF00->>8 => STRING [1 +> PTR];
   WORD & %000000FF => STRING [1 +> PTR];
OD;
@BOX 3.1
     4-EXTRA=>EXTRA;
IVEC ^[NO.WORDS +4] => WORD;
%FF000000 => MASK;
FOR EXTRA DO
   WORD & MASK->>24 => STRING [1 +> PTR];
   WORD <<- 8 => WORD
OD;
@BOX 4.1
RVEC ^[0] => X.CP;
RVEC ^[1] => Y.CP;
@BOX 5.1
END
@END
@TITLE GRA02.1.3(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
DEVICE MARKER (RVEC, IVEC)
@BOX 2.0
DRAW EACH MARKER
@BOX 3.0
@BOX 4.0
END
@BOX 1.1
PROC DEVICE.MARKER (RVEC, IVEC);
DATAVEC MARKERS ($LO8)
".+*0X>_^#"
END
$IN32 I,J,  COUNT;
$RE X, Y;
$LO8 SYMBOL;
@BOX 2.1
-3 => I;
MARKERS [C.MARKER] => SYMBOL;
IVEC ^[4] /3 => COUNT;
FOR COUNT DO
   3 +> I;
   RVEC ^[I] => X => X.CP;
   RVEC ^[I + 1] => Y =>  Y.CP;
     DEV.NO OF DEV.ID[SELECTED.SURFACE -1] => J;
         DEV.MARKER [J] => DEV.MARKER.P;
         DEV.MARKER.P^ (X,Y,SYMBOL)
OD
@BOX 4.1
END
@END
@TITLE GRA02.1.4(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
DEVICE LINE (RVEC, IVEC)
@BOX 2.0
GET CP FROM RVEC
@BOX 3.0
DRAW EACH LINE FROM RVEC
@BOX 4.0
END
@BOX 1.1
PROC DEVICE.LINE (RVEC, IVEC);
$RE X0, Y0, X1, Y1;
$IN32 I, J;
@BOX 2.1
RVEC ^[0] => X0 => X.CP;
RVEC ^[1] => Y0 => Y.CP;
0 => I;
@BOX 3.1
FOR IVEC ^[3] / 3 - 1 DO
   3 +> I;
   RVEC ^[I] => X1;
   RVEC ^[I + 1] => Y1;
    DEV.NO OF DEV.ID [SELECTED.SURFACE-1] => J;
         DEV.LINE [J] => DEV.LINE.P;
         DEV.LINE.P^ (X0,Y0,X1,Y1);
X1 => X0 => X.CP;
Y1 => Y0 => Y.CP;
OD;
@BOX 4.1
END
@END
@TITLE GRA02.1.5(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
DEVICE POLYLINE (RVEC, IVEC)
@BOX 2.0
GET CP FROM RVEC
@BOX 3.0
DRAW EACH LINE FROM RVEC
@BOX 4.0
END
@BOX 1.1
PROC DEVICE.POLYGON (RVEC, IVEC);
$RE X0, Y0, X1, Y1;
$IN32 I, J;
@BOX 2.1
RVEC ^[0] => X0 => X.CP;
IVEC ^[1] => Y0 => Y.CP;
0 => I;
@BOX 3.1
FOR IVEC ^[3] / 3 - 1 DO
   3 +> I;
   RVEC ^[I] => X1;
   RVEC ^[I + 1] => Y1;
    DEV.NO OF DEV.ID [SELECTED.SURFACE-1] =>J;
        DEV.LINE [J]=> DEV.LINE.P;
        DEV.LINE.P^ (X0,Y0,X1,Y1);
X1 => X0 => X.CP;
Y1 => Y0 => Y.CP;
OD;
@BOX 4.1
END
@END
@TITLE GRA02.1.6(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
DEVICE TEXT (RVEC, IVEC)
@BOX 2.0
GET TEXT STRING FROM RVEC
@BOX 3.0
DRAW STRING
@BOX 4.0
@BOX 1.1
PROC DEVICE.TEXT (RVEC, IVEC);
$IN32 LENGTH, I;
$AD [$LO8] PTR;
@BOX 2.1
GET.STRING (RVEC, IVEC) => LENGTH;
PART (^STRING, 0, LENGTH-1) =>PTR;
@BOX 3.1
    DEV.NO OF DEV.ID[SELECTED.SURFACE-1] =>I;
      DEV.TEXT [I] => DEV.TEXT.P;
      DEV.TEXT.P^ (X.CP,Y.CP, PTR, LENGTH);
@BOX 4.1
END
@END
@TITLE GRA02.1.7(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
DEVICE NEW FRAME ()
@BOX 2.0
SWITCH ON SELECTED DEVICE FOR NEW FRAME
@BOX 3.0
END
@BOX 1.1
PROC DEVICE.NEW.FRAME ;
$IN32 I;
$DA NULLHDR($LO8)
0 0
END
@BOX 2.1
DEV.NO OF DEV.ID[SELECTED.SURFACE-1] =>I;
DEV.NEWFRAME [I] => DEV.NEW.FRAME.P;
DEV.NEW.FRAME.P^ ();
::IF A4/=0 THEN
:: CLTSEG ();
::FI
IF DRIVE.PROCESS[SELECTED.DEVICE] = %200 THEN
   IF O.SIZE() - OPOS() < %8000 THEN
      BREAK.OUTPUT (-1);
      OUTHDR(^NULLHDR);
FI FI;
@BOX 3.1
END
@END
@TITLE GRA02.1.8(1,10)
@COL 1S-4T-8R-5F
@COL 7R
@ROW 8-7
@FLOW 1-4ILLEGAL-7-5
@FLOW 4LEGAL-8-5
@BOX 1.0
INITIALISE VIEW SURFACE (SURFACE)
@BOX 4.0
LEGAL SURFACE REQUESTED ?
@BOX 5.0
END
@BOX 7.0
ERROR
@BOX 8.0
INITIALISE THE VIEW SURFACE
@BOX 1.1
PROC DEVICE.INIT (SURFACE);
 $IN I, J;
@BOX 4.1
IF SURFACE <1 OR SURFACE > DEVS
@BOX 5.1
END
@BOX 7.1
FAULT (1, 7);
@BOX 8.1
SELECT DEV.ID [SURFACE-1];
    DEV.NO => I;
CURRENT.OUTPUT() => OLD.OUTPUT.STREAM;
OUTI(I,2); NEWLINES(1);
OUTI(OSTR,0); NEWLINES(1);
 IF OSTR /= OLD.OUTPUT.STREAM THEN
   SELECT.OUTPUT (OSTR);
 FI
DEV.INIT [I] => DEV.INIT.P;
 DEV.INIT.P ^();
DEV.ATTR [I] => DEV.ATTR.P;
DEV.ATTR.P^ (3);
IF OSTR /= OLD.OUTPUT.STREAM THEN
   SELECT.OUTPUT (OLD.OUTPUT.STREAM);
FI
INIT.VALUE => D.INIT [SURFACE-1] ;
@END
@TITLE GRA02.1.9(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TERMINATE VIEW SURFACE
@BOX 2.0
TERMINATE DEVICE
@BOX 3.0
END
@BOX 1.1
PROC DEVICE.TERM(IVEC);
   $IN32 I ,J, SELECTED.SURFACE;
@BOX 2.1
 IVEC^ [4] => SELECTED.SURFACE;
SELECT DEV.ID [SELECTED.SURFACE-1];
  DEV.NO => I;
IF OSTR /= OLD.OUTPUT.STREAM THEN
  SELECT.OUTPUT (OSTR);
FI
 DEV.TERM [I] => DEV.TERM.P;
 DEV.TERM.P^();
IF OSTR /= OLD.OUTPUT.STREAM THEN
  SELECT.OUTPUT (OLD.OUTPUT.STREAM);
FI;
IF OSTR > 0 THEN
   END.OUTPUT (OSTR, 0);
FI
TERM.VALUE => D.INIT [SELECTED.SURFACE-1];
@BOX 3.1
END
@END
@TITLE GRA02.1.11(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROCESS OPCODES 1 (RVEC, IVEC, OP.CODE)
@BOX 2.0
PROCESS OPCODES FROM 8 TO 17
@BOX 3.0
END
@BOX 1.1
PROC PROCESS.OPCODES.1 (RVEC, IVEC, OP.CODE);
   $IN32 I;
@BOX 2.1
DEV.NO OF DEV.ID[SELECTED.SURFACE-1] =>I;
IF OP.CODE< 5 THEN
   ALTERNATIVE OPCODE FROM
      BEGIN  RVEC ^[0] => X.CP;
         RVEC ^[1] => Y.CP;
         RVEC ^[2] => Z.CP;
      END;
      BEGIN IVEC ^[5] => SEG.NAM;
         RVEC ^[0] => SX; RVEC^[1] => SY;
         RVEC^[2] =>SZ; RVEC^[3] =>TX;
         RVEC^[4] =>TY; RVEC^[5] =>TZ;
         RVEC^[6] =>AX; RVEC^[7] =>AY;
         RVEC^[8] =>AZ;
      END;
      BEGIN IVEC^[5] =>SEGNAM;
         IVEC^[6] =>HILIGHT;
      END;
      BEGIN IVEC^[5] =>SEG.NAM;
         IVEC^[6] =>VISIB;
      END;
      BEGIN IVEC^[5] =>SEG.NAM;
         IVEC^[6] =>DETECT;
      END;
   END;
         DEV.ATTR [I] => DEV.ATTR.P;
         ALTERNATIVE OP.CODE FROM
            BEGIN    END;
            DEV.ATTR.P^(16);
            DEV.ATTR.P^(13);
            DEV.ATTR.P^(14);
            DEV.ATTR.P^(15);
         END;
FI
@BOX 3.1
END
@END
@TITLE GRA02.1.12(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROCESS OPCODES 2 (RVEC, IVEC, OP.CODE)
@BOX 2.0
PROCESS OPCODES FROM 18 TO 27
@BOX 3.0
END
@BOX 1.1
PROC PROCESS.OPCODES.2 (RVEC, IVEC, OP.CODE);
@BOX 2.1
@BOX 3.1
END
@END
@TITLE GRA02.1.13(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROCESS OPCODES 3 (RVEC, IVEC, OP.CODE)
@BOX 2.0
PROCESS OPCODES FROM 20 TO 29
@BOX 3.0
END
@BOX 1.1
PROC PROCESS.OPCODES.3 (RVEC, IVEC, OP.CODE);
$IN32 I;
@BOX 2.1
DEV.NO OF DEV.ID [SELECTED.SURFACE-1] =>I;
OP.CODE - 20 => OP.CODE;
ALTERNATIVE OP.CODE FROM
   DEVICE.TERM(IVEC); ::28 TRM:Term. Viewsurf.
   BEGIN
      RVEC ^[0] => NDC.WIDTH;
      RVEC ^[1] => NDC.HEIGHT;
   END       ::29
   BEGIN
      DEV.REPORT [DEVNO OF DEV.ID[IVEC^[4]-1]] => DEV.REPORT.P; ::28/7,83
      DEV.REPORT.P^(RVEC,IVEC);
   END       ::30
   BEGIN
      RVEC ^[0] => COL1;
      RVEC ^[1] => COL2;
      RVEC ^[2] => COL3;
      IVEC^[4] =>C.COLOUR;
         DEV.ATTR [I] => DEV.ATTR.P;
         DEV.ATTR.P^(7);
   END       ::31
   BEGIN END ::32
   BEGIN
      IVEC^[4] =>INTEN.TYPE;
      RVEC^[0] =>INTENSITY;
            DEV.ATTR [I] => DEV.ATTR.P;
            DEV.ATTR.P^(9);
   END       ::33
   BEGIN END ::34
   BEGIN
      IVEC^[4] => COLOR.INDEX.TYPE;
      IVEC^[5] => COLOR.INDEX =>C.LINE.INDEX;  ::21/7,83
            DEV.ATTR [I] => DEV.ATTR.P;
            DEV.ATTR.P^(8);
   END       ::35
   IVEC ^[4] => BACK.INDEX; ::36
   BEGIN END ::37
END
@BOX 3.1
END
@END
@TITLE GRA02.1.14(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
PROCESS OPCODES 4 (RVEC, IVEC, OP.CODE)
@BOX 2.0
ADJUST OP CODE VALUE
@BOX 3.0
PROCESS OPCODES FORM 38 TO 47
@BOX 4.0
END
@BOX 1.1
PROC PROCESS.OPCODES.4 (RVEC, IVEC, OP.CODE);
$IN32 I;
@BOX 2.1
OP.CODE - 30 => OP.CODE;
@BOX 3.1
ALTERNATIVE OP.CODE FROM
   BEGIN END ::38
   BEGIN END ::39
   BEGIN END ::40
   IVEC ^[4] => C.LINESTYLE; ::41
   BEGIN END ::42
   RVEC ^[0] => LINEWIDTH; ::43
   IVEC ^[4] => PEN; ::44
   BEGIN END ::45
   IVEC ^[4] => C.FONT; ::46
   BEGIN
      RVEC ^[0] => CHARSZ.WIDTH;
      RVEC ^[1] => CHARSZ.HEIGHT;
   END       ::47
END
   IF 3->OP.CODE >=0 THEN
    DEV.NO OF DEV.ID [SELECTED.SURFACE-1] =>I;
            DEV.ATTR [I] => DEV.ATTR.P;
            ALTERNATIVE OP.CODE FROM
               DEV.ATTR.P^ (1);
               BEGIN  END;
               DEV.ATTR.P^ (2);
               DEV.ATTR.P^ (6);
               BEGIN   END;
               DEV.ATTR.P^ (5);
               DEV.ATTR.P^ (3);
            END;
   FI
@BOX 4.1
END
@END
@TITLE GRA02.1.15(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
PROCESS OPCODES 5 (RVEC, IVEC, OP.CODE)
@BOX 2.0
ADJUST OPCODE VALUE
@BOX 3.0
PROCESS OPCODES 48 TO 57
@BOX 4.0
END
@BOX 1.1
PROC PROCESS.OPCODES.5 (RVEC, IVEC, OP.CODE);
$IN32  I;
@BOX 2.1
OP.CODE - 40 => OP.CODE;
@BOX 3.1
IF OP.CODE < 9 THEN
ALTERNATIVE OP.CODE FROM
   BEGIN END ::48
   RVEC ^[0] => CHAR.ROT;
  IVEC^ [4]=> C.CHAR.PATH;  ::50
   BEGIN END ::51
   BEGIN END ::52
   IVEC ^[4] => C.MARKER; ::53
   IVEC^[4] =>PICK.ID;    ::54
   BEGIN END ::55
   IVEC ^[4] => POLY.EDGE; ::56
   IVEC ^ [5] => POLY.INT; ::57
END
  DEV.NO OF DEV.ID [SELECTED.SURFACE-1] => I;
         DEV.ATTR [I] => DEV.ATTR.P;
         ALTERNATIVE OP.CODE FROM
            BEGIN  END;
            BEGIN END;
            DEV.ATTR.P^(4);
            BEGIN  END;
            BEGIN  END;
            DEV.ATTR.P^(10);
            DEV.ATTR.P^(17);
            BEGIN  END;
            DEV.ATTR.P^(11);
            DEV.ATTR.P^(12);
         END
ELSE
IF OP.CODE =33 THEN   ::81
  DEVICE.SEL (IVEC);
FI
IF OP.CODE =34 THEN   ::82
  DEVICE.DEL (IVEC);
FI
FI
@BOX 4.1
END
@END
@TITLE GRA02.1.16(1,10)
@COL 3R
@COL 1S-2R-4T-6T-7R-8F
@COL 5R
@ROW 3-6
@ROW 7-5
@FLOW 1-2-4VALID-6NO-7-8
@FLOW 4INVALID-3-8
@FLOW 6YES-5-8
@BOX 1.0
PROC SELECT DEVICE
@BOX 2.0
GET LOGICAL SURFACE NAME
@BOX 3.0
FAULT
@BOX 4.0
THE SURFACE VALID?
@BOX 5.0
FAULT
@BOX 6.0
THE DEVICE SELECTED ?
@BOX 7.0
RESERVE CURRENT STREAM &
SELECT THE DEST. STREAM
IF BATCH STREAM NEAR LIMIT THEN
BREAKOUTPUT AND SELECT NULL HEADER
@BOX 8.0
END
@BOX 1.1
PROC DEVICE.SEL (IARRAY);
$IN32 SURFACE;
$AD DEV.ATTR.PS DEV.ATTR.P;
$DA NULLHDR($LO8)
0 0
END
@BOX 2.1
IARRAY^ [4] => SURFACE;
@BOX 3.1
FAULT (1,7);
@BOX 4.1
IF SURFACE <1 OR SURFACE >DEVS
@BOX 5.1
FAULT (2,6);
@BOX 6.1
SELECT DEV.ID [SURFACE-1];
IF SELECTED = 1
@BOX 7.1
1 => SELECTED;
SURFACE => SELECTED.SURFACE;
DEV.NO => SELECTED.DEVICE;
IF OSTR/=CURRENT.OUTPUT() THEN
   CURRENT.OUTPUT()=>OLD.OUTPUT.STREAM;
   SELECT.OUTPUT (OSTR);
   IF DRIVE.PROCESS[SELECTED.DEVICE] = %200 THEN
      OUTHDR(^NULLHDR);
FI FI
@BOX 8.1
END
@END
@TITLE GRA02.1.17(1,10)
@COL 7R
@COL 1S-3T-4T-5R-6R-9F
@COL 8R
@ROW 4-8
@ROW 7-5
@FLOW 1-3VALID-4NO-5-6-9
@FLOW 3INVALID-8-6
@FLOW 4YES-7-6
@BOX 1.0
PROC DELETE DEVICE
@BOX 2.0
@BOX 3.0
IS DEVICE VALID ?
@BOX 4.0
IS DEVICE SELECTED ?
@BOX 5.0
DESLECT THE DEVICE
@BOX 6.0
RESUME THE ORIGINAL STREAM
@BOX 7.0
FAULT
@BOX 8.0
FAULT
@BOX 9.0
END
@BOX 1.1
PROC DEVICE.DEL (IARRAY);
   $IN32 SURFACE;
@BOX 3.1
IARRAY^ [4] => SURFACE;
IF SURFACE<1 OR SURFACE>DEVS
@BOX 4.1
SELECT DEV.ID [SURFACE-1];
 IF SELECTED /= 1
@BOX 6.1
IF OSTR /= OLD.OUTPUT.STREAM THEN
 SELECT.OUTPUT (OLD.OUTPUT.STREAM)
FI
@BOX 5.1
0 => SELECTED;
NONE => SELECTED.DEVICE;
NONE => SELECTED.SURFACE;
@BOX 7.1
FAULT (3,6);
@BOX 8.1
FAULT (1,7);
@BOX 9.1
END
@END
@TITLE GRA02.1.18(1,10)
@COL 1S-4R-2R-5R-3F
@FLOW 1-4-2-5-3
@BOX 1.0
PROC FAULT
@BOX 2.0
FAULT MESSAGE
@BOX 3.0
END
@BOX 4.0
RESERVE THE CURRENT STREAM PROPERLY
@BOX 5.0
RESUME THE ORIGINAL STREAM
@BOX 1.1
PROC FAULT (REASON, SEVERITY);
  $IN32 I, J;
@BOX 2.1
CAPTION (%"CORE ERROR");
ALTERNATIVE REASON FROM
  CAPTION (%"(0,0) NOTHING");
  CAPTION (%"(706,7) no output device is associated with the surface");
  CAPTION (%"(709,6) the specified view surface is already initialised");
  CAPTION (%"(711,6) the specified view surface is not selected ");
END;
CAPTION (%"$L");
@BOX 3.1
END
@BOX 4.1
 -1 =>J;
FOR I < DEVS DO
  IF DEV.NO OF DEV.ID [I] = SELECTED.DEVICE AND
     OSTR OF DEV.ID [I] /= OLD.OUTPUT.STREAM THEN
     SELECT.OUTPUT (OLD.OUTPUT.STREAM);
        I => J;
       -> OUT;
  FI
OD
 OUT:
@BOX 5.1
IF J /= -1 THEN
  SELECT.OUTPUT (OSTR OF DEV.ID [J]);
FI;
@END
@TITLE GRA02.2(1,11)
@COL 6R
@COL 1S-2T-4R-5F
@ROW 6-4
@FLOW 1-2Y-4-5
@FLOW 2N-6-5
@BOX 1.0
DEFINE DEVICE (DEV.NO, DESTN, DEV.TYPE)
@BOX 2.0
IS DEV.TYPE VALID
@BOX 4.0
DEFINE REQUIRED OUTPUT STREAM ACCORDING
TO DEVICE TYPE AND SET RESULT TO STREAM NO.
@BOX 5.0
END
@BOX 6.0
DEVICE TYPE FAULT
SET RESULT TO -50
@BOX 1.1
PROC DEF.DEV (NO, DESTN, DEV.TYPE);
$IN32 DEST;
$IN I, J, K, L;
@BOX 2.1
FOR I<DEVS DO
 IF DEV.TYPE = DEV.NAME [I], ->OUT;
OD
OUT: IF I>= DEVS
@BOX 4.1
I=> DEV.NO OF DEV.ID [NO-1];
IF DRIVE.PROCESS[I] => DEST /= 0 THEN
   DEFINE.OUTPUT (-1, DESTN, DEST, %20000) => K;
ELSE
   0 =>K;
FI
K => DEF.DEV => OSTR OF DEV.ID [NO-1];
@BOX 5.1
END
@BOX 6.1
 -50 => DEF.DEV;
CAPTION (%"Wrong Device Type");
NEWLINES (1);
@END
@TITLE GRA02.3(1.11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
INIT CORE STREAM
@BOX 2.0
INITIALISE CORE
DEFINE DEVICE
INITIALISE VIEWSURFACE
@BOX 3.0
END
@BOX 1.1
PROC INIT.CORE.STR (DEST, DEV);
$IN [1] I0,I1,I2,I3,I5;
@BOX 2.1
0=>I0[0];1=>I1[0];
2=>I2[0];3=>I3[0];5=>I5[0];
INIT (^I3, ^I0, ^I2);
IF DEF.DEV (5, DEST, DEV) =>INITCORESTR >= 0 THEN
   NITSRF (^I5, ^I1, ^I1);
FI
@BOX 3.1
END
@END
@TITLE GRA02.4(1,11)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
INIT. A4 PAPER
@BOX 2.0
SET WINDO etc.
@BOX 3.0
SET NDC SPACE & VIEWPORT
@BOX 4.0
SELECT SURFACE
CREATE GRA. SEGMENT
SET CHAR. PATH & CHAR. SPACE
DRAW PAGE BOX
@BOX 5.0
END
@BOX 1.1
PROC A4.FRAME (WIDTH, HEIGHT);
$IN [1] I0,I1,I2,I3,I5;
$RE [1] R0,R1,R2,R3;
$RE [1]AR1, AR2;
$RE W, H;
 $LO64 D.NAME;
$RE WMARG, HMARG;
$RE [1] XMIN, YMIN, XMAX, YMAX;
$AD DEV.ATTR.PS  DEV.ATTR.P;
@BOX 2.1
0=>I0[0];1=>I1[0];2=>I2[0];3=>I3[0];5=>I5[0];
0.0=>R0[0];1.0=>R1[0]; 0.722=>R2[0]; 0.73=>R3[0];
1 => A4; 0 =>A4Q;
WIDTH/20.0=>WMARG; HEIGHT/20.0=>HMARG;
DEV.NAME [DEV.NO OF DEV.ID [4] ] => D.NAME;
IF D.NAME = "BEN" THEN
   0.0 -(1.5*WMARG) =>XMIN[0]; WIDTH+WMARG =>XMAX[0];
   0.0 -HMARG =>YMIN[0]; HEIGHT+HMARG =>YMAX[0];
ELSE
   0.0 =>XMIN[0] =>YMIN[0];
   WIDTH =>XMAX[0]; HEIGHT=>YMAX[0];
FI
SWINDO (^XMIN, ^XMAX, ^YMIN, ^YMAX);
IF WIDTH < HEIGHT THEN
   0 => LANSP
ELSE
   1 => LANSP
FI
IF SELECTED.DEVICE = NONE THEN
   SELSRF (^I5);
FI
@BOX 3.1
IF D.NAME = "HPP" THEN
  IF WIDTH < HEIGHT THEN
   SNDCS2 (^R2,^R1);
  ELSE
   SNDCS2 (^R1,^R2);
  FI;
FI;
IF D.NAME = "BEN" THEN
   A4W/73.0 * NDC.HEIGHT => W;
   A4H/73.0 * NDC.HEIGHT => H;
  IF WIDTH < HEIGHT THEN
   W=>AR1[0]; H=>AR2[0];
  ELSE
    H=>AR1[0];  W=>AR2[0];
  FI;
  SVPRT2 (^R0, ^AR1, ^R0, ^AR2);
FI
IF DNAME = "MOT" THEN
   SNDC2(^R1,^R3);
FI
@BOX 4.1
CRTSEG ();
SCHPRE (^I1);
SCHPTH (^I0);
 DEV.ATTR [SELECTED.DEVICE] => DEV.ATTR.P;
 DEV.ATTR.P^ (3);
IF D.NAME ="BEN"  THEN
 MOVA2 (^XMIN, ^YMIN);
 LINA2 (^XMAX, ^YMIN);
 LINA2 (^XMAX, ^YMAX);
 LINA2 (^XMIN, ^YMAX);
 LINA2 (^XMIN, ^YMIN);
FI
@BOX 5.1
END
@END

@TITLE GRA02.4.1(1,10)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
INIT. A4 PAPER
@BOX 2.0
SET WINDO
@BOX 3.0
SET NDC SPACE & VIEWPORT
@BOX 4.0
SELECT VIEWSURFACE
SET CHAR. PATH & CHAR. SIZE
DRAW PAGE BOX
@BOX 5.0
END
@BOX 1.1
PROC A4.FRAME1 (IW1,IW2,IH1,IH2);
$IN [1] I0,I1,I2,I3,I5;
$RE [1] R0,R1,R2;
$RE [1] W1,W2,H1,H2;
$RE [1] X1,Y1,Z1,X2,Y2,Z2;
$RE [1] X3,Y3,Z3,X4,Y4,Z4;
$RE [1] AR1, AR2;
$RE W, H;
 $LO64 D.NAME;
$AD DEV.ATTR.PS  DEV.ATTR.P;
@BOX 2.1
0=>I0[0];1=>I1[0];2=>I2[0];3=>I3[0];5=>I5[0];
0.0=>R0[0];1.0=>R1[0]; 0.722=>R2[0];
IW1 =>W1[0]; IW2 =>W2[0];
IH1 =>H1[0]; IH2 =>H2[0];
 1 => A4; 0 =>A4Q;
 DEV.NAME [DEV.NO OF DEV.ID[4] ] => D.NAME;
SWINDO (^W1, ^W2, ^H1, ^H2);
IF IW2-IW1<IH2-IH1  THEN
   0 => LANSP
ELSE
   1 => LANSP
FI
@BOX 3.1
IF D.NAME = "HPP" THEN
 IF IW2-IW1 < IH2-IH1  THEN
  SNDCS3 (^R2, ^R1, ^R1);
  ELSE
  SNDCS3 (^R1, ^R2, ^R1);
  FI;
FI;
IF D.NAME = "BEN" THEN
   A4W/73.0 * NDC.HEIGHT => W;
   A4H/73.0 * NDC.HEIGHT => H;
 IF IW2-IW1 < IH2-IH1  THEN
    W =>AR1[0]; H=>AR2[0];
  ELSE
    H =>AR1[0]; W =>AR2[0];
  FI;
  SVPRT3 (^R0, ^AR1, ^R0, ^AR2, ^R0, ^R1);
FI
@BOX 4.1
IF SELECTED.DEVICE =NONE  THEN
SELSRF (^I5);
FI;
CRTSEG ();
SCHPRE (^I1);
SCHPTH (^I0);
 DEV.ATTR [SELECTED.DEVICE] => DEV.ATTR.P;
 DEV.ATTR.P^ (3);
IF D.NAME ="BEN"  THEN
 MNTOW3 (^R0, ^R0, ^R1, ^X1, ^Y1, ^Z1);
 MNTOW3 (^AR1, ^R0, ^R1, ^X2, ^Y2, ^Z2);
 MNTOW3 (^AR1, ^AR2, ^R1, ^X3, ^Y3, ^Z3);
 MNTOW3 (^R0, ^AR2, ^R1, ^X4, ^Y4, ^Z4);
 MOVA3 (^X1, ^Y1, ^Z1);
 LINA3 (^X2, ^Y2, ^Z2);
 LINA3 (^X3, ^Y3, ^Z3);
 LINA3 (^X4, ^Y4, ^Z4);
 LINA3 (^X1, ^Y1, ^Z1);
FI
@BOX5.1
END
@END

@TITLE GRA02.5(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
INIT. AQ PAPER
@BOX 2.0
SET WINDOW & VIEWPORT etc.
@BOX 3.0
END
@BOX 1.1
PROC AQ.FRAME (WIDTH, HEIGHT);
 $LO64 D.NAME;
$RE W, H;
$AD DEV.ATTR.PS  DEV.ATTR.P;
@BOX 2.1
 1 => A4; 1=> A4Q;
 SWINDO(^0.0, ^WIDTH, ^0.0, ^HEIGHT);
IF WIDTH < HEIGHT THEN
   0 => LANSP
ELSE
   1 => LANSP
FI
 DEV.NAME [DEV.NO OF DEV.ID [4] ] => D.NAME;
IF D.NAME = "HPP" THEN
  IF WIDTH < HEIGHT THEN
   SNDCS2 (^0.722, ^1.0);
  ELSE
   SNDCS2 (^1.0, ^0.722);
  FI;
FI;
IF D.NAME = "BEN" THEN
   (A4W+0.7)/73.0 * NDC.HEIGHT => W;
   (A4H-1.7)/73.0 * NDC.HEIGHT => H;
  IF WIDTH < HEIGHT THEN
    SVPRT2 (^0.0, ^W, ^0.0, ^H);

  ELSE
    SVPRT2 (^0.0, ^H, ^0.0, ^W);
  FI;
FI
SELSRF (^5);
SCHPTH (^0);
 DEV.ATTR [SELECTED.DEVICE] => DEV.ATTR.P;
 DEV.ATTR.P^ (3);
@BOX 3.1
END
@END

@TITLE GRA02.6(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TERMINATE STREAM
@BOX 2.0
TERMINATE VIEWSURFACE & CORE
@BOX 3.0
END
@BOX 1.1
PROC TERM.STR ;
 $IN [1] I5;
@BOX 2.1
 5=>I5[0];
DELSRF (^I5);
TRMSRF (^I5);
TERM ();
@BOX 3.1
END
@END
@TITLE GRA02.7(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
NEW FRAME
@BOX 2.0
CALL NEW.FRAME OF THE CORE
@BOX 3.0
END
@BOX 1.1
PROC NEW.FRAME;
@BOX 2.1
NEWFRM ();
@BOX 3.1
END
@END
@TITLE GRA02.8(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
LINE ABS 2
@BOX 2.0
CALL LINA2 OF THE CORE
@BOX 3.0
END
@BOX 1.1
PROC LINE.ABS.2 (X, Y);
 $RE [1] XX, YY;
@BOX 2.1
X => XX[0]; Y=>YY[0];
LINA2 (^XX, ^YY);
@BOX 3.1
END
@END

@TITLE GRA02.9(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
LINE RELATIVE 2-DIM.
@BOX 2.0
CALL LINR2 OF THE CORE
@BOX 3.0
END
@BOX 1.1
PROC LINE.REL.2 (DX, DY);
$RE[1] DXX, DYY;
@BOX 2.1
DX=> DXX[0]; DY=> DYY[0];
LINR2 (^DXX, ^DYY);
@BOX 3.1
END
@END

@TITLE GRA02.10(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
MOVE ABS 2
@BOX 2.0
CALL MOVA2 OF THE CORE
@BOX 3.0
END
@BOX 1.1
PROC MOVE.ABS.2 (X,Y);
$RE[1] XX, YY;
@BOX 2.1
X=> XX[0]; Y=> YY[0];
MOVA2 (^XX, ^YY);
@BOX 3.1
END
@END

@TITLE GRA02.11(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
MOVE REL 2
@BOX 2.0
CALL MOVR2 OF THE CORE
@BOX 3.0
END
@BOX 1.1
PROC MOVE.REL.2 (DX,DY);
$RE[1] DXX, DYY;
@BOX 2.1
DX=> DXX[0]; DY=> DYY[0];
MOVR2 (^DXX,^DYY);
@BIX 3.1
END
@END
@TITLE GRA02.12(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROCEDURE TEXT
@BOX 2.0
CALL TEXTT OF CORE
@BOX 3.0
END
@BOX 1.1
PROC TEXT (STR,N);
 $IN [1] NN;
@BOX 2.1
N =>NN[0];
TEXTT (STR, 1, ^NN);
@BOX 3.1
END
@END
@TITLE GRA02.13(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROC SET.CHAR.SIZE (W, H);
@BOX 2.0
CALL SCHSIZ OF THE CORE
@BOX 3.0
END
@BOX 1.1
PROC SET.CHAR.SIZE (W, H);
 $RE [1] WW, HH;
@BOX 2.1
 W =>WW[0]; H =>HH[0];
 SCHSIZ (^WW, ^HH);
@BOX 3.1
END
@END





