@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             SYS091
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                           ISSUE 11~
~V9 -1
~P
~V9 1
~YSYS091
~S~M~OSYS IMPLEMENTATION DESCRIPTION
~S~M~OSection 9 Version 1
~S~OSection 9.1 Graphics Device Management
~S1~O1. General Description
~BThis module provides basic facilities for handling graphics devices.
Its function is to allow transfer of data between the host computer
and the graphics store.
~BTwo broad types of graphics devices are handled in this module: those
that require bulk transfer of data between the host and the
device, and those that allow users to access graphics store directly.
The main task of this module is to handle the former type, by
setting up and controlling those transfers.
~S1~O2. Interface
~
Other modules used~
   Section  1   (Co-ordinator)~
   Section 13   (Process Management)~
   Section 14   (Virtual Store Management)~
Hardware registers used~
   V.GR.CONTROL~
   V.GR.COUNT~
   V.GR.CADDRESS~
   V.GR.DADDRESS~
Organisational commands~
   START.GR.OPERATION (UNIT.NO)~
   GR.READ(UNIT.NO,BUFFER.ADDR,COUNT,GR.ADDR)~
   GR.WRITE(UNIT.NO,BUFFER.ADDR,COUNT,GR.ADDR)~
   STOP.GR.OPERATION(UNIT.NO)~
Configuration parameters~
   NO.OF.GR.UNITS~
   MAX.GR.TRANSFER~
   GR.PAR~
~S1~O2.1 Hardware Interface
~BThe graphics units are controlled by four arrays of registers indexed
by the unit number, V.GR.CONTROL, V.GR.COUNT, V.GR.CADDRESS and V.GR.DADDRESS.
To initiate a graphics operation the core address and size in bytes of the
graphics data are written to V.GR.CADDRESS and V.GR.COUNT, respectively,
the graphics device store address is written to V.GR.DADDRESS, and the
code for the required operation is written to V.GR.CONTROL. V.GR.CONTROL
also contains bits indicating the state of the device and the reason for
any interrupts induced by the unit. Its format is shown in the diagram below:~
~3
~Q 9
~
           |Unit         |Interrupt|  Command  |~
       ~O    |Status       |Status   |           |   ~O~
           |   |         | |  |  | |           |~
       ~O    |   |         | |  |  | |           |   ~O~
             |               |  | |~
 INITIAL  ~O   ~O|               |  | |~O   ~OSTATUS CHANGE~
                             |  |~O     ~OOPERATION COMPLETE~
                             |~O        ~OOPERATION FAILED~
~0
~S1~O2.1.1 Unit States
~T# 18
~
0  IDLE/OPERATING~IUnit initialised~
1  INITIAL~IUnit will only accept INIT command.~
~
On system restart each unit interrupts with a STATUS CHANGE interrupt,
in the INITIAL state. An INIT command changes the state to idle.
~S1~O2.2.1 Interrupt States
~T# 25
~
??1  STATUS CHANGE~IUnit status has changed.~
01?  OPERATION COMPLETE~IOperation has completed successfully.~
10?  OPERATION FAIL~IOperation failed.~
~S1~O2.1.3 Commands
~T# 11
~
00  STOP~ITerminates the command operation, if any and clears any interrupts.~
01  READ~IReads data from graphics store into core.~
10  WRITE~IWrites data from core into graphics store.~
11  INIT~IResets the operating parameters of the unit from the
value in V.GR.COUNT, and takes unit out of INITIAL state.~
~S1~O2.2 Software Interface
~
~
1) TINI.GRS (SPN)~
~BThis procedure is called by the System Process Manager at the time
of the termination of a process.~
~
~
2) NO.OF.GR.UNITS~
~BThis configuration parameter sets the number of the graphics units.
~
~
3) MAX.GR.TRANSFER~
~BThis configuration parameter gives the size in bytes of the maximum
graphics transfer.~
~
~
4) GR.MEMORY.RA~
~BThis configuration parameter indicates whether a graphics unit is
directly accessible by the user, and if so the starting address of its
store is obtained from this parameter.
~S1~O3. Implementation
~S1~O3.1 Outline of Operation
~BThis module consists of an interrupt activity, an interrupt procedure and vari
ous
commands. The interrupt activity initially handles all graphics interrupts. Then
,
if necessary, it frees a process waiting for the interrupt.
The interrupt procedure is used by the commands to initiate operations.
~BThese various levels communicate using a variable associated
with the unit which contains all the necessary data about the
status of the unit and the operation in progress.
~S1~O3.2 Data Structures
~T# 32
~
GR.VARS~IAn array indexed by unit number holding the information
relating to the control of a particular unit. Each entry is a
record with the following fields:~
   :STATUS~IThe status of the unit. The following literals are associated
