@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             DOC031
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YDOC031
~S1~M~ODOCUMENTATION IMPLEMENTATION DESCRIPTION
~S1~M~OSection 3 Version 1
~S1~OSection 3.1 Code Generation
~S1~O1. General Description
~BThis section describes the FLIP procedure which is a means
for generating a program from a file of flowchart descriptions. The
common procedures INPUT.TITLE and INPUT.CHART in Section 2 are used
to convert the chart descriptions to tabular form. This form is
examined to produce output with the box text correctly ordered and
labels and 'gotos' inserted as necessary. The charts are ordered
as specified by cross-references in the box text, starting from the
master chart.
~S1~OInterfaces
~T% 25
~
Other modules used -~IDOC021 (Documentation common procedures)
Procedures INPUT.TITLE, INPUT.CHART.~
~S1~O2.1 Hardware Interface
~S1~O2.2 Software Interface
~S1FLIP(INPUT.FILE,TRANSLATION.LEVEL,MONITORING,LABELS~
     GOTOS,CONDITIONALS)~
~BThis procedure converts flowchart specifications on the
INPUT.FILE into a linear program at the specified
TRANSLATION.LEVEL and creates this as the current file.
The format of the labels, gotos and conditional gotos
which it inserts are specified by the last three parameters.
A flowchart title should follow the call for this
procedure. The master chart cross-references
the other charts which in turn cross reference others in a hierarchical manner.
If the
MONITORING parameter is set, the contents of each box
for all charts on the INPUT.FILE will be monitored
on the current stream.
~S1~O3. Implementation
~S1~O3.1 Outline of Operation
~BFLIP makes use of the two documentation common
procedures in section 2 (DOC021). It uses INPUT.TITLE
to read in the next chart title which allows a
directory of charts to be built up. INPUT.CHART then operates
on that chart description and forms a tabular representation
in the tables BOXTAB, COLTAB and BOXTEXTBUFFER (see DOC021).
FLIP then uses these tables to form a CODELIST which is an
encoded list of ordered box numbers, jumps (conditional and
unconditional) and labels. The codelist is then used
to output the text for each box from the BOXTEXTBUFFER
together with jumps and labels to an output stream. These
steps are repeated for all charts on the INPUT.FILE from
first to last. As each is processed by INPUT.CHART,
its starting position in the output stream is noted
in the title directory and an end of
chart warning character (EOCWC) is inserted in the output.
FLIP now reorders this output
starting from the master chart by following through the cross
references. It achieves this by converting
the output to an input stream and copying
characters to a current file output stream
until it encounters either a cross-reference warning character
(CRWC) inserted by INPUT.CHART or end
of chart warning character. A cross-reference causes
the input pointer to be stacked then reset to the
value for the new chart held in the title directory
before copying recommences.
Stacking may go to several levels in this way
until an end of chart is encountered when the stack is
unwound by one and copying continues from the
point following the last cross-reference.
Flip can also generate label specs in the
manner required by Pascal-like languages
by use of a variant of the CRWC called PWC.
It is generated by INPUT.CHART and in the same
way as CRWC it is followed by a chart
title. In its first pass Flip forms for each
chart a list of the numbers of all labelled
boxes (LABLIST) and stores a pointer to this list
in the title directory entry for the chart.
Subsequently, in the second pass when a PWC
is encountered, the chart title is read,
matched with an entry in the directory
and labels are generated for each of the
boxes in the box label list.
~BFaults monitored by INPUT.CHART cause that chart
to be ignored in the first pass of FLIP. Faults
encountered subsequently are monitored and their
total stored in PW0.
~S1~O3.2 Data Structures
~T% 15
~
~
CODELIST~Ia word vector in the form of a list expressing the
order of boxes and insertion of goto's, conditional and
unconditional, required in the code to cause the
correct flow paths through the code to be generated.
Each element has two fields explained below:-~
~
%BNO - the number of the next box whose~
%      text is to be planted.~
~
%JMP.INFO - an integer code with the following~
%           significances:~
~
%0 means plant the box text only~
%1 means plant an unconditional~
%goto to the label associated with~
%the text of BOX~
%2 means plant a conditional jump to~
%the label associated with the text~
%of BOX~
~
~IThere are two special encodings of BNO/JMP.INFO. When
both are zero it indicates the end of the code list. A
zero value of BNO with 3 in JMP.INFO is a 'PASCAL
marker'. This is generated by the @@P statement and it
causes automatic generation of PASCAL declarations for
the labels on the chart.~
~
CRS~IThe CROSS REFERENCE STACK is a vector of integers
operating as a stack in which each entry represents a
further level of chart cross referencing. It is used in
the second pass of FLIP when the output stream of chart
text produced by the first pass is being reprocessed to
deal with chart cross references. The chart text has
been reselected as an input stream an each entry in
the CROSS.REF.STACK points back to the place in the
input stream where the last cross reference occurred.~
~
TITLE.DIR~Ia list relating each chart title to its position in the
chart text stream. Its fields are described below.~
~
%TITLE.HASH - an integer representing a~
%hash value for a chart title.~
~
%CHART.POS - an integer giving the~
%character position of the start of~
%the chart text in the output stream~
%generated by the first pass of FLIP.~
~
LAB.PTR~Ian integer indexing the position in LAB.LIST of
the start of the list of box numbers for which
labels have been generated in this chart.~
~
TBUFF~IThe TITLE BUFFER is a character vector used as working
space for storing chart titles.~
~
LAB.LIST~Ia byte vector giving for all charts the
numbers of the boxes for which labels
were generated. The end of the list for
an individual chart is indicated by
box number 64.~
~
TDIND~Ian integer for indexing the TITLE.DIR.~
~
FCOUNT~Ia count of the number of faults
noticed by FLIP.~
~
OLD.OUT~Ian integer giving the previous
output stream number.~
~
OLD.IN~Ian integer for holding the
previous input stream number.~
~
START.BOX~Ian integer giving the start box.~
~
OUT~Ian integer giving the current output
stream number.~
~
IN~Ian integer giving the current input
stream number.~
~
CRS.PTR~Ian integer for indexing the
cross-reference stack (CRS).~
~
IN.OUT~Ian integer giving the stream
number used for output on the first
pass and is input on the second pass.~
~
FIN.BOX~Ian integer giving the finish box number.~
~
CLPTR~Ian integer for indexing the CODELIST.~
~
IFSIZE~Ian integer for holding the size of the INPUT.FILE.~
~
REQ.TITLE~Ia 32-bit word holding
a hash of the title of the
requested master chart.~
~
CUR.TITLE~Ia 32-bit word holding
a hash of the title of
the chart currently being processed.~
~
CURTPOS~Ia 32-bit integer giving
the input pointer position
of the current chart.~
~
INIT.CHT~Ia 32-bit integer giving
the position in the input stream of the
start of the master chart.~
~
DSEG1,DSEG2~Iintegers for holding
segment numbers created
due to size considerations
in smaller machines.~
~
NEXT.EL~Ian aggregate type used
for holding the current
entry on the CODELIST.~
~
DLAB~Ia datavector holding the default
label string i.e. L:~
~
DJUMP~Ia datavec holding the default
unconditional jump string i.e. -> L;~
~
DRJUMP~Ia datavec holding the default
conditional jump string i.e. ,-> L;~
~
BOXNO~Ian integer for indexing BOXTAB.~
~
COLNO~Ian integer for indexing COLTAB.~
~Y
~V9 -1
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H                DOC031
~V9 -1
~F
@TITLE DOC03(1,8)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
FORM LINEAR PROGRAM - (FLIP)
@BOX 2.0
@BOX 3.0
@BOX 4.0
PROCEDURES IN MODULE
   FLIP [DOC03.1]