with it:~
        :ON.LINE~ISet when unit is initialised and ready.~
        :OP.FAILED~ISet when operation has failed.~
        :DIRECT.USER.ACCESS~ISet when a unit is to be controlled directly
by a user.~
   :DISP~IThe displacement within a segment SEG of a read/write buffer.~
   :SEG~IThe segment containing a read/write buffer.~
   :SPN~IThe SPN of the process to which the unit is assigned.~
   :COUNT~IThe size in bytes of a read/write transfer.~
   :BLOCK~IThe block no of the start of the read/write buffer.~
   :GR.STORE.DISP~IThe address within the graphics store.~
   :BUFFER.RA~IThe read address of a buffer segment.~
~
HALT.FOR.GR~IAn array containing one variable for each unit, set to the
activity bit of a process waiting for an operation on that unit to
complete.~
~S1~O3.3 Special Notes
~BNone.
~YSYS091
~V9 -1
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                SYS091
~V9 -1
~F
@TITLE SYS09(1,8)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
GRAPHICS MANAGEMENT
@BOX 4.0
PROCEDURES IN MODULE
   INT1   GR INTERRUPT
   INT2   GR INT OPERATION
   CMD1   START GR OPERATION
   CMD2   GR READ
   CMD3   GR WRITE
   CMD4   STOP GR OPERATION
   CMD5   GR OPERATION
   CMD7   TINI GRS
@BOX 6.0
END
@BOX 1.1
#SYS09/1
MODULE SYS09 (GR.INTERRUPT, START.GR.OPERATION, GR.READ, GR.WRITE, STOP.GR.OPERA
TION,
   TINI.GRS);
@BOX 2.1
TYPE BUFFER.TYPE IS
   LOGICAL32 [MAX.BLOCKS.GR.XFER] GR.BUFFER.RA
   INTEGER8 BLOCKS.USED;
TYPE GR.VARS.TYPE IS
   LOGICAL STATUS, DISP, GR.STORE.DISP
   INTEGER SPN, SEG, BLOCK, COUNT
   BUFFER.TYPE BUFFER.RA;
@BOX 3.1
*GLOBAL 5;
LITERAL / LOGICAL ON.LINE = %1, OP.FAILED = %4, DIRECT.USER.ACCESS = %8000,
   STOP.CMD = 0, READ.CMD = 1, WRITE.CMD = 2, INIT.CMD = 3, STATUS.CHANGE  = %10
,
   INITIAL = %8000, INT.MASK = %70, CMD.MASK = 7;
GR.VARS.TYPE [NO.OF.GR.UNITS] GR.VARS;
LOGICAL [NO.OF.GR.UNITS] HALT.FOR.GR;
@BOX 4.1
::*INIT %6000;
*CODE 2;
::*INIT %6000;
PSPEC GR.INTERRUPT ();
PSPEC GR.INT.OP (INTEGER, INTEGER);
   #SYSINT09.1
   #SYSINT09.2
::*INIT %7000;
*CODE 25;
LSPEC START.GR.OPERATION (INTEGER);
LSPEC GR.READ (INTEGER, ADDR, INTEGER, INTEGER);
LSPEC GR.WRITE (INTEGER, ADDR, INTEGER, INTEGER);
LSPEC STOP.GR.OPERATION (INTEGER);
PSPEC GR.OPERATION (INTEGER, INTEGER, ADDR, INTEGER, INTEGER);
   #SYSCMD09.1
   #SYSCMD09.2
   #SYSCMD09.3
   #SYSCMD09.4
   #SYSCMD09.5
*CODE 19;
PSPEC TINI.GRS (INTEGER);
   #SYSCMD09.7
*CODE 4;
@BOX 6.1
*END
@END
@TITLE SYS09/1(1,11)

@COL 1S-2R-3R-4R

@FLOW 1-2-3-4
@BOX 1.0
OTHER MODULES REFERENCED
@BOX 4.0
SYS01 COORDINATOR
SYS13 PROCESS MANAGER
SYS14 VIRTUAL STORE MANAGER
@BOX 1.1
::EXTERNAL ENVIROMENT
@BOX 2.1
IMPORT LITERAL NO.OF.GR.UNITS, MAX.GR.TRANSFER, MAX.BLOCKS.GR.XFER;
INTEGER32 [NO.OF.GR.UNITS] GR.MEMORY.RA;
INTEGER [NO.OF.GR.UNITS] GR.PAR;
IMPORT VSTORE V.GR.CONTROL [], V.GR.COUNT [];
IMPORT VSTORE LOGICAL32 V.GR.CADDRESS [];
IMPORT VSTORE LOGICAL32 V.GR.DADDRESS [];
@BOX 3.1
PSPEC VALIDATE (ADDR, LOGICAL) / INTEGER;
@BOX 4.1
IMPORT LITERAL SYS01.GR.HALT;
LOGICAL SYS01.CURRENT.ACTIVITY.BIT;
PSPEC SYS01.NEXT.ACTIVITY ();
PSPEC SYS01.HALT (LOGICAL, INTEGER);
PSPEC SYS01.FREE (LOGICAL, INTEGER);
PSPEC SYS01.CHECK.IN (INTEGER, INTEGER);
PSPEC SYS01.CHECK.OUT (INTEGER, INTEGER);
INTEGER SYS13.CURRENT.SPN;
PSPEC SYS13.INT.PROC (LOGICAL, LOGICAL);
PSPEC SYS13.ENTER.INT.LEVEL (ADDR SYS13.INT.PROC, LOGICAL, LOGICAL);
IMPORT LITERAL SYS14.SEG.SHIFT, SYS14.SEG.SIZE, SYS14.PAGE.SHIFT, SYS14.PAGE.SIZ
E;
PSPEC MAP (INTEGER, INTEGER, INTEGER);
PSPEC SYS14.GET.BLOCK (INTEGER, INTEGER) / INTEGER32;
PSPEC SYS14.UPDATE.BLOCK (INTEGER32);
PSPEC SYS14.REL.BLOCK (INTEGER32);
ADDR PW0, PW1, PW2, PW3, PW4, PW5, PW6;
LOGICAL64 PWW1, PWW2, PWW3;
@END
@TITLE SYSINT09.1(1,8)
@COL 1S-16N-2T-3R-4T-5R-6T-8R-9R-10R-11F
@COL 15N-13R-14R-12R
@ROW 16-15
@ROW 3-13
@ROW 5-14
@ROW 8-12
@FLOW 1-16-2FOUND-3-4NO-5-6NO-8-9-10-16
@FLOW 2NONE-13-15-16
@FLOW 4YES-14-15
@FLOW 6YES-12-15
@BOX 1.0
GR INTERRUPT
@BOX 2.0
FIND A DEVICE TO SERVICE?
@BOX 3.0
STOP THE DEVICE AND CLEAR INTERRUPTS
@BOX 4.0
DEVICE AT INITIAL STATE?
@BOX 5.0
SELECT GRAPHICS VARS
@BOX 6.0
CHANGE OF STATUS?
@BOX 8.0
REMEMBER DEVICE STATUS
@BOX 9.0
RELEASE BLOCKS
@BOX 10.0
FREE THE HALTED USER PROCESS
@BOX 11.0
END
@BOX 12.0
SET DEVICE TO ON LINE
@BOX 13.0
NEXT ACTIVITY
[SYS01]
@BOX 14.0
INITIALISE UNIT
@BOX 1.1
PROC GR.INTERRUPT;
INTEGER UNIT.NO, BLK, INDEX;
LOGICAL INT.STATUS;
@BOX 2.1
-1 => UNIT.NO;
WHILE 1 +> UNIT.NO < NO.OF.GR.UNITS AND
   V.GR.CONTROL [UNIT.NO] => INT.STATUS & INT.MASK = 0