@BOX 5.0
#DOC03.1
@BOX 6.0
END
@BOX 1.1
#DOC03/1
MODULE(FLIP);
@BOX 2.1
@BOX 3.1
@BOX 4.1
LSPEC FLIP($AD[$LO8],$IN,$IN,ADDR[$LO8], ADDR[$LO8], ADDR[$LO8]);
#DOC03.1
@BOX 6.1
*END
@END
@TITLE DOC03/1(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
EXTERNAL ENVIRONMENT
@BOX 2.0
EXTERNALS
@BOX 3.0
END
@BOX 1.1
::EXTERNALS
@BOX 2.1
$LS CURRENT.INPUT()/$IN;
$LS CURRENT.OUTPUT()/$IN;
$LS DEFINE.IO($IN,$AD[$LO8],$IN32,$IN32)/$IN;
$LS DEFINE.INPUT($IN,$AD[$LO8],$IN32)/$IN;
$LS DEFINE.OUTPUT($IN,$AD[$LO8],$IN32,$IN32)/$IN;
$LS SELECT.INPUT($IN);$LS SELECT.OUTPUT($IN);
$LS END.INPUT($IN,$IN);$LS END.OUTPUT($IN,$IN);
$LS INCH()/$IN;$LS OUTCH($IN);$LS NEXTCH()/$IN;
$LS INBACKSPACE($IN);
$LS SPACES($IN);$LS NEWLINES($IN);
$LS OUTI($IN32,$IN);
$LS BREAKOUTPUT($IN);$LS IPOS()/$IN32;$LS OPOS()/$IN32;
$LS SET.I.POS($IN32);$LS SET.O.POS($IN32);$LS CAPTION($AD[$LO8]);
$LS OUTSTACK(ADDR,ADDR);
$LS I.SIZE()/$IN32;$LS IENQ()/$IN;
$LS ENTER.TRAP($IN,$IN);
$LS TIME.AND.DATE();
$LS CREATE.SEGMENT($IN,$AD);$LS MAP($IN,$IN,$IN);
$LS RELEASE.SEGMENT($IN);
$LS INTERCHANGE($IN,$IN);
::MU6 $PS INPUT.CHART($IN,$IN,$IN)/$IN;
::MU6 $PS INPUT.TITLE($AD[$LO8],$IN)/$IN32;
::MC68000 $PS INPUT.CHART($IN,$IN,$IN)/$IN;
::MC68000 $PS INPUT.TITLE($AD[$LO8],$IN)/$IN32;
::PDP $LS INPUT.CHART($IN,$IN,$IN)/$IN;
::PDP $LS INPUT.TITLE($AD[$LO8],$IN)/$IN32;
TYPE BOXSPECS IS $IN COL.LINK,ROW.LINK,PFLOW.LINK,YCOORD
$IN SFLOWLINK,TEXT.PTR,PFLOW.TEXT,SFLOW.TEXT,HT,TEXTPTR1
$LO8 T,BOXHT,BOXWTH,COL,INFLOW,LAB.COUNT,PLANTED,YFIXED,BOXHT1,BOXWTH1;
BOXSPECS[64] BOXTAB;$IN[8] COLTAB;
$LO8[8192] BTB;
$AD PW0,PW1;
$IM$LI PWC,CRWC,EOBWC,EOCWC,SEGSIZE;
::MU6 $IM$LI WORKSEG;
@BOX 3.1
::END
@END
@TITLE DOC03.1(1,11)
@COL 1S-2R-3R-4R-5R-6T-8R-9R-10T-19R-11T-12R-13R-14R
@COL 7T-18R-15R-16R-20T-21R-17F
@ROW 8-7
@FLOW 1-2-3-4-5-6-8-9-10N-11Y-12-13-14-6
@FLOW 10Y-19-6
@FLOW 6NONE-7Y-15-16-20Y-21-17
@FLOW 20N-17
@FLOW 7N-18-16
@FLOW 11N-13

@BOX 1.0
FLIP(FILE,LEVEL,MONITOR,LABEL,JUMP,RELJUMP)
@BOX 2.0
IF ANY OF LABEL/JUMP/RELJUMP
ARE ZERO SUBSTITUTE DEFAULTS
@BOX 3.0
NOTE CURRENT OUTPUT
ASSIGN OUTPUT STREAM
FOR STORING CHART TEXT
CLEAR F.COUNT
@BOX 4.0
READ TITLE FROM CURRENT INPUT AND
STORE AS REQUIRED TITLE
@BOX 5.0
NOTE CURRENT INPUT
ASSIGN INPUT STREAM TO 'FILE'
AND SELECT IT
@BOX 6.0
FIND AND INPUT NEXT TITLE
IN 'FILE'
@BOX 8.0
MONITOR IF TITLE
ALREADY DEFINED
PRINT TITLE.
NOTE CURRENT POSN OF
CHART TEXT OUTPUT STR
@BOX 9.0
INPUT.CHART (LEVEL,-1)
@BOX 10.0
ANY FAULTS?
@BOX 19.0
INC FAULTS COUNT
@BOX 11.0
IS THIS THE REQUIRED
CHART?
@BOX 12.0
NOTE THE START POINT
OF THIS CHART TEXT IN
THE CURRENT OUTPUT STREAM
@BOX 13.0
MAKE ENTRY IN TITLE DIRECTORY
@BOX 14.0
GENERATE CHT TEXT
[DOC03.1.1]
@BOX 7.0
MASTER CHART FOUND?
@BOX 18.0
MONITOR - MASTER
CHART NOT FOUND
@BOX 15.0
GENERATE FILE TEXT
[DOC03.1.2]
@BOX 16.0
RELEASE 'FILE' INPUT
RESELECT ORIGINAL INPUT
@BOX 20.0
ANY FAULTS?
@BOX 21.0
ENTER TRAP(9,20)
@BOX 17.0
RETURN
@BOX 1.1
PROC FLIP(FILE,LEV,MONITOR,LABL,JUMP,RELJUMP);
TYPE CODES IS $IN BNO $LO8 JMP.INFO;
CODES[128] CODELIST;$IN32[32] CRS;
TYPE TITLES IS $IN32 TITHASH,TITPOS $IN LABPOS;
TITLES[128] TITLE.DIR;$LO8[64]TBUFF;
$LO8[1024] LABLIST;
$IN TDIND,FCOUNT,OLD.IN,I,START.BOX,OUT,IN,SYM,OLD.OUT,LABPTR;
$IN CRS.PTR,IN.OUT,J,K,FIN.BOX,CLPTR,SJ,BOXNO,COLNO;
$IN32 REQ.TITLE,CUR.TITLE,CUR.TPOS,INIT.CHT,IFSIZE;
CODES NEXT.EL;$IN DSEG1,DSEG2;
$LI/$AD[$LO8] CUR.FILE= ;
DATAVEC DLAB($LO8); 'L ':; END
DATAVEC DJUMP($LO8); '- '> 'L ';; END
DATAVEC DRJUMP($LO8); ', '- '> 'L ';; END
PSPEC COPYSTR(ADDR[$LO8],$IN,$IN);
#DOC03.1.1.3
::PDP CREATE.SEGMENT(-1,%2000);MAP(PW1=>DSEG1,5,1);
::PDP CREATE.SEGMENT(-1,%2000);MAP(PW1=>DSEG2,6,1);
::MU6 CREATE.SEGMENT(WORKSEG=>DSEG1,%8000);
::MU6 IF PW0/= 0 THEN CREATE.SEGMENT(-1,%8000);INTERCHANGE(PW1=>DSEG1,WORKSEG) F
I;
::MC68000 RELEASE.SEGMENT(48);CREATESEGMENT(48,%4000);MAP(48,-1,0);
@BOX 2.1
IF SIZE(LABL)=0 THEN ^DLAB => LABL FI
IF SIZE(JUMP)=0 THEN ^DJUMP => JUMP FI
IF SIZE(RELJUMP)=0 THEN ^DRJUMP => RELJUMP FI
@BOX 3.1
CURRENT.OUTPUT() => OLD.OUT;
0 => TDIND => FCOUNT => LABPTR;
-1 => INIT.CHT;
@BOX 4.1
INPUT.TITLE(^TBUFF,0) => REQ.TITLE ;
@BOX 5.1
CURRENT.INPUT() => OLD.IN;
SELECT.INPUT(DEFINE.INPUT(-1,FILE,0)=>IN);
IF I.SIZE() => IFSIZE < SEGSIZE THEN
   SEGSIZE => IFSIZE;
FI
DEFINE.IO(-1,CUR.FILE,%40,IFSIZE) => IN.OUT;
@BOX 6.1
IF INPUT.TITLE(^TBUFF,1) => CUR.TITLE = 0
@BOX 8.1
NEWLINES(1) ;
FOR I < TD.IND DO
   IF TIT.HASH OF TITLE.DIR[I]=CUR.TITLE THEN
      CAPTION(%"CHART ALREADY DEFINED  ");
   1 +> FCOUNT;
FI OD
-1 => I;
WHILE TBUFF[1+>I] /= '$L DO OUTCH(TBUFF[I]) OD
SELECT.OUTPUT(IN.OUT);OPOS() => CUR.TPOS;
SELECT.OUTPUT(OLD.OUT);
@BOX 9.1
INPUT.CHART(LEV,-1,1) => START.BOX;
@BOX 10.1
IF START.BOX >= 0
@BOX 19.1
1 +> FCOUNT;
@BOX 11.1
IF CUR.TITLE /= REQ.TITLE
@BOX 12.1
CUR.TPOS => INIT.CHT;
@BOX 13.1
LABPTR => LABPOS OF TITLE.DIR[TDIND];
CUR.TITLE => TIT.HASH OF TITLE.DIR[TD.IND];
CUR.TPOS => TIT.POS OF TITLE.DIR[TD.IND];1 +> TD.IND;
@BOX 14.1
#DOC03.1.1
@BOX 7.1
IF INIT.CHT >= 0
@BOX 18.1
CAPTION(%"$LMASTER CHART NOT FOUND");
1 +> FCOUNT;
@BOX 15.1
#DOC03.1.2
@BOX 16.1
END.INPUT(IN.OUT,0);
SELECT.INPUT(OLD.IN) ;
::PDP RELEASE.SEGMENT(DSEG1);
::PDP RELEASE.SEGMENT(DSEG2);
::MU6 INTERCHANGE(DSEG1,WORKSEG);RELEASE.SEGMENT(DSEG1);
::MC68000 RELEASE.SEGMENT(48);
@BOX 20.1
IF FCOUNT = 0
@BOX 21.1
ENTER.TRAP(9,20);
@BOX 17.1
END
@END

@TITLE DOC03.1.1(1,8)
@COL 11T-12R-13T-14R-15R
@COL 1S-2R-3R-4R-6T-5T-7R-8T-9R-22R-10R
@COL 16R-18T-19R-17F
@ROW 11-5
@ROW 8-16
@FLOW 1-2-3-4-6N-5N-7-8Y-9-22-10-4
@FLOW 5Y-16-18N-19-17
@FLOW 18Y-17
@FLOW 6Y-11N-12-4
@FLOW 11Y-13Y-14-4
@FLOW 13N-15-4
@FLOW 8N-22-10

@BOX 1.0
GENERATE CHART TEXT
@BOX 2.0
FORM CODELIST TO
DETERMINE ORDER OF
BOXES, JUMPS AND LABELS
[DOC03.1.1.1]
SELECT CHART TEXT
OUTPUT STREAM
@BOX 3.0
SET PTR TO SCAN CODELIST
@BOX 4.0
EXAMINE NEXT ENTRY IN
CODE LIST
@BOX 5.0
IS IT THE END MARKER
@BOX 6.0
IS IT A JUMP ENTRY?
@BOX 7.0
OUTPUT BOX HEADING
IF MONITOR 2 SET
@BOX 8.0
IS THE SPECIFIED BOX LABELLED?
@BOX 9.0
STORE BOX NO IN
LABEL LIST
COPY LABEL TO
CURRENT OUTPUT
[DOC03.1.1.3]
@BOX 10.0
COPY BOX TEXT TO
CURRENT OUTPUT INSERTING
INTERNAL CONDITIONAL JUMPS
WHERE NECESSARY
@BOX 11.0
IS IT UNCONDITIONAL?
@BOX 12.0
REMOVE LAST NL &
COPY CJUMP TEXT
TO CURRENT OUTPUT
[DOC03.1.1.3]
@BOX 13.0
IS JUMP TO NEXT BOX IN CODE LIST?
@BOX 14.0
DECREMENT LABEL COUNT FOR NEXT BOX
@BOX 15.0
COPY JUMP TEXT TO
CURRENT OUTPUT
[DOC03.1.1.3]
@BOX 16.0
COPY EOC WARNING
TO CURRENT OUTPUT
RESELECT ORIGINAL OUTPUT
STORE END MARKER IN LABEL LIST
@BOX 18.0
IS MONITOR = 0
@BOX 19.0
LIST CODE
[DOC03.1.1.4]
@BOX 17.0
RETURN
@BOX 22.0
SET SWITCH IF BOX IS
CONDITIONAL BRANCH
@BOX 1.1
GENERATE.CHART.TEXT: BEGIN
$IN JMPSW,T1;
@BOX 2.1
#DOC03.1.1.1
SELECT.OUTPUT(IN.OUT);
@BOX 3.1
0 => CLPTR;
@BOX 4.1
BNO OF CODELIST[CLPTR] =>
BNO OF NEXT.EL;
JMP.INFO OF CODELIST[CLPTR] =>
JMP.INFO OF NEXT.EL;
1 +> CLPTR;
@BOX 5.1
IF BNO OF NEXT.EL = 0
@BOX 6.1
IF JMP.INFO OF NEXT.EL >= 1
@BOX 7.1
IF MONITOR = 2 THEN
CAPTION (%"$LBOX");
OUTI(BNO OF NEXT.EL,1);
NEWLINES(1);
FI
@BOX 8.1
IF LAB.COUNT OF BOXTAB[BNO
OF NEXT.EL] = 0
@BOX 9.1
BNO OF NEXT.EL=>LABLIST[1+>LABPTR];
COPYSTR(LABL,TDIND,BNO OF NEXT.EL);
NEWLINES(1);
@BOX 10.1
IF TEXTPTR OF BOXTAB[BNO OF NEXT.EL] => I /= 0 THEN
   CLPTR=>T1;
   WHILE BTB[I] /= EOBWC DO
      IF BTB[I]='@ AND JMPSW = 1 AND BTB[I+1]='>
         AND BTB[I+2]='> THEN
         BNO OF CODELIST[CLPTR] => BNO OF NEXT.EL;
         CLPTR + 1 => T1;
         COPYSTR(RELJUMP,TDIND,BNO OF NEXT.EL);
         4 +>I;
   ELSE
      OUTCH(BTB[I]);
      1 +> I;
      FI
   OD
T1 => CLPTR;
FI
@BOX 11.1
IF JMP.INFO OF NEXT.EL = 1
@BOX 12.1
SET.O.POS(O.POS()-1);
COPYSTR(RELJUMP,TDIND,BNO OF NEXT.EL);
NEWLINES(1);
@BOX 13.1
IF BNO OF NEXT.EL /= BNO
OF CODELIST[CLPTR]
@BOX 14.1
1 -> LAB.COUNT OF BOXTAB[BNO
OF CODELIST[CLPTR]];
@BOX 15.1
COPYSTR(JUMP,TDIND,BNO OF NEXTEL);
@BOX 16.1
64 => LABLIST[1+>LABPTR];
OUTCH(EOCWC);
SELECT.OUTPUT(OLD.OUT);
@BOX 18.1
IF MONITOR = 0
@BOX 19.1
#DOC03.1.1.4
@BOX 17.1
END
@BOX 22.1
IF JMP.INFO OF CODELIST[CLPTR] > 1 THEN
   1 => JMPSW;
ELSE
   0 => JMPSW;
FI
@END

@TITLE DOC03.1.1.1(1,8)
@COL 1S-2R-4R-5T-17R-6T-7T-8T-9T-10N-16R-11T-12T-13R-14R-15F
@FLOW 1-2-4-5N-17-6N-7Y-8N-9N-4
@FLOW 5Y-4
@FLOW 6Y-4
@FLOW 9Y-7
@FLOW 8Y-7
@FLOW 12N-14
@FLOW 7N-16-11Y-12Y-13-14-15
@FLOW 11N-17

@BOX 1.0
ORDER BOXES
@BOX 2.0
SET F = 0(I.E. NO FINISH BOX)
INITIALISE CODE LIST
CLEAR ALL PLANTED MARKERS
SET K = 1
SELECT START BOX
@BOX 4.0
PLANT BOX
[DOC03.1.1.2]
@BOX 5.0
SELECT NEXT BOX IN PRIMARY
FLOW IF ONE EXISTS
@BOX 6.0
IS IT THE START OF
A PRIMARY FLOW PATH?
@BOX 7.0
SELECT NEXT BOX IN PRIMARY
FLOW IF ONE EXISTS
@BOX 8.0
IS CURRENT BOX NO. > K?
@BOX 9.0
IS BOX NULL/ANNOT/UNDEFINED OR PLANTED
@BOX 11.0
K > MAXIMUM BOX NO?
@BOX 12.0
IS THERE A FINISH BOX
@BOX 13.0
ENTER FINISH BOX ON CODE LIST
@BOX 14.0
ENTER END MARK ON CODE LIST
@BOX 15.0
RETURN
@BOX 16.0
INCREMENT K
@BOX 17.0
SELECT BOX K
@BOX 1.1
ORDER.BOXES: BEGIN
@BOX 2.1
0 => FIN.BOX => CLPTR;
START.BOX => J;
1 => K;
FOR I <64 DO
  0 => PLANTED OF BOXTAB[I];
OD
@BOX 4.1
#DOC03.1.1.2
@BOX 5.1
IF PFLOW.LINK OF BOXTAB[J] => J /= 0
@BOX 6.1
IF T OF BOXTAB[J] /= 0 AND
   INFLOW OF BOXTAB[J] = 0
@BOX 7.1
IF PFLOW.LINK OF BOXTAB[J] => J = 0
@BOX 8.1
IF J > K
@BOX 9.1
IF T OF BOXTAB[J] < 3 OR
PLANTED OF BOXTAB[J] /= 0
@BOX 11.1
IF K < 64
@BOX 12.1
IF FIN.BOX = 0
@BOX 13.1
FIN.BOX => BNO OF CODELIST[CLPTR];
0 => JMP.INFO OF CODELIST[CLPTR];
1 +> CLPTR;
@BOX 14.1
0 => BNO OF CODELIST[CLPTR];
0 => JMP.INFO OF CODELIST[CLPTR];
1 +> CLPTR;
@BOX 16.1
1 +> K;
@BOX 15.1
END
@BOX 17.1
K => J;
@END

@TITLE DOC03.1.1.2(1,8)
@COL 1S-13R-14T-2T-3R-4T-5R-6R-7T-8R-12F
@COL 10R-11R
@ROW 6-10
@FLOW 1-13-14N-2N-3-4Y-5-10-11-12
@FLOW 4N-6-7Y-8-12
@FLOW 7N-12
@FLOW 2Y-10
@FLOW 14Y-12

@BOX 1.0
PLANT BOX
@BOX 13.0
MARK BOX NOT START
OF PRIMARY FLOW
@BOX 14.0
IS BOX NULL/ANNOT?
@BOX 2.0
IS BOX ALREADY PLANTED?
@BOX 3.0
MARK BOX PLANTED
@BOX 4.0
IS IT THE FINISH BOX?
@BOX 5.0
SET FINISH BOX = J
@BOX 6.0
ENTER BOX ON CODELIST
@BOX 7.0
HAS BOX ANY SECONDARY FLOW?
@BOX 8.0
FIND 1ST NON-NULL/ANNOT BOX
ON SECONDARY FLOW PATH
ENTER CJUMP TO IT ON CODELIST
INC ITS LABEL COUNT
@BOX 10.0
CLEAR PRIMARY FLOW LINK OF THIS BOX
INC LABEL COUNT FOR BOX
@BOX 11.0
ENTER JUMP TO THIS BOX ON CODELIST
@BOX 12.0
RETURN
@BOX 1.1
PLANT.BOX: BEGIN
@BOX 13.1
1 => INFLOW OF BOXTAB[J];
@BOX 14.1
IF T OF BOXTAB[J] < 3
@BOX 2.1
IF PLANTED OF BOXTAB[J] /= 0
@BOX 3.1
1 => PLANTED OF BOXTAB[J];
@BOX 4.1
IF T OF BOXTAB[J] /= 6
@BOX 5.1
J => FIN.BOX;
@BOX 6.1
J => BNO OF CODELIST[CLPTR];
0 => JMP.INFO OF CODELIST[CLPTR];
1 +> CLPTR;
@BOX 7.1
IF SFLOW.LINK OF BOXTAB[J] => SJ = 0
@BOX 8.1
WHILE T OF BOXTAB[SJ] < 3 DO
   PFLOW.LINK OF BOXTAB[SJ] => SJ;
OD
SJ => BNO OF CODELIST[CLPTR];
2 => JMP.INFO OF CODELIST[CLPTR];
1 +> CLPTR;
1 +> LAB.COUNT OF BOXTAB[SJ];
@BOX 10.1
0 => PFLOW.LINK OF BOXTAB[J];
1 +> LAB.COUNT OF BOXTAB[J];
@BOX 11.1
J => BNO OF CODELIST[CLPTR];
1 => JMP.INFO OF CODELIST[CLPTR];
1 +> CLPTR;
@BOX 12.1
END
@END

@TITLE DOC03.1.1.3(1,9)
@COL 1S-2R-4R-5R-3T-6R-7F
@FLOW 1-2-4-5-3Y-6-7
@FLOW 3N-7

@BOX 1.0
COPY STR(STRING,CHARTNO,BOXNO)
@BOX 2.0
COPY ALL BUT LAST CHAR STRING TO
CURRENT OUTPUT
@BOX 4.0
WRITE CHART NO IN OCTAL
TO CURRENT OUTPUT
@BOX 5.0
WRITE BOX NO IN OCTAL
TO CURRENT OUTPUT
@BOX 3.0
LAST CHAR REQUIRED?
@BOX 6.0
ADD LAST CHAR OF STRING
@BOX 7.0
RETURN
@BOX 1.1
PROC COPYSTR(STRING,CHTNO,BXNO);
$IN I,J;
@BOX 2.1
FOR I < SIZE(STRING)-1 DO
   OUTCH(STRING^[I]);
OD
@BOX 4.1
OUTCH(CHTNO /100 => I+ '0);
OUTCH(CHTNO -(I*100)/10=>J+ '0);
OUTCH(I*10+J*10-:CHTNO + '0);
@BOX 5.1
BXNO & %3F => J;
OUTCH(J/10 => I + '0);
OUTCH(I*10 -: J + '0);
@BOX 3.1
IF BXNO > 63
@BOX 6.1
OUTCH(STRING^[SIZE(STRING)-1]);
@BOX 7.1
END;
@END
@TITLE DOC03.1.1.4(1,8)
@COL 1S-2R-3R-6T-7R-8R-9F
@FLOW 1-2-3-6Y-7-3
@FLOW 6N-8-9
@BOX 1.0
LIST CODE
@BOX 2.0
SET PTR TO CUR.CHT
RESELECT OUTPUT AS INPUT
RESELECT ORIGINAL OUTPUT
@BOX 3.0
COPY OUTPUT UNTIL WC
@BOX 6.0
CR WC?
@BOX 7.0
OUTPUT CROSSREF
@BOX 8.0
RESELECT INPUT AS OUTPUT
RESELECT FILE INPUT
@BOX 9.0
RETURN
@BOX 1.1
LIST.CODE: BEGIN;
@BOX 2.1
SELECT.INPUT(IN.OUT);
SET.IPOS(CUR.TPOS);
0 => I;
@BOX 3.1
WHILE INCH() => SYM /= CRWC /= PWC /= EOCWC DO
   IF I = 0 THEN
      SPACES(24);
   FI
   SYM - '$L => I;
   OUTCH(SYM);
OD
@BOX 6.1
IF SYM /= CRWC /= PWC
@BOX 7.1
SPACES(16);
CAPTION(%"CROSS REFERENCE");
FOR 4 DO INCH() OD
NEWLINES(1);
0 => I;
@BOX 8.1
OUTCH('$P);
SELECT.INPUT(IN);
@BOX 9.1
END
@END
@TITLE DOC03.1.2(1,8)
@COL 1S-3R-4R-5R-6T-11T-12R-14T-15R-7R-9R
@COL 8T-10R-13F
@ROW 11-8
@FLOW 1-3-4-5-6N-11NOT FOUND-12-5
@FLOW 11FOUND-14PWC-15-5
@FLOW 14Y-7-5
@FLOW 6Y-8N-9-5
@FLOW 8Y-10-13
@BOX 1.0
GENERATE FILE TEXT
@BOX 3.0
REDEFINE CURRENT OUTPUT AS
AN INPUT STREAM AND SELECT IT
SET INPUT POINTER TO START
OF REQUIRED CHART TEXT
@BOX 4.0
SELECT CURRENT FILE
AS OUTPUT
@BOX 5.0
COPY FROM INPUT
TO OUTPUT UNTIL WC
@BOX 6.0
IS WC END OF CHART
@BOX 7.0
STACK INPUT POINTER
ON CROSS REF STACK
AND SET TO START OF
NEW CHART
@BOX 14.0
IS WC = CRWC?
@BOX 15.0
GENERATE LABELS
[3.1.2.1]
SKIP TO NEWLINE
OUTPUT NEWLINE
@BOX 11.0
FIND CROSS REF CHART
IN TITLE DIRECTORY
@BOX 12.0
SELECT ORIGINAL OUTPUT
TO MONITOR FAULTAND
REST OF LINE

RESELECT CURRENT FILE OUTPUT
@BOX 8.0
CROSS REF STACK EMPTY?
@BOX 9.0
UNSTACK INPUT POINTER
SKIP TO END OF LINE
OUTPUT NEWLINE
@BOX 10.0
BREAK CURRENT FILE OUTPUT
RESELECT ORIGINAL OUTPUT
@BOX 13.0
RETURN
@BOX 1.1
GENERATE.FILE.TEXT: BEGIN;
$IN OUT,NO.PARS,LOSE;
$IN32 THASH;
@BOX 3.1
SELECT.INPUT(IN.OUT) ; SET.I.POS(INIT.CHT);
0 => CRS.PTR;
@BOX 4.1
END.INPUT(IN,0);
DEFINE.OUTPUT(-1,CUR.FILE,0,IFSIZE) => OUT;
SELECT.OUTPUT(OUT);
@BOX 5.1
WHILE INCH()=>SYM/=CRWC/=PWC/=EOCWC DO
OUTCH(SYM);
OD
@BOX 6.1
IF SYM = EOCWC
@BOX 7.1
I.POS() => CRS[CRSPTR] ; 1 +> CRSPTR ;
SET.IPOS(TITPOS OF TITLE.DIR[I]);
@BOX 14.1
IF SYM = CRWC
@BOX 15.1
#DOC03.1.2.1
WHILE INCH()=>SYM /= '$L DO OD
OUTCH('$L);
@BOX 11.1
INCH()<<-8 ! INCH()<<-8 !
INCH()<<-8 !INCH() =>THASH;
FOR I < TD.IND DO
IF THASH = TIT.HASH OF TITLE.DIR[I] @>>
OD
@BOX 12.1
SELECT.OUTPUT(OLD.OUT);
CAPTION(%"$LCROSS REF NOT FOUND$L");
WHILE INCH() => SYM /= '$L DO OUTCH(SYM) OD
1+>FCOUNT;SELECT.OUTPUT(OUT);
@BOX 8.1
IF 1 -> CRSPTR >= 0
@BOX 9.1
SET.IPOS(CRS[CRS.PTR]);
WHILE INCH()=>SYM /= '$L DO OD
OUTCH('$L);
@BOX 10.1
END.OUTPUT(OUT,0);
SELECT.OUTPUT(OLD.OUT);
@BOX 13.1
END
@END

@TITLE DOC03.1.2.1(1,8)
@COL 1S-2R-3T-4R-5R
@COL 6F
@ROW 5-6
@FLOW 1-2-3OK-4-5-3NONE-6
@BOX 1.0
GENERATE LABELS
@BOX 2.0
PICK UP POINTER TO LABEL LIST
@BOX 3.0
PICK UP NEXT BOX NUMBER
FROM LABEL LIST
@BOX 4.0
OUTPUT COMMA OR NEWLINE
AS REQUIRED
@BOX 5.0
OUTPUT LABEL
@BOX 6.0
END
@BOX 1.1
::GENERATE LABELS
@BOX 2.1
LABPOS OF TITLE.DIR[I] => LABPTR;
-1=>J;
@BOX 3.1
IF LABLIST[1+>LABPTR] >63
@BOX 4.1
IF 1+>J>0 THEN
   OUTCH(',);
   IF J & 7 = 0 THEN
      NEWLINES(1);
   FI
FI
@BOX 5.1
COPYSTR(LABL,I+1,LABLIST[LABPTR]!%40);
@BOX 6.1
::END
@END