DO OD
IF UNIT.NO = NO.OF.GR.UNITS
@BOX 3.1
STOP.CMD => V.GR.CONTROL [UNIT.NO];
@BOX 4.1
IF INT.STATUS & INITIAL /= 0
@BOX 5.1
SELECT GR.VARS [UNIT.NO];
@BOX 6.1
IF INT.STATUS & INT.MASK = STATUS.CHANGE
@BOX 8.1
6 & STATUS -=> STATUS;
INT.STATUS ->> 4 & 6 !> STATUS;
V.GR.COUNT [UNIT.NO] => COUNT;
@BOX 9.1
SELECT BUFFER.RA;
FOR INDEX < BLOCKS.USED DO
   IF GR.BUFFER.RA [INDEX] => BLK /= 0 THEN
      IF INT.STATUS & CMD.MASK = READ.CMD THEN
         SYS14.UPDATE.BLOCK (BLK);
      FI
      SYS14.REL.BLOCK (BLK);
      0 => GR.BUFFER.RA [INDEX];
   FI
OD
0 => BLOCKS.USED;
@BOX 10.1
SYS01.FREE (HALT.FOR.GR [UNIT.NO], SYS01.GR.HALT);
@BOX 11.1
END
@BOX 12.1
ON.LINE !> STATUS;
@BOX 13.1
SYS01.NEXT.ACTIVITY ();
@BOX 14.1
GR.PAR [UNIT.NO] => V.GR.COUNT [UNIT.NO];
INIT.CMD => V.GR.CONTROL [UNIT.NO];
@END

@TITLE SYSINT09.2(1,8)
@COL 9R
@COL 1S-2R-3T-4R-5R-6R-7R-8F
@ROW 9-6
@FLOW 1-2-3NO-4-5-6-7-8
@FLOW 3YES-9-8
@BOX 1.0
GR INTERRUPT OPERATION (UNIT NO, OPERATION)
@BOX 2.0
SELECT GR VARS
@BOX 3.0
NON-TRANSFER OPERATION?
@BOX 4.0
FIND CORE ADDRESS OF BUFFER SEGMENT
@BOX 5.0
SET ADDRESS FOR TRANSFER
@BOX 6.0
SET GR ADDRESS AND START OPERATION
@BOX 7.0
HALT ACTIVITY FOR GRAPHICS OPERATION
@BOX 8.0
END
@BOX 9.0
START OPERATION
@BOX 1.1
PROC GR.INT.OP (UNIT.NO, OP);
INTEGER INDEX, BLK, UNIT.SPAN, COUNT.COPY;
LOGICAL32 DISP32;
@BOX 2.1
SELECT GR.VARS [UNIT.NO];
@BOX 3.1
IF OP /= READ.CMD /= WRITE.CMD
@BOX 4.1
UNIT.NO * MAX.BLOCKS.GR.XFER - 1 => UNIT.SPAN;
-1 => INDEX;
DISP => DISP32;
COUNT => V.GR.COUNT [UNIT.NO] + SYS14.PAGE.SIZE => COUNT.COPY;
BLOCK - 1 => BLK;
@BOX 5.1
SELECT BUFFER.RA;
WHILE SYS14.PAGE.SIZE -> COUNT.COPY > 0 DO
   SYS14.GET.BLOCK (SEG, 1 +> BLK) => GR.BUFFER.RA [1 +> INDEX]
   + DISP32 => V.GR.CADDRESS [1 +> UNIT.SPAN];
   0 => DISP32;
OD
INDEX + 1 => BLOCKS.USED;
@BOX 6.1
GR.STORE.DISP => V.GR.DADDRESS [UNIT.NO];
OP => V.GR.CONTROL [UNIT.NO];
@BOX 7.1
SYS01.HALT (SYS01.CURRENT.ACTIVITY.BIT => HALT.FOR.GR [UNIT.NO],
   SYS01.GR.HALT);
@BOX 8.1
END
@BOX 9.1
OP => V.GR.CONTROL [UNIT.NO];
@END
@TITLE SYSCMD09.1(1,8)
@COL 14T-9R
@COL 1S-2R-10T-8T-3T-7R-5R-6F
@COL 11R-13N-4R-12N
@ROW 14-3-13
@ROW 8-11
@ROW 9-4
@FLOW 1-2-10NO-8NO-3NO-7-5-6
@FLOW 10YES-11-12-5
@FLOW 8YES-14NO-9-5
@FLOW 3YES-13-4-12
@FLOW 14YES-7
@BOX 1.0
START GR OPERATION (UNIT NO)
@BOX 2.0
CHECKIN
[SYS01]
@BOX 3.0
DEVICE AVAILABLE?
@BOX 4.0
ASSIGN DEVICE TO USER PROCESS
@BOX 5.0
CHECKOUT
[SYS01]
@BOX 6.0
END
@BOX 7.0
RETURN FAULT STARTUS -60 IN PW0
(GRAPHICS DEVICE UNAVAILABLE)
@BOX 8.0
DIRECT USER ACCESS?
@BOX 9.0
ASSIGN DEVICE TO USER PROCESS
@BOX 10.0
UNIT NUMBER INVALID?
@BOX 11.0
RETURN FAULT STATUS -61 IN PW0
(GRAPHICS UNIT NO OUT OF RANGE)
@BOX 14.0
DEVICE UNAVAILABLE?
@BOX 1.1
PROC START.GR.OPERATION (UNIT.NO);
0 => PW0;
@BOX 2.1
SYS13.ENTER.INT.LEVEL (^SYS01.CHECKIN, 0, 0);
@BOX 3.1
IF STATUS & ON.LINE /= 0 AND SPN = 0
@BOX 4.1
SYS13.CURRENT.SPN => SPN;
@BOX 5.1
SYS13.ENTER.INT.LEVEL (^SYS01.CHECKOUT, 0, 0);
@BOX 6.1
END
@BOX 7.1
-60 => PW0;
@BOX 8.1
SELECT GR.VARS [UNIT.NO];
IF GR.MEMORY.RA [UNIT.NO] >= 0
@BOX 9.1
DIRECT.USER.ACCESS => STATUS;
SYS13.CURRENT.SPN => SPN;
@BOX 10.1
IF UNIT.NO < 0 OR UNIT.NO >= NO.OF.GR.UNITS
@BOX 11.1
-61 => PW0;
@BOX 14.1
IF SPN /= 0
@END

@TITLE SYSCMD09.2(1,11)
@COL 1S-2T-3R-4F
@COL 5R
@ROW 5-3
@FLOW 1-2OK-3-4
@FLOW 2FAIL-5-4
@BOX 1.0
GR READ (UNIT NO, BUFFER ADDR, COUNT, GR ADDR)
@BOX 2.0
VALIDATE BUFFER ADDRESS
@BOX 3.0
EXECUTE READ OPERATION
@BOX 4.0
END
@BOX 5.0
RETURN FAULT STATUS -8
(VALIDATE FAIL)
@BOX 1.1
PROC GR.READ (UNIT.NO, BUFFER.ADDR, COUNT, GR.ADDR);
0 => PW0;
@BOX 2.1
IF COUNT > MAX.GR.TRANSFER THEN
   MAX.GR.TRANSFER => COUNT;
FI
IF VALIDATE (BUFFER.ADDR, %4) /= 0 OR
   VALIDATE (BUFFER.ADDR + COUNT - 1, %4) /= 0
@BOX 3.1
GR.OPERATION (UNIT.NO, READ.CMD, BUFFER.ADDR, COUNT, GR.ADDR);
@BOX 4.1
END
@BOX 5.1
-8 => PW0;
@END

@TITLE SYSCMD09.3(1,11)
@COL 1S-2T-3R-4F
@COL 5R
@ROW 5-3
@FLOW 1-2OK-3-4
@FLOW 2FAIL-5-4
@BOX 1.0
GR WRITE (UNIT NO, BUFFER ADDR, COUNT, GR ADDR)
@BOX 2.0
VALIDATE BUFFER ADDRESS
@BOX 3.0
EXECUTE WRITE OPERATION
@BOX 4.0
END
@BOX 5.0
RETURN FAULT STATUS -8
(VALIDATE FAIL)
@BOX 1.1
PROC GR.WRITE (UNIT.NO, BUFFER.ADDR, COUNT, GR.ADDR);
0 => PW0;
@BOX 2.1
IF COUNT > MAX.GR.TRANSFER THEN
   MAX.GR.TRANSFER => COUNT;
FI
IF VALIDATE (BUFFER.ADDR, %C) /= 0 OR
   VALIDATE (BUFFER.ADDR + COUNT - 1, %C) /= 0
@BOX 3.1
GR.OPERATION (UNIT.NO, WRITE.CMD, BUFFER.ADDR, COUNT, GR.ADDR);
@BOX 4.1
END
@BOX 5.1
-8 => PW0;
@END


@TITLE SYSCMD09.4(1,8)
@COL 7R
@COL 1S-6T-2T-3R-4F
@COL 5R
@ROW 7-3-5
@FLOW 1-6NO-2NO-3-4
@FLOW 6YES-7-4
@FLOW 2YES-5-4
@BOX 1.0
STOP GR OPERATION (UNIT NO)
@BOX 2.0
DEVICE UNAVAILABLE TO THIS PROCESS?
@BOX 3.0
MAKE DEVICE AVAILABLE
@BOX 4.0
END
@BOX 5.0
RETURN FAULT STATUS -60 IN PW0
(DEVICE UNAVAILABLE)
@BOX 6.0
UNIT NUMBER INVALID?
@BOX 7.0
RETURN FAULT STATUS -61 IN PW0
(GRAPHICS UNIT NO OUT OF RANGE)
@BOX 1.1
PROC STOP.GR.OPERATION (UNIT.NO);
0 => PW0;
@BOX 2.1
SELECT GR.VARS [UNIT.NO];
IF SYS13.CURRENT.SPN /= SPN
@BOX 3.1
0 => SPN;
@BOX 4.1
END
@BOX 5.1
-60 => PW0;
@BOX 6.1
IF UNIT.NO < 0 OR UNIT.NO >= NO.OF.GR.UNITS
@BOX 7.1
-61 => PW0;
@END

@TITLE SYSCMD09.5(1,8)
@COL 10R-11R-16N
@COL 1S-2T-3T-4T-14T-5T-6T-7R-9F
@COL 12R-15R-13R-17N
@ROW 10-3
@ROW 4-12
@ROW 11-5-15
@ROW 16-6-13
@ROW 7-17
@FLOW 1-2NO-3NO-4NO-14NO-5OK-6FAILED-7-9
@FLOW 2YES-10-16-9
@FLOW 3YES-12-17-9
@FLOW 4YES-11-16
@FLOW 5FAILED-13-17
@FLOW 14YES-15-17
@FLOW 6OK-16
@BOX 1.0
GR OPERATION (UNIT NO, OPERATION, BUFFER ADDR, TRANSFER COUNT, GR ACCR)
@BOX 2.0
UNIT NUMBER INVALID?
@BOX 3.0
DEVICE UNAVAILABLE TO THIS PROCESS?
@BOX 4.0
DEVICE TO BE USED DIRECTLY?
@BOX 5.0
SET TRANSFER INFORMATION IN BUFFER?
@BOX 6.0
EXECUTE OPERATION?
@BOX 7.0
RETURN FAULT STATUS -63 IN PW0
(GRAPHICS OPERATION FAILED)
@BOX 9.0
END
@BOX 10.0
RETURN FAULT STATUS -61 IN PW0
(GRAPHICS UNIT NO OUT OF RANGE)
@BOX 11.0
RETURN FAULT STATUS -64 IN PW0
(GRAPHICS DEVICE TO BE USED DIRECTLY)
@BOX 12.0
RETURN FAULT STATUS -60 IN PW0
(GRAPHICS DEVICE UNAVAILABLE)
@BOX 13.0
RETURN FAULT STATUS -62 IN PW0
(GRAPHICS -BOUNDARY VIOLATION)
@BOX 14.0
TRANSFER COUNT IS TOO LOW?
@BOX 15.0
RETURN FAULT STATUS -65 IN PW0
(GRAPHICS TRANSFER COUNT IS NOT POSITIVE)
@BOX 1.1
PROC GR.OPERATION (UNIT.NO, OP, BUFFER.ADDR, TRANS.COUNT, GR.ADDR);
INTEGER TEMP;
@BOX 2.1
IF UNIT.NO < 0 OR UNIT.NO >= NO.OF.GR.UNITS
@BOX 3.1
SELECT GR.VARS [UNIT.NO];
IF SYS13.CURRENT.SPN /= SPN
@BOX 4.1
IF STATUS & DIRECT.USER.ACCESS /= 0
@BOX 5.1
MAP (-1, BUFFER.ADDR ->> SYS14.SEG.SHIFT => TEMP, 0);
PW1 => SEG;
TEMP <<- SYS14.SEG.SHIFT -: BUFFER.ADDR => DISP
   ->> SYS14.PAGE.SHIFT => BLOCK <<- SYS14.PAGE.SHIFT
   => TEMP -> DISP;
TRANS.COUNT => COUNT;
IF TEMP + DISP + COUNT > SYS14.SEG.SIZE
@BOX 6.1
GR.ADDR => GR.STORE.DISP;
SYS13.ENTER.INT.LEVEL (^GR.INT.OP, UNIT.NO, OP);
TRANS.COUNT - COUNT => PW1;
IF STATUS & OP.FAILED = 0
@BOX 7.1
-63 => PW0;
@BOX 9.1
END
@BOX 10.1
-61 => PW0;
@BOX 11.1
-64 => PW0;
@BOX 12.1
-60 => PW0;
@BOX 13.1
-62 => PW0;
@BOX 14.1
IF TRANS.COUNT =< 0
@BOX 15.1
-65 => PW0;
@END


@TITLE SYSCMD09.7(1,8)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TINI GRS (PROCESS)
@BOX 2.0
RELEASE ALL UNITS ASSIGNED TO THE PROCESS
@BOX 3.0
END
@BOX 1.1
PROC TINI.GRS (PROC.SPN);
INTEGER UNIT.NO;
@BOX 2.1
FOR UNIT.NO < NO.OF.GR.UNITS DO
   IF SPN OF GR.VARS [UNIT.NO] = PROC.SPN THEN
      0 => SPN OF GR.VARS [UNIT.NO];
   FI
OD
@BOX 3.1
END
@END



