User Tools

Site Tools


cdc:nos2.source:opl.opl871:deck:fsework

Deck FSEWORK

2 Modifications

Listing Sections

Source

Seq #  *Modification Id* Act 
----------------------------+
00001  M01S00001.fsework +++|PROC FSEWORK;
00002  M01S00002.fsework +++| BEGIN
00003  M01S00003.fsework +++|
00004  M01S00004.fsework +++|
00005  M01S00005.fsework +++|#
00006  M01S00006.fsework +++|***       FSEWORK - WORKFILE ACCESS METHOD FOR FULL SCREEN EDITOR.
00007  M01S00007.fsework +++|*
Line S00008 Modification History
M01 (Added by) fsework
M02 (Updated by) 281l803
Seq #  *Modification Id* Act 
----------------------------+
00008  M02S00008.281l803 ---|*         COPYRIGHT CONTROL DATA CORPORATION, 1983.
00009  M01S00001.281l803 +++|*         COPYRIGHT CONTROL DATA SYSTEMS INC.  1992.
00010  M01S00009.fsework +++|#
00011  M01S00010.fsework +++|
00012  M01S00011.fsework +++|  DEF LISTCON #0#;
00013  M01S00012.fsework +++|
00014  M01S00013.fsework +++|CONTROL EJECT;                         # UNIVERSAL DEFINITIONS       #
00015  M01S00014.fsework +++|
00016  M01S00015.fsework +++|*IFCALL SINGLE,COMFSGL
00017  M01S00016.fsework +++|*IFCALL ONLY,COMFONL
00018  M01S00017.fsework +++|*IFCALL MULTI,COMFMLT
00019  M01S00018.fsework +++|*CALL COMFFSE
00020  M01S00019.fsework +++|
00021  M01S00020.fsework +++|
00022  M01S00021.fsework +++|  CONTROL IFEQ MULTI,1;
00023  M01S00022.fsework +++|    DEF RECALL(AA) #SMFRCL(AA)#;
00024  M01S00023.fsework +++|    DEF DELAY      #SMFDLY#;
00025  M01S00024.fsework +++|    XREF PROC SMFRCL;
00026  M01S00025.fsework +++|    XREF PROC SMFDLY;
00027  M01S00026.fsework +++|  CONTROL FI;
00028  M01S00027.fsework +++|  CONTROL IFEQ SINGLE,1;
00029  M01S00028.fsework +++|    XREF PROC RECALL;
00030  M01S00029.fsework +++|    DEF DELAY      #RECALL(0)#;
00031  M01S00030.fsework +++|  CONTROL FI;
00032  M01S00031.fsework +++|
00033  M01S00032.fsework +++|  XREF                       # SYSTEM PROCS      #
00034  M01S00033.fsework +++|    BEGIN
00035  M01S00034.fsework +++|    PROC WRITE;
00036  M01S00035.fsework +++|    PROC REWRITE;
00037  M01S00036.fsework +++|    PROC RPHR;
00038  M01S00037.fsework +++|    PROC RPHRLS;
00039  M01S00038.fsework +++|    PROC SKIPEI;
00040  M01S00039.fsework +++|    PROC REWIND;
00041  M01S00040.fsework +++|    PROC READ;
00042  M01S00041.fsework +++|    PROC WRITER;
00043  M01S00042.fsework +++|    PROC WRITEW;
00044  M01S00043.fsework +++|    PROC REWRITR;
00045  M01S00044.fsework +++|    CONTROL IFEQ SINGLE,1;
00046  M01S00045.fsework +++|      PROC EVICT;
00047  M01S00046.fsework +++|    CONTROL FI;
00048  M01S00047.fsework +++|    END
00049  M01S00048.fsework +++|
00050  M01S00049.fsework +++|  XREF                       # COMPASS PROCS     #
00051  M01S00050.fsework +++|    BEGIN
00052  M01S00051.fsework +++|    PROC MOVEWD;
00053  M01S00052.fsework +++|    PROC EXCHWD;
00054  M01S00053.fsework +++|    FUNC MOVELN;
00055  M01S00054.fsework +++|    FUNC LINESZ;
00056  M01S00055.fsework +++|    END
00057  M01S00056.fsework +++|
00058  M01S00057.fsework +++|  XREF
00059  M01S00058.fsework +++|    BEGIN
00060  M01S00059.fsework +++|*CALL COMFXSB
00061  M01S00060.fsework +++|    END
00062  M01S00061.fsework +++|
00063  M01S00062.fsework +++|  XDEF
00064  M01S00063.fsework +++|    BEGIN
00065  M01S00064.fsework +++|*CALL COMFXWK
00066  M01S00065.fsework +++|    END
00067  M01S00066.fsework +++|
00068  M01S00067.fsework +++|                             # COMMON DATA       #
00069  M01S00068.fsework +++|
00070  M01S00069.fsework +++|CONTROL IFEQ MULTI,1;
00071  M01S00070.fsework +++|  XREF ARRAY RENTSTK [1:MAXREENT];     # SUBROUTINE STACK  #
00072  M01S00071.fsework +++|    BEGIN
00073  M01S00072.fsework +++|    ITEM RSTK;
00074  M01S00073.fsework +++|    END
00075  M01S00074.fsework +++|  XREF ITEM RSTKPTR;
00076  M01S00075.fsework +++|  XREF PROC WIOSTAT;
00077  M01S00076.fsework +++|CONTROL FI;
00078  M01S00077.fsework +++|
00079  M01S00078.fsework +++|*CALL COMFDS1
00080  M01S00079.fsework +++|*CALL COMFVD2
00081  M01S00080.fsework +++|*CALL COMFDS2
00082  M01S00081.fsework +++|PAGE
00083  M01S00082.fsework +++|
00084  M01S00083.fsework +++|
00085  M01S00084.fsework +++|PROC INITFET(BUFF,LEN);      # INITIALIZE FET    #
00086  M01S00085.fsework +++|  BEGIN
00087  M01S00086.fsework +++|#
00088  M01S00087.fsework +++|**        INITFET - INITIALIZE FILE ENVIRONMENT TABLE.
00089  M01S00088.fsework +++|*
00090  M01S00089.fsework +++|*         INITFET IS SPECIALIZED FOR THE WORKFILE MANAGER.  THE FET
00091  M01S00090.fsework +++|*         IS ASSUMED TO BE MAPPED BY THE BASED ARRAY "FET". THE
00092  M01S00091.fsework +++|*         LENGTH OF THE FET IS ASSUMED TO BE AT LEAST SEVEN WORDS,
00093  M01S00092.fsework +++|*         AND RANDOM I/O FLAGS WILL BE SET.
00094  M01S00093.fsework +++|*
00095  M01S00094.fsework +++|*         ENTRY  BUFF - THE ARRAY PROVIDED AS A BUFFER.
00096  M01S00095.fsework +++|*                LEN - INTEGER LENGTH OF BUFFER.
00097  M01S00096.fsework +++|*
00098  M01S00097.fsework +++|*         EXIT   FET - INITIALIZED FOR RANDOM I/O.
00099  M01S00098.fsework +++|*                QUARTER - INITIALIZED AS APPROX LEN/4.
00100  M01S00099.fsework +++|#
00101  M01S00100.fsework +++|  ARRAY BUFF;;
00102  M01S00101.fsework +++|  ITEM LEN;
00103  M01S00102.fsework +++|  QUARTER=(LEN+O"300")/4;
00104  M01S00103.fsework +++|  FETNAM = WORKNAM;
00105  M01S00104.fsework +++|  FETCOD = 0;
00106  M01S00105.fsework +++|  FETDUN = TRUE;
00107  M01S00106.fsework +++|  FETR = TRUE;
00108  M01S00107.fsework +++|  FETW = FALSE;
00109  M01S00108.fsework +++|  FETOUT = LOC(BUFF); FETLIM = LOC(BUFF) + LEN;
00110  M01S00109.fsework +++|  FETL = 2;
00111  M01S00110.fsework +++|  FETFIR = LOC(BUFF); FETIN = LOC(BUFF);
00112  M01S00111.fsework +++|  END
00113  M01S00112.fsework +++|
00114  M01S00113.fsework +++|
00115  M01S00114.fsework +++|FUNC BUFAVAIL I;
00116  M01S00115.fsework +++|  BEGIN
00117  M01S00116.fsework +++|#
00118  M01S00117.fsework +++|**        BUFAVAIL - FUNCTION TO COMPUTE BUFFER FREE SPACE.
00119  M01S00118.fsework +++|*
00120  M01S00119.fsework +++|*         BUFAVAIL COMPUTES THE SPACE AVAILABLE IN THE CIRCULAR
00121  M01S00120.fsework +++|*         BUFFER ASSIGNED TO THE FET MAPPED BY THE BASED ARRAY
00122  M01S00121.fsework +++|*         "FET".
00123  M01S00122.fsework +++|*
00124  M01S00123.fsework +++|*         ENTRY  FET - FET.
00125  M01S00124.fsework +++|*
00126  M01S00125.fsework +++|*         EXIT   BUFAVAIL - WORDS OF SPACE STILL AVAILABLE FOR DATA.
00127  M01S00126.fsework +++|#
00128  M01S00127.fsework +++|  IF FETIN LS FETOUT THEN BUFAVAIL=FETOUT-FETIN;
00129  M01S00128.fsework +++|  ELSE BUFAVAIL=(FETLIM-FETFIR)-(FETIN-FETOUT);
00130  M01S00129.fsework +++|  END
00131  M01S00130.fsework +++|
00132  M01S00131.fsework +++|
00133  M01S00132.fsework +++|FUNC BUFUSAGE I;
00134  M01S00133.fsework +++|  BEGIN
00135  M01S00134.fsework +++|#
00136  M01S00135.fsework +++|**        BUFUSAGE - FUNCTION TO COMPUTE BUFFER UTILIZATION.
00137  M01S00136.fsework +++|*
00138  M01S00137.fsework +++|*         BUFUSAGE IS THE COUTERPART TO BUFAVAIL, COMPUTING THE
00139  M01S00138.fsework +++|*         NUMBER OF WORDS ALREADY USED IN THE CIRCULAR BUFFER
00140  M01S00139.fsework +++|*         ASSIGNED TO THE FET MAPPED BY BASED ARRAY "FET".
00141  M01S00140.fsework +++|*
00142  M01S00141.fsework +++|*         ENTRY  FET - FET.
00143  M01S00142.fsework +++|*
00144  M01S00143.fsework +++|*         EXIT   BUFUSAGE - RESULT.
00145  M01S00144.fsework +++|#
00146  M01S00145.fsework +++|  IF FETIN GQ FETOUT THEN BUFUSAGE=FETIN-FETOUT;
00147  M01S00146.fsework +++|  ELSE BUFUSAGE=(FETLIM-FETFIR)-(FETOUT-FETIN);
00148  M01S00147.fsework +++|  END
00149  M01S00148.fsework +++|
00150  M01S00149.fsework +++|
00151  M01S00150.fsework +++|FUNC LSTUSAGE I;
00152  M01S00151.fsework +++|  BEGIN
00153  M01S00152.fsework +++|#
00154  M01S00153.fsework +++|**        LSTUSAGE - COMPUTE UTILIZATION OF READ LIST.
00155  M01S00154.fsework +++|*
00156  M01S00155.fsework +++|*         LSTUSAGE COMPUTES THE NUMBER OF WORDS USED IN THE READ
00157  M01S00156.fsework +++|*         LIST.
00158  M01S00157.fsework +++|*
00159  M01S00158.fsework +++|*         ENTRY  RDIN, RDOUT - BOUNDS FOR PORTION OF LIST USED.
00160  M01S00159.fsework +++|*                LSTSIZE - SIZE OF LIST.
00161  M01S00160.fsework +++|*
00162  M01S00161.fsework +++|*         EXIT   LSTUSAGE - RESULT.
00163  M01S00162.fsework +++|#
00164  M01S00163.fsework +++|  LSTUSAGE=RDIN-RDOUT;
00165  M01S00164.fsework +++|  IF RDIN LS RDOUT THEN LSTUSAGE=LSTSIZE-1-RDOUT+RDIN;
00166  M01S00165.fsework +++|  END
00167  M01S00166.fsework +++|
00168  M01S00167.fsework +++|
00169  M01S00168.fsework +++|FUNC LSTAVAIL I;
00170  M01S00169.fsework +++|  BEGIN
00171  M01S00170.fsework +++|#
00172  M01S00171.fsework +++|**        LSTAVAIL - COMPUTE SPACE AVAILABLE IN READ LIST.
00173  M01S00172.fsework +++|*
00174  M01S00173.fsework +++|*         LSTAVAIL COMPUTES THE NUMBER OF WORDS AVAILABLE FOR USE
00175  M01S00174.fsework +++|*         IN THE RANDOM READ LIST.
00176  M01S00175.fsework +++|*
00177  M01S00176.fsework +++|*         ENTRY - RDIN, RDOUT, LSTSIZE - CONTROL READ LIST.
00178  M01S00177.fsework +++|*
00179  M01S00178.fsework +++|*         EXIT   LSTAVAIL - RESULT.
00180  M01S00179.fsework +++|*
00181  M01S00180.fsework +++|*         CALLS  LSTUSAGE.
00182  M01S00181.fsework +++|#
00183  M01S00182.fsework +++|  LSTAVAIL=LSTSIZE-1-LSTUSAGE;
00184  M01S00183.fsework +++|  END
00185  M01S00184.fsework +++|
00186  M01S00185.fsework +++|
00187  M01S00186.fsework +++|PROC RDWBUF(LENGTH);
00188  M01S00187.fsework +++|  BEGIN
00189  M01S00188.fsework +++|#
00190  M01S00189.fsework +++|**        RDWBUF - READ WORDS FROM BUFFER WITH NO I/O.
00191  M01S00190.fsework +++|*
00192  M01S00191.fsework +++|*         RDWBUF FUNCTIONS AS A SPECIALIZED READW MACRO.  A STANDARD
00193  M01S00192.fsework +++|*         FET IS ASSUMED AND THE DATA TRANSFER WORKING BUFFER IS
00194  M01S00193.fsework +++|*         ASSUMED TO BE MAPPED BY A STANDARD BASED ARRAY.  MOST
00195  M01S00194.fsework +++|*         IMPORTANT, THIS ROUTINE IS GUARANTEED TO NEVER CALL CIO.
00196  M01S00195.fsework +++|*         THE CALLER IS RESPONSIBLE TO ASSURE THAT THE CIRCULAR
00197  M01S00196.fsework +++|*         BUFFER HAS ENOUGH DATA TO SATISFY THE REQUEST.
00198  M01S00197.fsework +++|*
00199  M01S00198.fsework +++|*         ENTRY  LENGTH - AMMOUNT OF DATA NEEDED.
00200  M01S00199.fsework +++|*                FET - FET AND CIRCULAR BUFFER HAVE ENOUGH DATA.
00201  M01S00200.fsework +++|*                TOO - MAPPED TO USER'S WORKING BUFFER.
00202  M01S00201.fsework +++|*
00203  M01S00202.fsework +++|*         EXIT   FET - INDICATES DATA TRANSFERRED.
00204  M01S00203.fsework +++|*                TOO - DATA IS TRANSFERRED.
00205  M01S00204.fsework +++|*
00206  M01S00205.fsework +++|*         CALLS  MOVEWD, TRAGIC, BUFUSAGE.
00207  M01S00206.fsework +++|*
00208  M01S00207.fsework +++|*         USES   FROM.
00209  M01S00208.fsework +++|#
00210  M01S00209.fsework +++|  ITEM LENGTH, X1;
00211  M01S00210.fsework +++|  IF BUFUSAGE LS LENGTH OR LENGTH LS 0 THEN
00212  M01S00211.fsework +++|    BEGIN
00213  M01S00212.fsework +++|    TRAGIC(" WORKFILE BUFFER EMPTY ON READ.$");
00214  M01S00213.fsework +++|    END
00215  M01S00214.fsework +++|  P<FROM>=FETOUT;
00216  M01S00215.fsework +++|  IF FETIN GR FETOUT OR FETLIM-FETOUT GR LENGTH THEN
00217  M01S00216.fsework +++|    BEGIN
00218  M01S00217.fsework +++|    MOVEWD(LENGTH,FROM,TOO);
00219  M01S00218.fsework +++|    FETOUT=FETOUT+LENGTH;
00220  M01S00219.fsework +++|    END
00221  M01S00220.fsework +++|  ELSE
00222  M01S00221.fsework +++|    BEGIN
00223  M01S00222.fsework +++|    X1=FETLIM-FETOUT;
00224  M01S00223.fsework +++|    MOVEWD(X1,FROM,TOO);
00225  M01S00224.fsework +++|    P<TOO>=LOC(TOO)+X1;
00226  M01S00225.fsework +++|    X1=LENGTH-X1;
00227  M01S00226.fsework +++|    P<FROM>=FETFIR;
00228  M01S00227.fsework +++|    MOVEWD(X1,FROM,TOO);
00229  M01S00228.fsework +++|    FETOUT=FETFIR+X1;
00230  M01S00229.fsework +++|    END
00231  M01S00230.fsework +++|  END
00232  M01S00231.fsework +++|
00233  M01S00232.fsework +++|
00234  M01S00233.fsework +++|PROC WTWBUF(LENGTH);
00235  M01S00234.fsework +++|  BEGIN
00236  M01S00235.fsework +++|#
00237  M01S00236.fsework +++|**        WTWBUF - WRITE WORDS TO BUFFER WTH NO I/O.
00238  M01S00237.fsework +++|*
00239  M01S00238.fsework +++|*         WTWBUF PERFORMS THE ROLE OF THE WRITEW MACRO, BUT IS
00240  M01S00239.fsework +++|*         SPECIALIZED TO USE AN ASSUMED FET AND WORKING BUFFER, AND
00241  M01S00240.fsework +++|*         IS GUARANTEED TO NEVER PERFORM ANY CIO CALLS.  THE CALLER
00242  M01S00241.fsework +++|*         IS RESPONSIBLE TO ASSURE THE CIRCULAR BUFFER HAS ROOM TO
00243  M01S00242.fsework +++|*         ACCEPT THE DATA.
00244  M01S00243.fsework +++|*
00245  M01S00244.fsework +++|*         ENTRY  LENGTH - NUMBER OF WORDS.
00246  M01S00245.fsework +++|*                FET - THE CIRCULAR BUFFER HAS ROOM.
00247  M01S00246.fsework +++|*                FROM - MAPPED ONTO WORKING BUFFER.
00248  M01S00247.fsework +++|*
00249  M01S00248.fsework +++|*         EXIT   FET - THE CIRCULAR BUFFER HAS DATA.
00250  M01S00249.fsework +++|*
00251  M01S00250.fsework +++|*         CALLS  BUFAVAIL, TRAGIC, MOVEWD.
00252  M01S00251.fsework +++|*
00253  M01S00252.fsework +++|*         USES   TOO.
00254  M01S00253.fsework +++|#
00255  M01S00254.fsework +++|  ITEM LENGTH, X1;
00256  M01S00255.fsework +++|  IF BUFAVAIL LS LENGTH OR LENGTH LS 0 THEN
00257  M01S00256.fsework +++|    BEGIN
00258  M01S00257.fsework +++|    TRAGIC(" WORKFILE BUFFER FULL ON WRITE.$");
00259  M01S00258.fsework +++|    END
00260  M01S00259.fsework +++|  P<TOO>=FETIN;
00261  M01S00260.fsework +++|  IF FETOUT GR FETIN OR FETLIM-FETIN GR LENGTH THEN
00262  M01S00261.fsework +++|    BEGIN
00263  M01S00262.fsework +++|    MOVEWD(LENGTH,FROM,TOO);
00264  M01S00263.fsework +++|    FETIN=FETIN+LENGTH;
00265  M01S00264.fsework +++|    END
00266  M01S00265.fsework +++|  ELSE
00267  M01S00266.fsework +++|    BEGIN
00268  M01S00267.fsework +++|    X1=FETLIM-FETIN;
00269  M01S00268.fsework +++|    MOVEWD(X1,FROM,TOO);
00270  M01S00269.fsework +++|    P<FROM>=LOC(FROM)+X1;
00271  M01S00270.fsework +++|    X1=LENGTH-X1;
00272  M01S00271.fsework +++|    P<TOO>=FETFIR;
00273  M01S00272.fsework +++|    MOVEWD(X1,FROM,TOO);
00274  M01S00273.fsework +++|    FETIN=FETFIR+X1;
00275  M01S00274.fsework +++|    END
00276  M01S00275.fsework +++|  END
00277  M01S00276.fsework +++|
00278  M01S00277.fsework +++|PROC WAIT;
00279  M01S00278.fsework +++|  IOBEGIN(WAIT)
00280  M01S00279.fsework +++|#
00281  M01S00280.fsework +++|**        WAIT - WAIT (RECALL) FOR I/O TO FINISH.
00282  M01S00281.fsework +++|*
00283  M01S00282.fsework +++|*         WAIT DELAYS THIS TASK UNTIL THE FET IS FOUND TO INDICATE
00284  M01S00283.fsework +++|*         COMPLETION OF A PREVIOUS I/O OPERATION.  WAIT IS A NO-OP
00285  M01S00284.fsework +++|*         IF THE FET ALREADY INDICATES COMPLETION.
00286  M01S00285.fsework +++|*
00287  M01S00286.fsework +++|*         ENTRY  FETDUN - SHOWS WHETHER DELAYS REALLY NEEDED.
00288  M01S00287.fsework +++|*
00289  M01S00288.fsework +++|*         EXIT   FETDUN - TRUE.
00290  M01S00289.fsework +++|*
00291  M01S00290.fsework +++|*         CALLS  RECALL.
00292  M01S00291.fsework +++|#
00293  M01S00292.fsework +++|  IF NOT FETDUN THEN
00294  M01S00293.fsework +++|    BEGIN
00295  M01S00294.fsework +++|    RECALL(FET);
00296  M01S00295.fsework +++|    END
00297  M01S00296.fsework +++|  IOEND
00298  M01S00297.fsework +++|
00299  M01S00298.fsework +++|
00300  M01S00299.fsework +++|PROC DISOWNCACHE(PARM);
00301  M01S00300.fsework +++|  BEGIN
00302  M01S00301.fsework +++|#
00303  M01S00302.fsework +++|**        DISOWNCACHE - RELEASE CACHE FRAME FROM OWNERSHIP.
00304  M01S00303.fsework +++|*
00305  M01S00304.fsework +++|*         DISOWNCACHE IS USED TO RELEASE A PAGE FROM OWNERSHIP BY
00306  M01S00305.fsework +++|*         A LEVEL OF THE TREE STRUCTURE.  RELEASE OF A PAGE MAKES
00307  M01S00306.fsework +++|*         IT ELIGIBLE TO BE FLUSHED OUT OF MEMORY (AND POSSIBLY
00308  M01S00307.fsework +++|*         REWRITTEN BACK TO DISK) ANYTIME THE FLUSHCACHE ROUTINE
00309  M01S00308.fsework +++|*         IS NEEDED.  DISOWNCACHE ALSO SETS THE AGE FOR THE PAGE
00310  M01S00309.fsework +++|*         SO THAT FLUSHCACHE CAN DO ANY REWRITES IN THE MANDATORY
00311  M01S00310.fsework +++|*         ORDER OF RELEASE.  THE GLOBAL AGE COUNTER IS INCREMENTED.
00312  M01S00311.fsework +++|*
00313  M01S00312.fsework +++|*         ENTRY  PARM - TREE LEVEL.
00314  M01S00313.fsework +++|*                CACHEOWNED[PARM] - TRUE FOR NON-TRIVIAL OPERATON.
00315  M01S00314.fsework +++|*                AGECOUNT - HIGHEST AGE YET ASSIGNED TO ANY PAGE.
00316  M01S00315.fsework +++|*
00317  M01S00316.fsework +++|*         EXIT   AGECOUNT - INCREMENTED.
00318  M01S00317.fsework +++|*                CACHEOWNED[PARM] - FALSE.
00319  M01S00318.fsework +++|*                CACHEAGE[PARM] - SETUP.
00320  M01S00319.fsework +++|#
00321  M01S00320.fsework +++|  ITEM PARM;
00322  M01S00321.fsework +++|  IF PARM LS 0 OR NOT CACHEOWNED[PARM] THEN RETURN;
00323  M01S00322.fsework +++|  CACHEOWNED[PARM]=FALSE;
00324  M01S00323.fsework +++|  AGECOUNT=AGECOUNT+1;
00325  M01S00324.fsework +++|  CACHEAGE[PARM]=AGECOUNT;
00326  M01S00325.fsework +++|  END                         # OF DISOWNCACHE        #
00327  M01S00326.fsework +++|
00328  M01S00327.fsework +++|
00329  M01S00328.fsework +++|FUNC COUNTCACHE;
00330  M01S00329.fsework +++|  BEGIN
00331  M01S00330.fsework +++|#
00332  M01S00331.fsework +++|**        COUNTCACHE - DETERMINE HOW MANY CACHE FRAMES ARE NOT USED.
00333  M01S00332.fsework +++|*
00334  M01S00333.fsework +++|*         COUNTCACHE TELLS THE CALLER HOW MANY CACHE FRAMES ARE
00335  M01S00334.fsework +++|*         NEITHER OWNED BY ANY TREE LEVEL NOR CONTAIN DATA, WHICH
00336  M01S00335.fsework +++|*         HAS BEEN ALTERED IN THE CACHE BUT NOT YET ON DISK.
00337  M01S00336.fsework +++|*
00338  M01S00337.fsework +++|*         ENTRY  CACHEOWNED[ALL] - SETUP.
00339  M01S00338.fsework +++|*                CACHEDIRTY[ALL] - SETUP.
00340  M01S00339.fsework +++|*
00341  M01S00340.fsework +++|*         EXIT   COUNTCACHE - RESULT.
00342  M01S00341.fsework +++|#
00343  M01S00342.fsework +++|  ITEM I, J;
00344  M01S00343.fsework +++|  J=0;
00345  M01S00344.fsework +++|  FOR I=0 STEP 1 UNTIL MAXCACHE DO IF NOT
00346  M01S00345.fsework +++|    (CACHEDIRTY[I] OR CACHEOWNED[I]) THEN J=J+1;
00347  M01S00346.fsework +++|  COUNTCACHE=J;
00348  M01S00347.fsework +++|  END                         # OF COUNTCACHE     #
00349  M01S00348.fsework +++|
00350  M01S00349.fsework +++|
00351  M01S00350.fsework +++|PROC SEARCHCACHE(M);
00352  M01S00351.fsework +++|  BEGIN
00353  M01S00352.fsework +++|#
00354  M01S00353.fsework +++|**        SEARCHCACHE - DETERMINE BEST CACHEFRAME TO TAKE OVER.
00355  M01S00354.fsework +++|*
00356  M01S00355.fsework +++|*         SEARCHCACHE TESTS ALL CACHE FRAMES FOR THOSE WHICH ARE
00357  M01S00356.fsework +++|*         AVAILABLE TO BE CLAIMED AND USED FOR DIFFERENT DATA THAN
00358  M01S00357.fsework +++|*         PRESENTLY IN MEMORY.  THE OLDEST AVAILABLE FRAME IS
00359  M01S00358.fsework +++|*         CONSIDERED THE BEST CANDIDATE FOR RECYCLE.  A FRAME
00360  M01S00359.fsework +++|*         IS AVAILABLE IF IT IS NEITHER CURRENTLY OWNED BY ANY TREE
00361  M01S00360.fsework +++|*         LEVEL NOR CONTAINS DATA ALTERED IN MEMORY BUT NOT ON DISK.
00362  M01S00361.fsework +++|*
00363  M01S00362.fsework +++|*         ENTRY  CACHEOWNED[ALL] - SETUP.
00364  M01S00363.fsework +++|*                CACHEDIRTY[ALL] - SETUP.
00365  M01S00364.fsework +++|*                CACHEAGE[ALL] - SETUP FOR UNOWNED, UNDIRTY FRAMES.
00366  M01S00365.fsework +++|*
00367  M01S00366.fsework +++|*         EXIT   M - CHOSEN FRAME.
00368  M01S00367.fsework +++|*
00369  M01S00368.fsework +++|*         CALLS  TRAGIC.
00370  M01S00369.fsework +++|#
00371  M01S00370.fsework +++|  ITEM K,L,M;
00372  M01S00371.fsework +++|  M=-1;
00373  M01S00372.fsework +++|  K=999999999;
00374  M01S00373.fsework +++|  FOR L=0 STEP 1 UNTIL MAXCACHE DO
00375  M01S00374.fsework +++|    BEGIN
00376  M01S00375.fsework +++|    IF CACHEAGE[L] LS K AND
00377  M01S00376.fsework +++|      NOT (CACHEDIRTY[L] OR CACHEOWNED[L]) THEN
00378  M01S00377.fsework +++|      BEGIN               # SEARCH OLDEST AVAIL PAGE    #
00379  M01S00378.fsework +++|      M=L;
00380  M01S00379.fsework +++|      K=CACHEAGE[L];
00381  M01S00380.fsework +++|      END
00382  M01S00381.fsework +++|    END
00383  M01S00382.fsework +++|  IF M LS 0 THEN TRAGIC(" ALL WORKFILE BUFFERS ARE FULL.$");
00384  M01S00383.fsework +++|  END                         # OF SEARCHCACHE     #
00385  M01S00384.fsework +++|
00386  M01S00385.fsework +++|
00387  M01S00386.fsework +++|PROC ALLOCCACHE;
00388  M01S00387.fsework +++|  BEGIN
00389  M01S00388.fsework +++|#
00390  M01S00389.fsework +++|**        ALLOCCACHE - LAY CLAIM TO A CACHE FRAME.
00391  M01S00390.fsework +++|*
00392  M01S00391.fsework +++|*         ALLOCCACHE IS CALLED TO CLAIM A FRAME OF MEMORY IN THE
00393  M01S00392.fsework +++|*         DISK CACHE, AND ATTACH IT TO A PARTICULAR TREE LEVEL.
00394  M01S00393.fsework +++|*         THE DISK ADDRESS OF THE DISK DATA IS SAVED IN THE HEADER
00395  M01S00394.fsework +++|*         WORD OF THE CACHE FRAME, SO IT CAN BE MATCHED FOR
00396  M01S00395.fsework +++|*         PURPOSES OF AVOIDING DISK READS.
00397  M01S00396.fsework +++|*
00398  M01S00397.fsework +++|*         ENTRY  PL - CURRENT TREE LEVEL.
00399  M01S00398.fsework +++|*                PADA[PL] - DISK ADDRESS ASSIGNED FOR REAL DATA.
00400  M01S00399.fsework +++|*
00401  M01S00400.fsework +++|*         EXIT   PACACHE[PL] - WHICH CACHE FRAME WAS SELECTED.
00402  M01S00401.fsework +++|*                BFDA[PL] - DISK ADDRESS IS STORED IN CACHE FRAME.
00403  M01S00402.fsework +++|*
00404  M01S00403.fsework +++|*         CALLS  SEARCHCACHE.
00405  M01S00404.fsework +++|#
00406  M01S00405.fsework +++|  ITEM TMP1;
00407  M01S00406.fsework +++|  SEARCHCACHE(TMP1);
00408  M01S00407.fsework +++|  PACACHE[PL]=TMP1;
00409  M01S00408.fsework +++|  CACHEOWNED[TMP1]=TRUE;
00410  M01S00409.fsework +++|  BFDA[TMP1]=PADA[PL];
00411  M01S00410.fsework +++|  END                         # OF ALLOCCACHE     #
00412  M01S00411.fsework +++|
00413  M01S00412.fsework +++|
00414  M01S00413.fsework +++|PROC RECLAIMCACHE;
00415  M01S00414.fsework +++|  BEGIN
00416  M01S00415.fsework +++|#
00417  M01S00416.fsework +++|**        RECLAIMCACHE - IDENTIFY CACHE FRAME WRONGLY RELEASED.
00418  M01S00417.fsework +++|*
00419  M01S00418.fsework +++|*         RECLAIMCACHE IS USED TO MATCH A TREE LEVEL TO A CACHE
00420  M01S00419.fsework +++|*         FRAME WHICH CONTAINS THE VIRTUAL DISK SECTOR FOR THE
00421  M01S00420.fsework +++|*         TREE LEVEL, AND REESTABLISH OWNERSHIP.  THIS IS DONE
00422  M01S00421.fsework +++|*         BECAUSE THERE ARE SITUATIONS WHERE A PAGE MUST BE
00423  M01S00422.fsework +++|*         TEMPORARILY RELEASED FROM OWNERSHIP SO IT CAN BE WRITTEN
00424  M01S00423.fsework +++|*         TO DISK, BUT FORFEITURE OF OWNERSHIP IS NOT INTENDED
00425  M01S00424.fsework +++|*         FOR ANY OTHER REASON.  RECLAIMCACHE CAN BE CALLED AFTER
00426  M01S00425.fsework +++|*         A SEQUENCE OF DISOWNCACHE AND FLUSHCACHE, AND THE TREE
00427  M01S00426.fsework +++|*         LEVELS ARE THEN AS THEY WERE BUT DATA ALTERATIONS ARE
00428  M01S00427.fsework +++|*         UP TO DATE ON DISK.  REMEMBER THAT THE ORDER IN WHICH PAGES
00429  M01S00428.fsework +++|*         CAN BE UPDATED TO DISK DEPENDS ON THE TREE HIERARCHY, SO
00430  M01S00429.fsework +++|*         IT IS SOMETIMES NECESSARY TO GO THRU THIS SEQUENCE WITH ONE
00431  M01S00430.fsework +++|*         TREE LEVEL IN ORDER TO ACHIEVE THE ACTUAL PURPOSE OF
00432  M01S00431.fsework +++|*         WRITING A DIFFERENCE TREE LEVEL TO DISK.
00433  M01S00432.fsework +++|*
00434  M01S00433.fsework +++|*         ENTRY  PL - CURRENT TREE LEVEL.
00435  M01S00434.fsework +++|*                PALVL - DEEPEST VALID TREE LEVEL.
00436  M01S00435.fsework +++|*                CACHEOWNED[ALL], PACACHE[ALL], BFDA[ALL] - SETUP.
00437  M01S00436.fsework +++|*
00438  M01S00437.fsework +++|*         EXIT   CACHEOWNED[PL THRU PALVL] - TRUE.
00439  M01S00438.fsework +++|*
00440  M01S00439.fsework +++|*         CALLS  TRAGIC.
00441  M01S00440.fsework +++|*
00442  M01S00441.fsework +++|*         USES   TPL.
00443  M01S00442.fsework +++|#
00444  M01S00443.fsework +++|  FOR TPL=PL STEP 1 UNTIL PALVL DO
00445  M01S00444.fsework +++|    BEGIN
00446  M01S00445.fsework +++|    IF CACHEOWNED[PACACHE[TPL]] THEN TEST TPL;
00447  M01S00446.fsework +++|    IF BFDA[PACACHE[TPL]] NQ PADA[TPL] THEN
00448  M01S00447.fsework +++|      BEGIN
00449  M01S00448.fsework +++|      TRAGIC(" WORKFILE BUFFER CONTAINS WRONG TEXT.$");
00450  M01S00449.fsework +++|      END
00451  M01S00450.fsework +++|    CACHEOWNED[PACACHE[TPL]]=TRUE;
00452  M01S00451.fsework +++|    END
00453  M01S00452.fsework +++|  END                         # OF RECLAIMCACHE   #
00454  M01S00453.fsework +++|PAGE
00455  M01S00454.fsework +++|PROC MOVEIO;
00456  M01S00455.fsework +++|  BEGIN
00457  M01S00456.fsework +++|#
00458  M01S00457.fsework +++|**        MOVEIO - INITIATE ANY CIO CALLS AS NEEDED.
00459  M01S00458.fsework +++|*
00460  M01S00459.fsework +++|*         MOVEIO IS CALLED ANY TIME CIO CALLS ARE KNOWN TO BE
00461  M01S00460.fsework +++|*         NECESSARY, AND CAN ALSO BE CALLED ANY TIME CIO CALLS MIGHT
00462  M01S00461.fsework +++|*         BE DESIRABLE.  MOVEIO BECOMES A NO-OP IF A CIO CALL IS
00463  M01S00462.fsework +++|*         ALREADY IN PROGRESS, OR IF NO CIO CALL IS NEEDED.  THE
00464  M01S00463.fsework +++|*         CALLER IS RESPONSIBLE TO PREPARE THE FET AND CIRCULAR
00465  M01S00464.fsework +++|*         BUFFER IN ALL WAYS EXCEPT THE CHOICE OF CIO FUNCTION CODE.
00466  M01S00465.fsework +++|*
00467  M01S00466.fsework +++|*         WRITES ARE INITIATED WHEN THE IOWRITE FLAG HAS BEEN
00468  M01S00467.fsework +++|*         PREPARED TO INDICATE THAT WRITES ARE NEEDED, THE FET IS NOT
00469  M01S00468.fsework +++|*         PREVIOUSLY INTERLOCKED, AND THE CIRCULAR BUFFER CONTAINS
00470  M01S00469.fsework +++|*         SOME DATA.  READS ARE INITIATED WHEN THE IOREAD FLAG HAS
00471  M01S00470.fsework +++|*         BEEN PREPARED TO INDICATE THAT READS ARE NEEDED, THE FET IS
00472  M01S00471.fsework +++|*         NOT PREVIOUSLY INTERLOCKED, AND THE RDIN/RDOUT POINTERS
00473  M01S00472.fsework +++|*         INDICATE THERE IS A NON-TRIVIAL LIST OF PRUS STILL AWAITING
00474  M01S00473.fsework +++|*         READS.
00475  M01S00474.fsework +++|*
00476  M01S00475.fsework +++|*         MOVEIO ALSO PERFORMS THE FUNCTION OF RECOGNIZING THAT ALL
00477  M01S00476.fsework +++|*         DESIRED I/O HAS BEEN COMPLETED, SUCH AS ALL WRITEABLE DATA
00478  M01S00477.fsework +++|*         REMOVED FROM CIRCULAR BUFFER OR ALL READABLE PRUS REMOVED
00479  M01S00478.fsework +++|*         FROM READ LIST.  UNDER THESE CONDITIONS, MOVEIO CLEARS THE
00480  M01S00479.fsework +++|*         IOXXXX FLAGS SO THAT NO FURTHER DESIRE FOR CIO CALLS WILL
00481  M01S00480.fsework +++|*         BE INDICATED, UNTIL AND UNLESS SOMEONE TURNS THE FLAGS ON
00482  M01S00481.fsework +++|*         AGAIN.
00483  M01S00482.fsework +++|*
00484  M01S00483.fsework +++|*         IN THE CASES WHERE THE CIRCULAR BUFFER CONTAINS DATA TO BE
00485  M01S00484.fsework +++|*         WRITTEN, THE ACTUAL CIO FUNCTION CODE IS CHOSEN FROM FOUR
00486  M01S00485.fsework +++|*         POSSIBILITIES BASED ON EXTENSION/ALTERATION OF THE FILE AND
00487  M01S00486.fsework +++|*         NEED OR NON-NEED FOR END-OF-RECORD TO BE WRITTEN.  WHEN THE
00488  M01S00487.fsework +++|*         DISK IS TO BE READ, THE FUNCTION CODE IS ALWAYS "RPHRLS",
00489  M01S00488.fsework +++|*         AKA "READ PRUS RANDOMLY BY LIST".
00490  M01S00489.fsework +++|*
00491  M01S00490.fsework +++|*         NOTE THAT MOVEIO NEVER WAITS FOR ANY CIO TO COMPLETE, THUS
00492  M01S00491.fsework +++|*         MOVEIO IS NOT A REENTRANT ROUTINE.
00493  M01S00492.fsework +++|*
00494  M01S00493.fsework +++|*         ENTRY  FETDUN - WHETHER ANY PREVIOUS I/O IS DONE.
00495  M01S00494.fsework +++|*                IOACT - WHETHER I/O SHOULD BE DONE SOMETIME SOON.
00496  M01S00495.fsework +++|*                IOWRITE - WHETHER I/O NEEDED IS A WRITE.
00497  M01S00496.fsework +++|*                IOREAD - WHETHER I/O NEEDED IS A READ.
00498  M01S00497.fsework +++|*                IOAPEND - WHETHER WRITE IS TO EXTEND FILE OR ALTER.
00499  M01S00498.fsework +++|*                IOWRTEOR - WHETHER WRITE IS TO PRODUCE EOR.
00500  M01S00499.fsework +++|*                FETIN, FETOUT - INDICATE WHETHER UNWRITTEN DATA IS
00501  M01S00500.fsework +++|*                    STILL IN THE BUFFER.
00502  M01S00501.fsework +++|*                RDIN, RDOUT - INDICATE WHETHER THERE ARE PRUS
00503  M01S00502.fsework +++|*                    IDENTIFIED IN READ LIST AS DESIRABLE TO READ,
00504  M01S00503.fsework +++|*                    BUT NOT YET READ IN.
00505  M01S00504.fsework +++|*                FETLA, FETLAW - CURRENT POSITION IN READ LIST.
00506  M01S00505.fsework +++|*                RDLIST[ALL] - SETUP.
00507  M01S00506.fsework +++|*                CIOCOUNT - ACCOUNTING ACCUMULATOR.
00508  M01S00507.fsework +++|*                MAXDA, LASTDA - USED TO DETERMINE VALIDITY OF
00509  M01S00508.fsework +++|*                    WRITE PARAMETERS, WHEN CONSISTENCY CHECKING
00510  M01S00509.fsework +++|*                    IS ENABLED IN THE SOURCE CODE.
00511  M01S00510.fsework +++|*                FETCRI - USED WITH MAXDA AND LASTDA FOR VALIDITY.
00512  M01S00511.fsework +++|*
00513  M01S00512.fsework +++|*         EXIT   FETDUN - FALSE IF A CIO CALL STARTED UP.
00514  M01S00513.fsework +++|*                CIOCOUNT - INCREMENTED IF CIO CALLED.
00515  M01S00514.fsework +++|*                IOACT, IOREAD, IOWRITE, IOAPEND - CLEARED IF AND
00516  M01S00515.fsework +++|*                    ONLY IF ALL MOVEIO DETERMINES THAT ALL
00517  M01S00516.fsework +++|*                    PREVIOUSLY REQUESTED I/O HAS COMPLETED.
00518  M01S00517.fsework +++|*
00519  M01S00518.fsework +++|*         CALLS  WRITE, REWRITE, WRITER, REWRITR, RPHRLS, TRAGIC.
00520  M01S00519.fsework +++|#
00521  M01S00520.fsework +++|  ITEM I;
00522  M01S00521.fsework +++|  SWITCH CALLWRITE WRTFUNC,RWRTFUNC,WRTRFUNC,RWRTRFUNC;
00523  M01S00522.fsework +++|
00524  M01S00523.fsework +++|  IF IOACT AND FETDUN THEN
00525  M01S00524.fsework +++|   BEGIN
00526  M01S00525.fsework +++|
00527  M01S00526.fsework +++|    IF IOWRITE AND FETIN NQ FETOUT THEN          # WRITE NOT DONE    #
00528  M01S00527.fsework +++|      BEGIN
00529  M01S00528.fsework +++|      CIOCOUNT = CIOCOUNT + 1;
00530  M01S00529.fsework +++|
00531  M01S00530.fsework +++|      I=1;
00532  M01S00531.fsework +++|      IF IOAPEND THEN I=0;
00533  M01S00532.fsework +++|      IF IOWRTEOR THEN I=I+2;
00534  M01S00533.fsework +++|      IOWRTEOR=FALSE;
00535  M01S00534.fsework +++|      GOTO CALLWRITE[I];
00536  M01S00535.fsework +++|
00537  M01S00536.fsework +++|WRTFUNC:
00538  M01S00537.fsework +++|      WRITE(FET,0);
00539  M01S00538.fsework +++|      RETURN;
00540  M01S00539.fsework +++|
00541  M01S00540.fsework +++|RWRTFUNC:
00542  M01S00001.ns2681  +++|      FETEP = TRUE;                  # SET ERROR PROCESSING BIT       #
00543  M01S00541.fsework +++|      REWRITE(FET,0);
00544  M01S00002.ns2681  +++|      FETEP = FALSE;                 # CLEAR ERROR PROCESSING BIT     #
00545  M01S00003.ns2681  +++|      IF FETAT EQ O"22" THEN
00546  M01S00004.ns2681  +++|        BEGIN                        # IF FATAL ERROR                 #
00547  M01S00005.ns2681  +++|        TRAGIC(" WORKFILE BUFFER EMPTY ON REWRITE.$");
00548  M01S00006.ns2681  +++|        END
00549  M01S00542.fsework +++|      RETURN;
00550  M01S00543.fsework +++|
00551  M01S00544.fsework +++|WRTRFUNC:
00552  M01S00545.fsework +++|      WRITER(FET,0);
00553  M01S00546.fsework +++|      RETURN;
00554  M01S00547.fsework +++|
00555  M01S00548.fsework +++|RWRTRFUNC:
00556  M01S00007.ns2681  +++|      FETEP = TRUE;                  # SET ERROR PROCESSING BIT       #
00557  M01S00549.fsework +++|      REWRITR(FET,0);
00558  M01S00008.ns2681  +++|      FETEP = FALSE;                 # CLEAR ERROR PROCESSING BIT     #
00559  M01S00009.ns2681  +++|      IF FETAT EQ O"22" THEN
00560  M01S00010.ns2681  +++|        BEGIN                        # IF FATAL ERROR                 #
00561  M01S00011.ns2681  +++|        TRAGIC(" WORKFILE BUFFER EMPTY ON REWRITER. $");
00562  M01S00012.ns2681  +++|        END
00563  M01S00550.fsework +++|      RETURN;
00564  M01S00551.fsework +++|
00565  M01S00552.fsework +++|      END
00566  M01S00553.fsework +++|
00567  M01S00554.fsework +++|    ELSE IF IOREAD AND RDIN NQ RDOUT THEN        # READ NOT DONE     #
00568  M01S00555.fsework +++|      BEGIN
00569  M01S00556.fsework +++|      IF FETLA EQ LOC(RDLIST[RDLIM])
00570  M01S00557.fsework +++|        THEN FETLAW = LOC(RDLIST[0]);
00571  M01S00558.fsework +++|
00572  M01S00559.fsework +++|      IF FETLA NQ LOC(RDLIST[RDIN]) THEN
00573  M01S00560.fsework +++|        BEGIN
00574  M01S00561.fsework +++|        CIOCOUNT = CIOCOUNT + 1;
00575  M01S00562.fsework +++|        RPHRLS(FET,0);
00576  M01S00563.fsework +++|        END
00577  M01S00564.fsework +++|      END
00578  M01S00565.fsework +++|
00579  M01S00566.fsework +++|    ELSE                               # READ AND WRITE DONE         #
00580  M01S00567.fsework +++|      BEGIN
00581  M01S00568.fsework +++|
00582  M01S00569.fsework +++|      CONTROL IFGQ PARANOIA,5;
00583  M01S00570.fsework +++|        IF IOWRITE THEN                # CHECK WRITE CRI   #
00584  M01S00571.fsework +++|          BEGIN
00585  M01S00572.fsework +++|          IF IOAPEND THEN
00586  M01S00573.fsework +++|            BEGIN
00587  M01S00574.fsework +++|            IF FETCRI NQ MAXDA+1 THEN
00588  M01S00575.fsework +++|              BEGIN
00589  M01S00576.fsework +++|              TRAGIC(" FILE SIZE INCORRECT.$");
00590  M01S00577.fsework +++|              END
00591  M01S00578.fsework +++|            END
00592  M01S00579.fsework +++|          ELSE
00593  M01S00580.fsework +++|            BEGIN
00594  M01S00581.fsework +++|            IF FETCRI NQ LASTDA+1 THEN
00595  M01S00582.fsework +++|              BEGIN
00596  M01S00583.fsework +++|              TRAGIC(" RANDOM ADDRESS INCORRECT.$");
00597  M01S00584.fsework +++|              END
00598  M01S00585.fsework +++|            END
00599  M01S00586.fsework +++|          END
00600  M01S00587.fsework +++|      CONTROL FI;
00601  M01S00588.fsework +++|
00602  M01S00589.fsework +++|      IOACT = FALSE;
00603  M01S00590.fsework +++|      IOWRITE = FALSE; IOAPEND = FALSE;
00604  M01S00591.fsework +++|      IOREAD = FALSE;
00605  M01S00592.fsework +++|      END
00606  M01S00593.fsework +++|
00607  M01S00594.fsework +++|    END
00608  M01S00595.fsework +++|  END
00609  M01S00596.fsework +++|PAGE
00610  M01S00597.fsework +++|PROC PAUSEIO;
00611  M01S00598.fsework +++|  IOBEGIN(PAUSEIO)
00612  M01S00599.fsework +++|#
00613  M01S00600.fsework +++|**        PAUSEIO - AWAIT AND/OR ENFORCE CIO COMPLETION.
00614  M01S00601.fsework +++|*
00615  M01S00602.fsework +++|*         PAUSEIO IS CALLED FOR ONE OF THREE REASONS:  (1) THE CALLER
00616  M01S00603.fsework +++|*         HAS STARTED SOME I/O VIA MOVEIO AND NEEDS TO WAIT FOR IT TO
00617  M01S00604.fsework +++|*         FINISH, OR (2) THE CALLER NEEDS SOME OLD I/O TO FINISH SO
00618  M01S00605.fsework +++|*         THAT THE FET CAN BE USED TO INITIATE NEW DESIRED I/O, OR
00619  M01S00606.fsework +++|*         (3) THE CALLER NEEDS SOME OLD I/O TO FINISH, TO FREE THE
00620  M01S00607.fsework +++|*         CIRCULAR BUFFER AND READ LIST SO THOSE MEMORY RESOURCES CAN
00621  M01S00608.fsework +++|*         BE MANAGED AND POSSIBLY RE-ASSIGNED.
00622  M01S00609.fsework +++|*
00623  M01S00610.fsework +++|*         PAUSEIO THEREFORE GUARANTEES THAT ANY WRITEABLE DATA IN THE
00624  M01S00611.fsework +++|*         CIRCULAR BUFFER REALLY GETS WRITTEN, AND THAT ANY INITIATED
00625  M01S00612.fsework +++|*         READS ARE FINISHED WITH THE DATA DISCARDED AND THE CIRCULAR
00626  M01S00613.fsework +++|*         BUFFER EMPTY.  PAUSEIO IS ALLOWED TO HANDLE READS WHICH
00627  M01S00614.fsework +++|*         HAVE BEEN REQUESTED BUT NOT YET INITIATED BY SIMPLE
00628  M01S00615.fsework +++|*         CANCELLATION.  THUS, PAUSEIO IS MEANINGFUL TO THE TYPE 1
00629  M01S00616.fsework +++|*         CALLER ONLY FOR THE WRITE DIRECTION - THE READ DIRECTION IS
00630  M01S00617.fsework +++|*         A THROWAWAY WHILE THE WRITE DIRECTION HAS ASSURANCE OF
00631  M01S00618.fsework +++|*         COMPLETION.
00632  M01S00619.fsework +++|*
00633  M01S00620.fsework +++|*         SINCE THE TYPE 3 CALLER OFTEN DOES NOT KNOW HOW (OR IS NOT
00634  M01S00621.fsework +++|*         ALLOWED) TO DETERMINE IF THE MEMORY RESOURCES ARE ALREADY
00635  M01S00622.fsework +++|*         AVAILABLE FOR REASSIGNMENT, PAUSEIO CAN BE CALLED CASUALLY,
00636  M01S00623.fsework +++|*         AND WILL NO-OP ITSELF IF THE DESIRED CONDITIONS ARE ALREADY
00637  M01S00624.fsework +++|*         TRUE.
00638  M01S00625.fsework +++|*
00639  M01S00626.fsework +++|*         PAUSEIO ALSO ZEROES OUT FETCHGUIDE.  THIS IS USED TO CONTROL
00640  M01S00627.fsework +++|*         THE QUANTITY OF DATA PREFETCHED AS A FUNCTION OF HOW MUCH
00641  M01S00628.fsework +++|*         SUCCESS WE HAVE HAD IN UTILIZING PREFETCHED DATA IN RECENT
00642  M01S00629.fsework +++|*         HISTORY.  A PAUSEIO CALL IS REGARDED AS AN ADMISSION THAT
00643  M01S00630.fsework +++|*         ANY CURRENT PREFETCHING HAS LOST ALL RELEVANCE.
00644  M01S00631.fsework +++|*
00645  M01S00632.fsework +++|*         ENTRY  IOREAD - WHETHER WE WERE PREVIOUSLY TRYING TO READ
00646  M01S00633.fsework +++|*                    SOMETHING WHICH MUST NOW BE THROWN AWAY.
00647  M01S00634.fsework +++|*                IOWRITE - WHETHER WE HAD PREVIOUSLY REQUESTED THAT
00648  M01S00635.fsework +++|*                    SOMETHING BE WRITTEN, WHICH MUST NOW BE BROUGHT
00649  M01S00636.fsework +++|*                    TO FASTEST POSSIBLE COMPLETION.
00650  M01S00637.fsework +++|*                RDIN, RDOUT - BRACKET ACTIVE SEGMENT OF READ LIST.
00651  M01S00638.fsework +++|*                FETIN, FETOUT - BRACKET CIRCULAR BUFFER DATA.
00652  M01S00639.fsework +++|*
00653  M01S00640.fsework +++|*         EXIT   IOREAD, IOWRITE, IOACT - GUARANTEED FALSE.
00654  M01S00641.fsework +++|*                FET - CIRCULAR BUFFER GUARANTEED EMPTY.
00655  M01S00642.fsework +++|*                RDLIST[ALL], RDIN, RDOUT - GUARANTEED EMPTY.
00656  M01S00643.fsework +++|*                FETCHGUIDE - ZEROED.
00657  M01S00644.fsework +++|*
00658  M01S00645.fsework +++|*         CALLS  WAIT, MOVEIO.
00659  M01S00646.fsework +++|#
00660  M01S00647.fsework +++|  ITEM I, J, K;
00661  M01S00648.fsework +++|
00662  M01S00649.fsework +++|  FETCHGUIDE=0;
00663  M01S00650.fsework +++|
00664  M01S00651.fsework +++|  IF IOREAD THEN
00665  M01S00652.fsework +++|    BEGIN
00666  M01S00653.fsework +++|    WAIT;                    # FOR ACTIVE TRANSFER TO FINISH         #
00667  M01S00654.fsework +++|    FOR I = RDIN WHILE I NQ RDOUT DO   # CLEAN OUT READLIST          #
00668  M01S00655.fsework +++|      BEGIN
00669  M01S00656.fsework +++|      I = I - 1;
00670  M01S00657.fsework +++|      IF I LS 0 THEN I = RDLIM - 1;
00671  M01S00658.fsework +++|      RDLIST[I] = 0;
00672  M01S00659.fsework +++|      END
00673  M01S00660.fsework +++|    FETOUT = FETIN;          # ABANDON CIRCULAR BUFFER CONTENT       #
00674  M01S00661.fsework +++|    IOACT = FALSE;
00675  M01S00662.fsework +++|    IOREAD = FALSE;
00676  M01S00663.fsework +++|    END
00677  M01S00664.fsework +++|
00678  M01S00665.fsework +++|  ELSE IF IOWRITE THEN
00679  M01S00666.fsework +++|    BEGIN
00680  M01S00667.fsework +++|    WHYLE IOWRITE DO
00681  M01S00668.fsework +++|      BEGIN
00682  M01S00669.fsework +++|      MOVEIO;
00683  M01S00670.fsework +++|      WAIT;
00684  M01S00671.fsework +++|      END
00685  M01S00672.fsework +++|    END
00686  M01S00673.fsework +++|
00687  M01S00674.fsework +++|  IOEND
00688  M01S00675.fsework +++|PAGE
00689  M01S00676.fsework +++|PROC SETREAD((DA));
00690  M01S00677.fsework +++|  BEGIN
00691  M01S00678.fsework +++|#
00692  M01S00679.fsework +++|**        SETREAD - ADD DISK ADDRESS TO READ LIST.
00693  M01S00680.fsework +++|*
00694  M01S00681.fsework +++|*         SETREAD PERFORMS FET INITIALIZATION AS NEEDED, TO ASSURE
00695  M01S00682.fsework +++|*         THAT THE BUFFER AND FET ARE TURNED AROUND TO THE INPUT
00696  M01S00683.fsework +++|*         DIRECTION, AND APPENDS THE SPECIFIED DISK ADDRESS ONTO THE
00697  M01S00684.fsework +++|*         READ LIST.  THE CALLER IS RESPONSIBLE TO ASSURE THAT
00698  M01S00685.fsework +++|*         SETREAD WILL NOT ENCOUNTER A FULL READ LIST.  THE CALLER IS
00699  M01S00686.fsework +++|*         ALLOWED TO CALL SETREAD FOR AN ADDRESS ALREADY LISTED, IN
00700  M01S00687.fsework +++|*         WHICH CASE SETREAD NO-OPS ITSELF.  THE USER IS REQUIRED TO
00701  M01S00688.fsework +++|*         PROVIDE AN IN-BOUNDS DISK ADDRESS, AND TO HAVE USED PAUSEIO
00702  M01S00689.fsework +++|*         TO COMPLETE ANY PREVIOUS OUTPUT ACTIVITIES.
00703  M01S00690.fsework +++|*
00704  M01S00691.fsework +++|*         ENTRY  DA - SECTOR NUMBER FOR DESIRED PRU.
00705  M01S00692.fsework +++|*                IOREAD - WHETHER FET ALREADY INITIALIZED FOR INPUT.
00706  M01S00693.fsework +++|*                IOWRITE, MAXDA - WHEN CONSISTENCY CHECKING IS ENABLED,
00707  M01S00694.fsework +++|*                    THESE ARE USED TO VERIFY VALIDITY.
00708  M01S00695.fsework +++|*                RDIN, RDOUT - BRACKET ACTIVE SEGMENT OF READ LIST.
00709  M01S00696.fsework +++|*                RDLIST[ALL] - SETUP FOR EXISTING DISK ADDRESSES
00710  M01S00697.fsework +++|*                    AND WITH ZEROES IN EXCESS LIST AREAS.
00711  M01S00698.fsework +++|*
00712  M01S00699.fsework +++|*         EXIT   IOREAD, IOACT - TRUE.
00713  M01S00700.fsework +++|*                FET AND CIRCULAR BUFFER - VALID FOR MOVEIO CALL.
00714  M01S00701.fsework +++|*                RDIN, RDOUT - UPDATED FOR ENLARGED READ LIST.
00715  M01S00702.fsework +++|*                RDLIST[NEW RDIN-1] - DISK ADDRESS STORED HERE.
00716  M01S00703.fsework +++|*
00717  M01S00704.fsework +++|*         CALLS  TRAGIC, INITFET.
00718  M01S00705.fsework +++|#
00719  M01S00706.fsework +++|  ITEM DA;
00720  M01S00707.fsework +++|  ITEM P;
00721  M01S00708.fsework +++|
00722  M01S00709.fsework +++|  CONTROL IFGQ PARANOIA,5;
00723  M01S00710.fsework +++|    IF DA LQ 0 OR DA GR MAXDA THEN
00724  M01S00711.fsework +++|      BEGIN
00725  M01S00712.fsework +++|      TRAGIC(" OUT OF BOUNDS PRU ADDRESS ON READ (1).$");
00726  M01S00713.fsework +++|      END
00727  M01S00714.fsework +++|    IF IOWRITE THEN TRAGIC(" WORKFILE BUFFER FULL ON READ.$");
00728  M01S00715.fsework +++|  CONTROL FI;
00729  M01S00716.fsework +++|
00730  M01S00717.fsework +++|  IF NOT IOREAD THEN
00731  M01S00718.fsework +++|    BEGIN
00732  M01S00719.fsework +++|    INITFET(DISK,DSKSIZ);
00733  M01S00720.fsework +++|
00734  M01S00721.fsework +++|    RDIN = 0;
00735  M01S00722.fsework +++|    RDOUT = 0;
00736  M01S00723.fsework +++|    FETLAW = LOC(RDLIST[0]);
00737  M01S00724.fsework +++|
00738  M01S00725.fsework +++|    IOACT = TRUE;
00739  M01S00726.fsework +++|    IOREAD = TRUE;
00740  M01S00727.fsework +++|    END
00741  M01S00728.fsework +++|
00742  M01S00729.fsework +++|  FOR P = RDOUT WHILE RDLIST[P] NQ DA DO
00743  M01S00730.fsework +++|    BEGIN
00744  M01S00731.fsework +++|    IF P EQ RDIN THEN
00745  M01S00732.fsework +++|      BEGIN
00746  M01S00733.fsework +++|      RDLIST[RDIN] = DA;
00747  M01S00734.fsework +++|      RDIN = RDIN + 1;
00748  M01S00735.fsework +++|      IF RDIN EQ RDLIM THEN RDIN = 0;
00749  M01S00736.fsework +++|      CONTROL IFGQ PARANOIA,5;
00750  M01S00737.fsework +++|        IF RDIN EQ RDOUT THEN TRAGIC(" RPHRLS LIST BUFFER IS FULL.$");
00751  M01S00738.fsework +++|      CONTROL FI;
00752  M01S00739.fsework +++|      END
00753  M01S00740.fsework +++|
00754  M01S00741.fsework +++|    ELSE
00755  M01S00742.fsework +++|      BEGIN
00756  M01S00743.fsework +++|      P = P + 1;
00757  M01S00744.fsework +++|      IF P EQ RDLIM THEN P = 0;
00758  M01S00745.fsework +++|      END
00759  M01S00746.fsework +++|
00760  M01S00747.fsework +++|    END
00761  M01S00748.fsework +++|
00762  M01S00749.fsework +++|  END
00763  M01S00750.fsework +++|PAGE
00764  M01S00751.fsework +++|PROC PREFETCH((DD));
00765  M01S00752.fsework +++|  BEGIN
00766  M01S00753.fsework +++|#
00767  M01S00754.fsework +++|**        ARRANGE READ LIST FOR SEVERAL PREFETCHES.
00768  M01S00755.fsework +++|*
00769  M01S00756.fsework +++|*         PREFETCH SHOULD BE CALLED ONCE PER SECTOR PROCESSED, BY
00770  M01S00757.fsework +++|*         THOSE PROCESSES WHICH ACT UPON POTENTIALLY LARGE SERIES OF
00771  M01S00758.fsework +++|*         DISK SECTORS IN EITHER THE FORWARD OR BACKWARD LOGICAL
00772  M01S00759.fsework +++|*         ORDER OF TEXT IN THE FILE.  THE LOGICAL ORDER CAN BE QUITE
00773  M01S00760.fsework +++|*         DIFFERENT FROM THE PHYSICAL ORDER DUE TO THE TREE LINKAGES.
00774  M01S00761.fsework +++|*
00775  M01S00762.fsework +++|*         PREFETCH DETERMINES SEVERAL DISK ADDRESSES WHOSE NEED IS
00776  M01S00763.fsework +++|*         ANTICIPATED ON BEHALF OF THE CALLER, AND USES SETREAD TO
00777  M01S00764.fsework +++|*         ARRANGE THAT SUCH SECTORS CAN BE READ IN THE LOGICAL ORDER.
00778  M01S00765.fsework +++|*         IT IS THE CALLING PROCESSES RESPONSIBILITY TO OCCASIONALLY
00779  M01S00766.fsework +++|*         CALL MOVEIO FOR ACTUAL INITIATION OF CIO.
00780  M01S00767.fsework +++|*
00781  M01S00768.fsework +++|*         TO MINIMIZE OVERHEAD, PREFETCH CHOOSES A DEPTH OF
00782  M01S00769.fsework +++|*         PREFETCHING BASED ON APPARENT RECENT SUCCESS IN UTILIZING
00783  M01S00770.fsework +++|*         PREFETCHED DATA, AND SUCCESSIVELY UPDATES THE DEPTH OF
00784  M01S00771.fsework +++|*         PREFETCH.  THIS DEPTH INDICATOR MAY BE CLEARED BY PAUSEIO
00785  M01S00772.fsework +++|*         IN RECOGNITION OF THE ABANDONMENT OF A READ, OR BY THE
00786  M01S00773.fsework +++|*         CALLER WHEN A LOGICAL BREAK IN SEQUENTIAL PROCESSING IS
00787  M01S00774.fsework +++|*         KNOWN TO OCCUR.
00788  M01S00775.fsework +++|*
00789  M01S00776.fsework +++|*         TO MINIMIZE OVERHEAD, PREFETCH ATTEMPTS TO PRODUCE EITHER
00790  M01S00777.fsework +++|*         ZERO OR SEVERAL NEW ENTRIES IN THE READ LIST, AND ATTEMPTS
00791  M01S00778.fsework +++|*         TO NO-OP ITSELF WHEN IT IS RECOGNIZED THAT ONLY ONE OR A
00792  M01S00779.fsework +++|*         FEW ENTRIES COULD BE PRODUCED.  PREFETCH MUST KEEP THE
00793  M01S00780.fsework +++|*         DEPTH OF PREFETCHING WITHIN THE LEGAL BOUNDS OF THE SETREAD
00794  M01S00781.fsework +++|*         ROUTINE.
00795  M01S00782.fsework +++|*
00796  M01S00783.fsework +++|*         THE DEPTH OF PREFETCHING IS LIMITED TO THE SMALLEST OF THE
00797  M01S00784.fsework +++|*         FOLLOWING FACTORS - (1) THE FETCHGUIDE QUANTITY, WHICH
00798  M01S00785.fsework +++|*         REPRESENTS RECENT SUCCESS, (2) THE LEGAL LIMITS IMPOSED BY
00799  M01S00786.fsework +++|*         SETREAD, AND (3) ONE AND A HALF TIMES THE SIZE OF THE
00800  M01S00787.fsework +++|*         CIRCULAR BUFFER.  PREFETCHING IS SET UP ONLY WHEN THE
00801  M01S00788.fsework +++|*         EXISTING QUEUE IS LESS THAN HALF THE DESIRED DEPTH.  FOR
00802  M01S00789.fsework +++|*         LARGER QUEUES, IT IS ANTICIPATED THE QUEUE WILL BE SHRUNK
00803  M01S00790.fsework +++|*         BACK DOWN AT SOME FUTURE CALL TO PREFETCH, AT WHICH TIME
00804  M01S00791.fsework +++|*         A LARGE BATCH OF QUEUE ENTIRES CAN BE PRODUCED.
00805  M01S00792.fsework +++|*
00806  M01S00793.fsework +++|*         ONCE PREFETCH DECIDES TO SET UP A BATCH OF READ LIST QUEUE
00807  M01S00794.fsework +++|*         ENTRIES, IT IDENTIFIES THE SECTORS TO BE READ AS ALL DATA
00808  M01S00795.fsework +++|*         (BOTTOM) LEVEL PRUS, POINTED TO BY THE NEXT-TO-BOTTOM
00809  M01S00796.fsework +++|*         DIRECTORY, LOGICALLY ADJACENT TO THE CURRENT DATA SECTOR IN
00810  M01S00797.fsework +++|*         THE SPECIFIED DIRECTION.  PREFETCH ALSO CAN QUEUE THE NEXT
00811  M01S00798.fsework +++|*         LOGICALLY ADJACENT NEXT-TO-BOTTOM DIRECTORY, BY LOOKING
00812  M01S00799.fsework +++|*         ANOTHER LEVEL TOWARDS THE ROOT OF THE TREE.
00813  M01S00800.fsework +++|*
00814  M01S00801.fsework +++|*         ENTRY  FETCHGUIDE - CURRENT GUIDELINE FOR DEPTH.
00815  M01S00802.fsework +++|*                RDIN, RDOUT - DESCRIBE CURRENT READ LIST.
00816  M01S00803.fsework +++|*                DSKSIZ - CIRCULAR BUFFER SIZE.
00817  M01S00804.fsework +++|*                PALVL - DEEPEST TREE LEVEL CURRENTLY VALID.
00818  M01S00805.fsework +++|*                PACACHE[ALL] - CACHE FRAMES AT EACH TREE LEVEL.
00819  M01S00806.fsework +++|*                BFPRU[ALL] - DISK ADDRESSES FOR EACH FRAME.
00820  M01S00807.fsework +++|*                PAFINAL[ALL] - LAST WORDS IN EACH SECTOR OF TREE.
00821  M01S00808.fsework +++|*                IOWRITE - WHETHER FET INTERLOCKED FOR OUTPUT.
00822  M01S00809.fsework +++|*
00823  M01S00810.fsework +++|*         EXIT   RDLIST[ALL], RDIN, RDOUT - UPDATED.
00824  M01S00811.fsework +++|*                FETCHGUIDE - INCREMENTED UNLESS DIRECTORY INCLUDED.
00825  M01S00812.fsework +++|*
00826  M01S00813.fsework +++|*         CALLS  LSTAVAIL, LSTUSAGE, MIN, MAX, SETREAD.
00827  M01S00814.fsework +++|*
00828  M01S00815.fsework +++|*         USES   P<PRU> WITH RESTORATION.
00829  M01S00816.fsework +++|#
00830  M01S00817.fsework +++|  ITEM DD,N;
00831  M01S00818.fsework +++|  ITEM DSTOP;
00832  M01S00819.fsework +++|  ITEM DONE B;
00833  M01S00820.fsework +++|  ITEM TMPPRU;
00834  M01S00821.fsework +++|  ITEM TMPPL,TMPD;
00835  M01S00822.fsework +++|  ITEM I;
00836  M01S00823.fsework +++|
00837  M01S00824.fsework +++|  IF FETCHGUIDE LS 0 OR IOWRITE THEN RETURN;
00838  M01S00825.fsework +++|
00839  M01S00826.fsework +++|  FETCHGUIDE=FETCHGUIDE+2;
00840  M01S00827.fsework +++|  N=LSTAVAIL;
00841  M01S00828.fsework +++|  N=MIN(N-3,3*DSKSIZ/O"200");
00842  M01S00829.fsework +++|  N=MIN(N,FETCHGUIDE);
00843  M01S00830.fsework +++|
00844  M01S00831.fsework +++|  IF LSTUSAGE LQ N/2 THEN
00845  M01S00832.fsework +++|    BEGIN
00846  M01S00833.fsework +++|    TMPPRU = P<PRU>;
00847  M01S00834.fsework +++|
00848  M01S00835.fsework +++|    DONE = FALSE;
00849  M01S00836.fsework +++|    FOR TMPPL = PALVL-1 STEP -1 WHILE TMPPL GQ 0 AND NOT DONE DO
00850  M01S00837.fsework +++|      BEGIN
00851  M01S00838.fsework +++|      TMPD = PADISP[TMPPL] + DD;
00852  M01S00839.fsework +++|      P<PRU> = LOC(BFPRU[PACACHE[TMPPL]]);
00853  M01S00840.fsework +++|
00854  M01S00841.fsework +++|      IF DD GR 0 THEN DSTOP = MIN(PAFINAL[TMPPL]+1,TMPD+N);
00855  M01S00842.fsework +++|      ELSE DSTOP = MAX(0,TMPD-N);
00856  M01S00843.fsework +++|
00857  M01S00844.fsework +++|      IF DSTOP EQ TMPD+N*DD THEN DONE = TRUE;
00858  M01S00845.fsework +++|      ELSE FETCHGUIDE=-1;
00859  M01S00846.fsework +++|      N=1;
00860  M01S00847.fsework +++|
00861  M01S00848.fsework +++|      FOR TMPD = TMPD STEP DD WHILE TMPD NQ DSTOP DO
00862  M01S00849.fsework +++|        BEGIN
00863  M01S00850.fsework +++|        FOR I=0 STEP 1 UNTIL MAXCACHE DO
00864  M01S00851.fsework +++|          BEGIN
00865  M01S00852.fsework +++|          IF BFDA[I] EQ DIRDA[TMPD] THEN TEST TMPD;
00866  M01S00853.fsework +++|          END
00867  M01S00854.fsework +++|        SETREAD(DIRDA[TMPD]);
00868  M01S00855.fsework +++|        END
00869  M01S00856.fsework +++|
00870  M01S00857.fsework +++|      END
00871  M01S00858.fsework +++|
00872  M01S00859.fsework +++|    P<PRU> = TMPPRU;
00873  M01S00860.fsework +++|    END
00874  M01S00861.fsework +++|  END
00875  M01S00862.fsework +++|PAGE
00876  M01S00863.fsework +++|PROC READPA;
00877  M01S00864.fsework +++|  IOBEGIN(READPA)
00878  M01S00865.fsework +++|#
00879  M01S00866.fsework +++|**        READPA - READ NEXT DEEPER TREE PATH SECTOR.
00880  M01S00867.fsework +++|*
00881  M01S00868.fsework +++|*         READPA IS USED TO ACCESS THE SECTOR OF DIRECTORY OR DATA
00882  M01S00869.fsework +++|*         FOR A SPECIFIED LEVEL OF THE TREE.  THE HIGHER LEVELS OF
00883  M01S00870.fsework +++|*         THE TREE MUST ALREADY BE PROPERLY FILLED IN.  ANY RESIDUAL
00884  M01S00871.fsework +++|*         SECTOR IN THE CURRENT TREE LEVEL MUST BE PROPERLY RELEASED
00885  M01S00872.fsework +++|*         FROM OWNERSHIP, SO THAT READPA WILL NOT NEED TO CONCERN
00886  M01S00873.fsework +++|*         ITSELF WITH THE UPDATING OF ALTERED DATA TO DISK.  THE
00887  M01S00874.fsework +++|*         CALLER DOES NOT NEED TO SETUP THE FET AND CIRCULAR BUFFER
00888  M01S00875.fsework +++|*         FOR INPUT, AND READPA WILL TAKE CARE OF THAT IF NEEDED.
00889  M01S00876.fsework +++|*
00890  M01S00877.fsework +++|*         WHEN POSSIBLE, READPA WILL ACCESS THE DESIRED DISK SECTOR
00891  M01S00878.fsework +++|*         BY SIMPLY IDENTIFYING IT IN CACHE AND CLAIMING OWNERSHIP OF
00892  M01S00879.fsework +++|*         THE RIGHT CACHE FRAME.  WHEN THE CACHE DOES NOT PROVIDE THE
00893  M01S00880.fsework +++|*         NECESSARY DATA, READPA WILL READ IT FROM DISK.  IF THE FET
00894  M01S00881.fsework +++|*         AND CIRCULAR BUFFER ARE PREVIOUSLY INTERLOCKED FOR PENDING
00895  M01S00882.fsework +++|*         OUTPUT, READPA WILL ASSURE THAT THE UNFINISHED WRITES GET
00896  M01S00883.fsework +++|*         DONE.  IF THE FET IS ALREADY SETUP FOR INPUT BUT HAS THE
00897  M01S00884.fsework +++|*         WRONG DISK ADDRESS COMING IN AT THE FRONT OF THE CIRCULAR
00898  M01S00885.fsework +++|*         BUFFER, READPA WILL DISCARD SUCH INCORRECT INPUT AND
00899  M01S00886.fsework +++|*         REINITIALIZE TO INPUT THE RIGHT DISK ADDRESS.  IF THE FET
00900  M01S00887.fsework +++|*         IS ALREADY SET UP FOR INPUT WITH THE RIGHT SECTOR IN OR
00901  M01S00888.fsework +++|*         COMING INTO THE CIRCULAR BUFFER, READPA WILL MAKE USE OF
00902  M01S00889.fsework +++|*         THAT CIO ACTIVITY.
00903  M01S00890.fsework +++|*
00904  M01S00891.fsework +++|*         IF READPA READS THE SECTOR FROM DISK, IT CLEANS UP THE
00905  M01S00892.fsework +++|*         RANDOM READ LIST AFTERWARDS, ATTEMPTING TO SHUFFLE THE
00906  M01S00893.fsework +++|*         ACTIVE SEGMENT OF THE READ LIST TO MAXIMIZE THE REMAINING
00907  M01S00894.fsework +++|*         LIST CAPACITY BEFORE WRAPAROUND.  READPA ALSO CHECKS TO SEE
00908  M01S00895.fsework +++|*         IF THE BUFFER IS SUFFICIENTLY EMPTY WITH A SUFFICIENTLY
00909  M01S00896.fsework +++|*         FULL PREFETCH LIST SO THAT ANTICIPATORY READS SHOULD BE
00910  M01S00897.fsework +++|*         STARTED.
00911  M01S00898.fsework +++|*
00912  M01S00899.fsework +++|*         ENTRY  TEMP - SECTOR NUMBER.
00913  M01S00900.fsework +++|*                PL - CURRENT PATH LEVEL.
00914  M01S00901.fsework +++|*                PACACHE[ALL] - CACHE FRAMES CURRENTLY OWNED.
00915  M01S00902.fsework +++|*                CACHEOWNED[ALL] - SETUP.
00916  M01S00903.fsework +++|*                BFDA[ALL] - IDENTIFY SECTOR ADDRESSES EACH FRAME.
00917  M01S00904.fsework +++|*                BFHEAD[ALL] - HEADER WORDS FOR EACH CACHED SECTOR.
00918  M01S00905.fsework +++|*                ACCTPRU - PRU TRANSFER COUNT.
00919  M01S00906.fsework +++|*                IOWRITE - WHETHER FET ALREADY SET FOR WRITES.
00920  M01S00907.fsework +++|*                RDIN, RDOUT - READ LIST BRACKETING.
00921  M01S00908.fsework +++|*                RDLIST[ALL] - SETUP.
00922  M01S00909.fsework +++|*                IOREAD - WHETHER SOME READ ALREADY SCHEDULED.
00923  M01S00910.fsework +++|*                FETCHGUIDE - PREFETCH QUANTITY GUIDELINE.
00924  M01S00911.fsework +++|*                QUARTER - APPROX ONE FOURTH BUFFER SIZE.
00925  M01S00912.fsework +++|*
00926  M01S00913.fsework +++|*         EXIT   PACACHE[PL] - INDICATES CACHE FRAME WITH SECTOR.
00927  M01S00914.fsework +++|*                CACHEOWNED[PACACHE[PL]] - TRUE.
00928  M01S00915.fsework +++|*                ANY OLD CACHE FRAMES MAY HAVE BEEN FLUSHED TO
00929  M01S00916.fsework +++|*                    DISK AND/OR REASSIGNED IN MEMORY.
00930  M01S00917.fsework +++|*                PAHEAD[PL] - HEADER WORD.
00931  M01S00918.fsework +++|*                IOWRITE - FALSE IF NOT CACHE HIT.
00932  M01S00919.fsework +++|*                IOREAD - POSSIBLY CHANGED.
00933  M01S00920.fsework +++|*                RDOUT - ADVANCED IF DISK READ DONE.
00934  M01S00921.fsework +++|*                RDIN - RDIN AND RDOUT POSSIBLY RELOCATED IF READ
00935  M01S00922.fsework +++|*                    DONE AND CIO TERMINATED.
00936  M01S00923.fsework +++|*                ACCTPRU - INCREMENTED IF NO CACHE HIT.
00937  M01S00924.fsework +++|*                FETCHGUIDE - POSSIBLY NEW VALUE.
00938  M01S00925.fsework +++|*                ANTICIPATORY CIO POSSIBLY CALLED.
00939  M01S00926.fsework +++|*
00940  M01S00927.fsework +++|*         CALLS  TRAGIC, COUNTCACHE, FLUSHCACHE, DISOWNCACHE,
00941  M01S00928.fsework +++|*                WIOSTAT, PAUSEIO, ALLOCCACHE, SETREAD, MOVEIO,
00942  M01S00929.fsework +++|*                DELAY, RECALL, RDWBUF, BUFUSAGE.
00943  M01S00930.fsework +++|*
00944  M01S00931.fsework +++|*         USES   P<TOO>.
00945  M01S00932.fsework +++|#
00946  M01S00933.fsework +++|  ITEM X1;
00947  M01S00934.fsework +++|
00948  M01S00935.fsework +++|  CONTROL IFGQ PARANOIA,5;
00949  M01S00936.fsework +++|    IF PADIRTY[PL] THEN TRAGIC(" ALTERED PRU WAS NOT REWRITTEN.$");
00950  M01S00937.fsework +++|  CONTROL FI;
00951  M01S00938.fsework +++|
00952  M01S00939.fsework +++|  IF COUNTCACHE LQ 2 THEN FLUSHCACHE;
00953  M01S00940.fsework +++|
00954  M01S00941.fsework +++|  # FIRST RELEASE CURRENTLY OWNED SECTOR IF ANY #
00955  M01S00942.fsework +++|  DISOWNCACHE(PACACHE[PL]);
00956  M01S00943.fsework +++|
00957  M01S00944.fsework +++|  FOR X1=0 STEP 1 UNTIL MAXCACHE DO
00958  M01S00945.fsework +++|    BEGIN                     # TRY TO FIND IN CACHE        #
00959  M01S00946.fsework +++|    IF BFDA[X1] EQ TEMP THEN        # GOT IT  #
00960  M01S00947.fsework +++|      BEGIN
00961  M01S00948.fsework +++|      CONTROL IFGQ PARANOIA,5;
00962  M01S00949.fsework +++|        IF CACHEOWNED[X1] THEN
00963  M01S00950.fsework +++|          BEGIN
00964  M01S00951.fsework +++|          TRAGIC(" WORKFILE BUFFER ALLOCATED TWICE.$");
00965  M01S00952.fsework +++|          END
00966  M01S00953.fsework +++|      CONTROL FI;
00967  M01S00954.fsework +++|      PACACHE[PL]=X1;
00968  M01S00955.fsework +++|      CACHEOWNED[X1]=TRUE;
00969  M01S00956.fsework +++|      PAHEAD[PL] = BFHEAD[X1];
00970  M01S00957.fsework +++|      CONTROL IFEQ MULTI,1;
00971  M01S00958.fsework +++|        WIOSTAT(1);          # ACCUMULATE CACHE HITS #
00972  M01S00959.fsework +++|      CONTROL FI;
00973  M01S00960.fsework +++|      IORET
00974  M01S00961.fsework +++|     END
00975  M01S00962.fsework +++|   END
00976  M01S00963.fsework +++|
00977  M01S00964.fsework +++|  CONTROL IFEQ MULTI,1;
00978  M01S00965.fsework +++|    WIOSTAT(2);              # ACCUMULATE SECTORS READ #
00979  M01S00966.fsework +++|    ACCTPRU=ACCTPRU+1;
00980  M01S00967.fsework +++|  CONTROL FI;
00981  M01S00968.fsework +++|
00982  M01S00969.fsework +++|  IF IOWRITE THEN            # DO ANY PENDING WRITES       #
00983  M01S00970.fsework +++|    BEGIN
00984  M01S00971.fsework +++|    PAUSEIO;
00985  M01S00972.fsework +++|    CONTROL IFEQ MULTI,1;
00986  M01S00973.fsework +++|      WIOSTAT(3);            # ACCUMULATE FLUSHED WRITES #
00987  M01S00974.fsework +++|    CONTROL FI;
00988  M01S00975.fsework +++|    END
00989  M01S00976.fsework +++|
00990  M01S00977.fsework +++|  CONTROL IFGQ PARANOIA,5;
00991  M01S00978.fsework +++|    IF TEMP LQ 0 OR TEMP GR MAXDA THEN
00992  M01S00979.fsework +++|      BEGIN
00993  M01S00980.fsework +++|      TRAGIC(" OUT OF BOUNDS PRU ADDRESS ON READ (2).$");
00994  M01S00981.fsework +++|      END
00995  M01S00982.fsework +++|  CONTROL FI;
00996  M01S00983.fsework +++|
00997  M01S00984.fsework +++|  PADA[PL] = TEMP;
00998  M01S00985.fsework +++|  ALLOCCACHE;
00999  M01S00986.fsework +++|
01000  M01S00987.fsework +++|  IF IOREAD AND RDLIST[RDOUT] NQ TEMP THEN
01001  M01S00988.fsework +++|    BEGIN
01002  M01S00989.fsework +++|    PAUSEIO;
01003  M01S00990.fsework +++|    CONTROL IFEQ MULTI,1;
01004  M01S00991.fsework +++|      WIOSTAT(4);            # ACCUMULATE READ REJECTS #
01005  M01S00992.fsework +++|    CONTROL FI;
01006  M01S00993.fsework +++|    END
01007  M01S00994.fsework +++|
01008  M01S00995.fsework +++|  IF NOT IOREAD THEN
01009  M01S00996.fsework +++|    BEGIN
01010  M01S00997.fsework +++|    SETREAD(TEMP);
01011  M01S00998.fsework +++|    FETCHGUIDE=2;
01012  M01S00999.fsework +++|    END
01013  M01S01000.fsework +++|
01014  M01S01001.fsework +++|  WHYLE FETIN EQ FETOUT DO
01015  M01S01002.fsework +++|    BEGIN
01016  M01S01003.fsework +++|    CONTROL IFEQ MULTI,1;
01017  M01S01004.fsework +++|      WIOSTAT(10);           # ACCUMULATE NOT ALREADY IN BUFFER #
01018  M01S01005.fsework +++|    CONTROL FI;
01019  M01S01006.fsework +++|    MOVEIO;
01020  M01S01007.fsework +++|    CONTROL IFEQ MULTI,1;
01021  M01S01008.fsework +++|      WAIT;
01022  M01S01009.fsework +++|    CONTROL FI;
01023  M01S01010.fsework +++|    CONTROL IFEQ SINGLE,1;
01024  M01S01011.fsework +++|      IF NOT FETDUN THEN DELAY;
01025  M01S01012.fsework +++|    CONTROL FI;
01026  M01S01013.fsework +++|    END
01027  M01S01014.fsework +++|
01028  M01S01015.fsework +++|  P<TOO> = LOC(BFPRU[PACACHE[PL]]);
01029  M01S01016.fsework +++|  RDWBUF(O"100");
01030  M01S01017.fsework +++|  PAHEAD[PL] = BFHEAD[PACACHE[PL]];
01031  M01S01018.fsework +++|
01032  M01S01019.fsework +++|  CONTROL IFGQ PARANOIA,5;
01033  M01S01020.fsework +++|    IF TEMP NQ RDLIST[RDOUT] THEN
01034  M01S01021.fsework +++|      BEGIN
01035  M01S01022.fsework +++|      TRAGIC(" RANDOM READ LIST INCORRECT.$");
01036  M01S01023.fsework +++|      END
01037  M01S01024.fsework +++|    IF PADA[PL] NQ TEMP THEN TRAGIC(" PRU CONTENT INCORRECT.$");
01038  M01S01025.fsework +++|    IF PADIRTY[PL] THEN
01039  M01S01026.fsework +++|      BEGIN
01040  M01S01027.fsework +++|      TRAGIC(" STATUS FLAGS SHOULD HAVE BEEN CLEARED.$");
01041  M01S01028.fsework +++|      END
01042  M01S01029.fsework +++|  CONTROL FI;
01043  M01S01030.fsework +++|
01044  M01S01031.fsework +++|  RDLIST[RDOUT] = 0;
01045  M01S01032.fsework +++|  IF RDOUT EQ RDLIM-1 THEN RDOUT = 0;
01046  M01S01033.fsework +++|  ELSE RDOUT = RDOUT + 1;
01047  M01S01034.fsework +++|  IF FETDUN AND RDIN EQ RDOUT THEN
01048  M01S01035.fsework +++|    BEGIN
01049  M01S01036.fsework +++|    RDIN=0;
01050  M01S01037.fsework +++|    RDOUT=0;
01051  M01S01038.fsework +++|    FETCHGUIDE=ABS(FETCHGUIDE);
01052  M01S01039.fsework +++|    END
01053  M01S01040.fsework +++|
01054  M01S01041.fsework +++|  IF BUFUSAGE LQ QUARTER THEN MOVEIO;
01055  M01S01042.fsework +++|
01056  M01S01043.fsework +++|  IOEND
01057  M01S01044.fsework +++|PAGE
01058  M01S01045.fsework +++|PROC ALLOC;
01059  M01S01046.fsework +++|  BEGIN
01060  M01S01047.fsework +++|#
01061  M01S01048.fsework +++|**        ALLOC - ASSIGN DISK ADDRESS.
01062  M01S01049.fsework +++|*
01063  M01S01050.fsework +++|*         ALLOC IS CALLED WHEN A NEW SECTOR MUST BE CREATED.  THE
01064  M01S01051.fsework +++|*         NEXT PRU OFF THE LOGICAL END OF THE FILE IS CHOSEN.  NOTE
01065  M01S01052.fsework +++|*         THAT THE LOGICAL END OF THE FILE REPRESENTS THOSE ADDRESSES
01066  M01S01053.fsework +++|*         WHICH HAVE BEEN ALLOCATED.  THE PHYSICAL END OF THE FILE
01067  M01S01054.fsework +++|*         REPRESENTS THOSE ADDRESSES ACTUALLY WRITTEN ONTO THE FILE,
01068  M01S01055.fsework +++|*         AND CAN BE A SMALLER NUMBER THAN THE LOGICAL END.
01069  M01S01056.fsework +++|*
01070  M01S01057.fsework +++|*         ENTRY  PL - CURRENT PATH LEVEL.
01071  M01S01058.fsework +++|*                DANEXT - ALLOCATION THRESHOLD.
01072  M01S01059.fsework +++|*
01073  M01S01060.fsework +++|*         EXIT   PADA[PL] - SETUP.
01074  M01S01061.fsework +++|*                DANEXT - INCREMENTED.
01075  M01S01062.fsework +++|*
01076  M01S01063.fsework +++|*         CALLS  TRAGIC.
01077  M01S01064.fsework +++|#
01078  M01S01065.fsework +++|  CONTROL IFGQ PARANOIA,5;
01079  M01S01066.fsework +++|    IF PADIRTY[PL] THEN TRAGIC(" OLD SECTOR MUST BE WRITTEN.$");
01080  M01S01067.fsework +++|  CONTROL FI;
01081  M01S01068.fsework +++|  PADA[PL] = DANEXT;
01082  M01S01069.fsework +++|  DANEXT = DANEXT + 1;
01083  M01S01070.fsework +++|  END
01084  M01S01071.fsework +++|
01085  M01S01072.fsework +++|
01086  M01S01073.fsework +++|PROC DEALLOC;
01087  M01S01074.fsework +++|  BEGIN
01088  M01S01075.fsework +++|#
01089  M01S01076.fsework +++|**        DEALLOC - DISCARD DISK SECTOR.
01090  M01S01077.fsework +++|*
01091  M01S01078.fsework +++|*         DEALLOC IS USED TO DISCARD A DISK SECTOR WHICH CAN NO
01092  M01S01079.fsework +++|*         LONGER BE USED.  THIS CAN BE NEEDED WHEN A SECTOR HAS
01093  M01S01080.fsework +++|*         OVERFLOWED AND HAS BEEN SPLIT INTO TWO NEW SECTORS.  IF THE
01094  M01S01081.fsework +++|*         ROOT SECTOR NEEDS TO BE SPLIT, A COMPLETE NEW TREE LEVEL IS
01095  M01S01082.fsework +++|*         CREATED WITH NEW SECTORS, THE ROOT SECTOR IS MODIFIED TO
01096  M01S01083.fsework +++|*         BECOME A DIRECTORY FOR THE NEW LEVEL, AND NO DEALLOCATION
01097  M01S01084.fsework +++|*         IS NEEDED.  IF A NON-ROOT SECTOR NEEDS TO BE SPLIT EXACTLY
01098  M01S01085.fsework +++|*         AT (JUST AFTER) ITS EXISTING LAST FIELD, THEN THAT SECTOR
01099  M01S01086.fsework +++|*         IS PRESERVED WITHOUT DEALLOCATION AND A NEW SECTOR IS
01100  M01S01087.fsework +++|*         CREATED FOR THE OVERFLOW CONTENT.  BUT IF A NON-ROOT SECTOR
01101  M01S01088.fsework +++|*         MUST BE SPLIT SOMEWHERE IN THE MIDDLE OF ITS EXISTING
01102  M01S01089.fsework +++|*         CONTENT, IT MUST BE DEALLOCATED AND BE REPLACED BY TWO
01103  M01S01090.fsework +++|*         COMPLETELY NEW SECTORS.
01104  M01S01091.fsework +++|*
01105  M01S01092.fsework +++|*         THE REASON FOR DEALLOCATION IS THAT NOTHING MUST BE ALLOWED
01106  M01S01093.fsework +++|*         TO BE POINTED TO UNTIL AND UNLESS IT ALREADY EXISTS, AS
01107  M01S01094.fsework +++|*         UPDATED TO DISK ALTHOUGH NOT NECESSARILY AS CACHED IN
01108  M01S01095.fsework +++|*         MEMORY.  SINCE A NON-ROOT SECTOR IS POINTED TO BE
01109  M01S01096.fsework +++|*         HIGHER-LEVEL DIRECOTRIES, IT CANNOT BE TOTALLY REFORMATTED
01110  M01S01097.fsework +++|*         IN PLACE, THEREFORE IT IS LEFT AS IS AND NEW SECTORS
01111  M01S01098.fsework +++|*         REPLACE IT.  THE DIRECTORIES WHICH POINT TO THE DISCARDED
01112  M01S01099.fsework +++|*         SECTOR WILL EVENTUALLY BE UPDATED THEMSELVES.  UNTIL THEN,
01113  M01S01100.fsework +++|*         THOSE HIGHER DIRECTORIES MAY BE OUT OF DATE BUT AT LEAST
01114  M01S01101.fsework +++|*         POINT TO A VALID DATA STRUCTURE.
01115  M01S01102.fsework +++|*
01116  M01S01103.fsework +++|*         ENTRY  PL - CURRENT TREE LEVEL.
01117  M01S01104.fsework +++|*
01118  M01S01105.fsework +++|*         EXIT   PADA[PL] - CLEARED AWAY.
01119  M01S01106.fsework +++|
01120  M01S01107.fsework +++|*
01121  M01S01108.fsework +++|*         CALLS  TRAGIC.
01122  M01S01109.fsework +++|#
01123  M01S01110.fsework +++|  CONTROL IFGQ PARANOIA,5;
01124  M01S01111.fsework +++|    IF PL EQ 0 OR PADA[PL] EQ 0 THEN
01125  M01S01112.fsework +++|      BEGIN
01126  M01S01113.fsework +++|      TRAGIC(" SECTOR CANNOT BE DEALLOCATED.$");
01127  M01S01114.fsework +++|      END
01128  M01S01115.fsework +++|  CONTROL FI;
01129  M01S01116.fsework +++|  PADA[PL] = 0;
01130  M01S01117.fsework +++|  PADIRTY[PL] = FALSE;
01131  M01S01118.fsework +++|  END
01132  M01S01119.fsework +++|
01133  M01S01120.fsework +++|
01134  M01S01121.fsework +++|PROC SETWRITE(PARM);
01135  M01S01122.fsework +++|  BEGIN
01136  M01S01123.fsework +++|#
01137  M01S01124.fsework +++|**        SETWRITE - SCHEDULE EXTENSION/ALTERATION OF FILE.
01138  M01S01125.fsework +++|*
01139  M01S01126.fsework +++|*         SETWRITE INITIALIZES THE FET FOR OUTPUT.  IT SETS THE IOACT
01140  M01S01127.fsework +++|*         FLAG TO INDICATE THAT I/O IS SCHEDULED, SETS IOWRITE TO
01141  M01S01128.fsework +++|*         INDICATE THAT THE I/O SHALL BE AN OUTPUT FUNCTION, AND
01142  M01S01129.fsework +++|*         SETS OR CLEARS IOAPEND ACCORDING TO WHETHER THE SECTOR TO
01143  M01S01130.fsework +++|*         BE WRITTEN IS WITHIN THE CURRENT PHYSICAL BOUNDARIES OF THE
01144  M01S01131.fsework +++|*         FILE OR REPRESENTS AN EXTENSION OF PHYSICAL SIZE.
01145  M01S01132.fsework +++|*
01146  M01S01133.fsework +++|*         ENTRY  PARM - DISK ADDRESS TO BE WRITTEN.
01147  M01S01134.fsework +++|*                MAXDA - CURRENT PHYSICAL SIZE OF FILE.
01148  M01S01135.fsework +++|*
01149  M01S01136.fsework +++|*         EXIT   FET - INITIALIZED WITH EMPTY CIRCULAR BUFFER.
01150  M01S01137.fsework +++|*                IOACT - TRUE.
01151  M01S01138.fsework +++|*                IOWRITE - TRUE.
01152  M01S01139.fsework +++|*                IOAPEND - TRUE OR FALSE BASED ON PARM AND MAXDA.
01153  M01S01140.fsework +++|*                LASTDA - SET TO KEEP TRACK OF WHERE WE ARE IN FILE.
01154  M01S01141.fsework +++|*                FETRR - SETUP.
01155  M01S01142.fsework +++|*
01156  M01S01143.fsework +++|*         CALLS  INITFET.
01157  M01S01144.fsework +++|#
01158  M01S01145.fsework +++|  ITEM PARM;
01159  M01S01146.fsework +++|
01160  M01S01147.fsework +++|  INITFET(DISK,DSKSIZ);
01161  M01S01148.fsework +++|
01162  M01S01149.fsework +++|  IOACT = TRUE;
01163  M01S01150.fsework +++|  IOWRITE = TRUE;
01164  M01S01151.fsework +++|
01165  M01S01152.fsework +++|  IF PARM GR MAXDA THEN
01166  M01S01153.fsework +++|    BEGIN
01167  M01S01154.fsework +++|    IOAPEND = TRUE;
01168  M01S01155.fsework +++|    FETRR = LOC(DUMB);
01169  M01S01156.fsework +++|    END
01170  M01S01157.fsework +++|
01171  M01S01158.fsework +++|  ELSE
01172  M01S01159.fsework +++|    BEGIN
01173  M01S01160.fsework +++|    IOAPEND = FALSE;
01174  M01S01161.fsework +++|    FETRR = PARM;
01175  M01S01162.fsework +++|    LASTDA = PARM - 1;
01176  M01S01163.fsework +++|    END
01177  M01S01164.fsework +++|
01178  M01S01165.fsework +++|  END
01179  M01S01166.fsework +++|PAGE
01180  M01S01167.fsework +++|PROC TRYWRITE(PARM,FLAG);
01181  M01S01168.fsework +++|  BEGIN
01182  M01S01169.fsework +++|#
01183  M01S01170.fsework +++|**        TRYWRITE - TRANSMIT SECTOR TO CIRCULAR BUFFER.
01184  M01S01171.fsework +++|*
01185  M01S01172.fsework +++|*         TRYWRITE ATTEMPTS TO TRANSMIT A SECTOR TO THE CIRCULAR
01186  M01S01173.fsework +++|*         BUFFER.  IT MAY FAIL TO DO SO IF THE CIRCULAR BUFFER ALREADY
01187  M01S01174.fsework +++|*         CONTAINS SECTORS FOR WHICH THIS SECTOR IS NOT CONTIGUOUS.
01188  M01S01175.fsework +++|*         THE CALLER SHOULD CALL PAUSEIO WHEN TRYWRITE FAILS, AND
01189  M01S01176.fsework +++|*         THEN CALL THIS ROUTINE AGAIN.  TRYWRITE CANNOT FAIL IF
01190  M01S01177.fsework +++|*         PAUSEIO IS USED.
01191  M01S01178.fsework +++|*
01192  M01S01179.fsework +++|*         ENTRY  P<FROM> - POINTS TO TEXT OF SECTOR.
01193  M01S01180.fsework +++|*                PARM - DISK ADDRESS.
01194  M01S01181.fsework +++|*                MAXDA - PHYSICAL FILE SIZE.
01195  M01S01182.fsework +++|*                LASTDA - MOST RECENT DISK ADDRESS TRANSMITTED.
01196  M01S01183.fsework +++|*
01197  M01S01184.fsework +++|*
01198  M01S01185.fsework +++|*         EXIT   P<FROM> - POSSIBLY DESTROYED.
01199  M01S01186.fsework +++|*                MAXDA - INCREMENTED IF FILE EXTENDED.
01200  M01S01187.fsework +++|*                LASTDA - INCREMENTED IF CONTIGUOUS EARLIER OUTPUT.
01201  M01S01188.fsework +++|*                FET - GUARANTEED SETUP FOR OUTPUT WITH THIS SECTOR
01202  M01S01189.fsework +++|*                    OF TEXT IN CIRCULAR BUFFER.  EXISTING FET SETUP
01203  M01S01190.fsework +++|*                    AND CIRCULAR BUFFER CONTENT, IF ANY, ARE NOT
01204  M01S01191.fsework +++|*                    DISTURBED WITH REGARD TO EARLIER OUTPUT.
01205  M01S01192.fsework +++|*                FLAG - TRUE IF THIS SECTOR TRANSMITTED.  FALSE IF
01206  M01S01193.fsework +++|*                    UNABLE TO TRANSMIT DUE TO DISCONTIGUITY WITH
01207  M01S01194.fsework +++|*                    EARLIER OUTPUT.
01208  M01S01195.fsework +++|*                IOACT, IOWRITE - TRUE.
01209  M01S01196.fsework +++|*                IOAPEND - SETUP.
01210  M01S01197.fsework +++|*
01211  M01S01198.fsework +++|*         CALLS  SETWRITE, WTWBUF.
01212  M01S01199.fsework +++|#
01213  M01S01200.fsework +++|  ITEM PARM, FLAG B, ZERO = 0;         # ZERO IS A CONSTANT          #
01214  M01S01201.fsework +++|
01215  M01S01202.fsework +++|  FLAG = TRUE;
01216  M01S01203.fsework +++|
01217  M01S01204.fsework +++|  IF NOT IOWRITE THEN SETWRITE(PARM);
01218  M01S01205.fsework +++|
01219  M01S01206.fsework +++|  IF IOAPEND THEN
01220  M01S01207.fsework +++|    BEGIN
01221  M01S01208.fsework +++|
01222  M01S01209.fsework +++|    IF MAXDA+1 LS PARM THEN  # ADD PADDING SECTOR          #
01223  M01S01210.fsework +++|      BEGIN
01224  M01S01211.fsework +++|      MAXDA = MAXDA + 1;
01225  M01S01212.fsework +++|      P<FROM>=LOC(ZERO);
01226  M01S01213.fsework +++|      WTWBUF(O"100");
01227  M01S01214.fsework +++|      END
01228  M01S01215.fsework +++|
01229  M01S01216.fsework +++|    ELSE IF MAXDA+1 EQ PARM THEN       # ADD REAL SECTOR   #
01230  M01S01217.fsework +++|      BEGIN
01231  M01S01218.fsework +++|      MAXDA = MAXDA+1;
01232  M01S01219.fsework +++|      WTWBUF(O"100");
01233  M01S01220.fsework +++|      END
01234  M01S01221.fsework +++|
01235  M01S01222.fsework +++|    ELSE
01236  M01S01223.fsework +++|      BEGIN
01237  M01S01224.fsework +++|      FLAG = FALSE;
01238  M01S01225.fsework +++|      END
01239  M01S01226.fsework +++|    END
01240  M01S01227.fsework +++|
01241  M01S01228.fsework +++|  ELSE
01242  M01S01229.fsework +++|    BEGIN
01243  M01S01230.fsework +++|
01244  M01S01231.fsework +++|    IF LASTDA+1 EQ PARM AND PARM LQ MAXDA THEN
01245  M01S01232.fsework +++|      BEGIN
01246  M01S01233.fsework +++|      LASTDA = LASTDA+1;
01247  M01S01234.fsework +++|      WTWBUF(O"100");
01248  M01S01235.fsework +++|      END
01249  M01S01236.fsework +++|
01250  M01S01237.fsework +++|    ELSE
01251  M01S01238.fsework +++|      BEGIN
01252  M01S01239.fsework +++|      FLAG = FALSE;
01253  M01S01240.fsework +++|      END
01254  M01S01241.fsework +++|    END
01255  M01S01242.fsework +++|
01256  M01S01243.fsework +++|  END
01257  M01S01244.fsework +++|PAGE
01258  M01S01245.fsework +++|PROC FLUSHCACHE;
01259  M01S01246.fsework +++|  IOBEGIN(FLUSHCACHE)
01260  M01S01247.fsework +++|#
01261  M01S01248.fsework +++|**        FLUSHCACHE - UPDATE ALTERED CACHE FRAMES TO DISK.
01262  M01S01249.fsework +++|*
01263  M01S01250.fsework +++|*         FLUSHCACHE IS OBLIGATED TO ASSURE THAT ALL ALTERED, UNOWNED
01264  M01S01251.fsework +++|*         CACHE PAGES BECOME UNALTERED IN CACHE.  THIS REQUIRES THAT
01265  M01S01252.fsework +++|*         SUCH PAGES BE TRANSMITTED TO THE CIRCULAR BUFFER.  THIS IN
01266  M01S01253.fsework +++|*         TURN CAN BE DONE ONLY IN ORDER OF AGE AND IN ADDRESS ORDER.
01267  M01S01254.fsework +++|*
01268  M01S01255.fsework +++|*         UNALTERED FRAMES DO NOT NEED TO BE UPDATED TO DISK.  OWNED
01269  M01S01256.fsework +++|*         FRAMES CANNOT YET BE UPDATED - IN THE AGE-RESTRICTED ORDER
01270  M01S01257.fsework +++|*         OF UPDATE, OWNED PAGES CAN BE THOUGHT OF AS HAVING THE
01271  M01S01258.fsework +++|*         WORST AGE CATEGORY.
01272  M01S01259.fsework +++|*
01273  M01S01260.fsework +++|*         EACH SECTOR CAN BE TRANSMITTED TO THE CIRCULAR BUFFER IF
01274  M01S01261.fsework +++|*         THE BUFFER AND FET ARE AVAILABLE FOR OUTPUT, AND IF THE
01275  M01S01262.fsework +++|*         BUFFER IS EITHER EMPTY OR HAS ONE OR MORE SECTORS ALREADY IN
01276  M01S01263.fsework +++|*         IT FOR WHICH THE NEW SECTOR IS CONTIGOUS IN ADDRESS.  IF THE
01277  M01S01264.fsework +++|*         FET IS ALREADY CLAIMED FOR INPUT PROCESSING, PAUSEIO CAN BE
01278  M01S01265.fsework +++|*         CALLED TO STOP AND DISCARD SUCH INPUT.  FOR SPANNED
01279  M01S01266.fsework +++|*         ADDRESSES, WE MUST CALL PAUSEIO.  THIS LOGIC IS PROVIDED BY
01280  M01S01267.fsework +++|*         INSPECTING THE FLAG RETURNED BY TRYWRITE, AND CALLING
01281  M01S01268.fsework +++|*         TRYWRITE A SECOND TIME WITH PAUSEIO, WHEN TRYWRITE FAILED.
01282  M01S01269.fsework +++|*
01283  M01S01270.fsework +++|*         BECAUSE THE ALLOCATION OF NEW SECTORS AT THE LOGICAL END OF
01284  M01S01271.fsework +++|*         THE FILE CAN RUN SEVERAL UNITS AHEAD OF THE ACTUAL
01285  M01S01272.fsework +++|*         EXTENDING OF THE PHYSICAL END OF THE FILE, AND BECAUSE THE
01286  M01S01273.fsework +++|*         AGE-DEPENDENT ORDERING MIGHT REQUIRE A HIGH ADDRESS SECTOR
01287  M01S01274.fsework +++|*         TO BE WRITTEN BEFORE A LOWER ADDRESS SECTOR MAY BE LEGALLY
01288  M01S01275.fsework +++|*         WRITTEN, A SITUATION CAN ARISE WHERE A SECTOR MUST BE
01289  M01S01276.fsework +++|*         WRITTEN SEVERAL ADDRESSES BEYOND THE CURRENT PHYSICAL END
01290  M01S01277.fsework +++|*         OF FILE.  WHEN THIS OCCURS, FLUSHCACHE RECOGNIZES THE
01291  M01S01278.fsework +++|*         SITUATION AND PADS THE PHYSICAL END OUT TO WITHIN ONE
01292  M01S01279.fsework +++|*         SECTOR OF THE SECTOR THAT MUST BE NEXT WRITTEN.  THE
01293  M01S01280.fsework +++|*         INTERMEDIATE SECTORS THUS GET A DISK IMAGE WHICH IS NOT UP
01294  M01S01281.fsework +++|*         TO DATE IN ANY WAY WHATSOEVER.  THIS IS NOT A PROBLEM - THE
01295  M01S01282.fsework +++|*         UP TO DATE FRAMES FOR SUCH PADDING WILL EVENTUALLY BE
01296  M01S01283.fsework +++|*         RELEASED FOR ACTUAL DISK UPDATE.  THE CONTENT OF PADDING
01297  M01S01284.fsework +++|*         SECTORS IS INNOCUOUS, TO FOLLOW THE RULE THAT NOTHING CAN
01298  M01S01285.fsework +++|*         BE POINTED TO ON DISK UNTIL THE OBJECT ITSELF IS UP TO DATE
01299  M01S01286.fsework +++|*         ON DISK.
01300  M01S01287.fsework +++|*
01301  M01S01288.fsework +++|*         ENTRY  CACHEDIRTY[ALL] - SETUP.
01302  M01S01289.fsework +++|*                CACHEAGE[ALL] - SETUP.
01303  M01S01290.fsework +++|*                CACHEOWNED[ALL] - SETUP.
01304  M01S01291.fsework +++|*                BFDA[ALL] - SETUP.
01305  M01S01292.fsework +++|*                IOREAD - WHETHER OBSOLETE INPUT SCHEDULED.
01306  M01S01293.fsework +++|*                IOACT - WHETHER ANY PREVIOUS I/O SCHEDULED.
01307  M01S01294.fsework +++|*                FETDUN - FET INTERLOCK.
01308  M01S01295.fsework +++|*                IOAPEND - WHETHER A PREVIOUS WRITE EXTENDS.
01309  M01S01296.fsework +++|*                QUARTER - APPROX ONE FOURTH BUFFER CAPACITY.
01310  M01S01297.fsework +++|*                ACCTPRU - SECTOR TRANSFER ACCUMULATOR.
01311  M01S01298.fsework +++|*                MAXDA - FILE PHYSICAL BOUNDARY.
01312  M01S01299.fsework +++|*
01313  M01S01300.fsework +++|*         EXIT   ALL ALTERED AND UNOWNED CACHE FRAMES OUTPUT TO DISK
01314  M01S01301.fsework +++|*                    OR BUFFERED FOR OUTPUT.
01315  M01S01302.fsework +++|*                IOREAD - FORCED FALSE IF ANY OUTPUT NEEDED.
01316  M01S01303.fsework +++|*                IOACT, IOWRITE, IOAPEND - POSSIBLY TRUE.
01317  M01S01304.fsework +++|*                CACHEDIRTY[ALL] - FALSE WHERE CACHEOWNED IS FALSE.
01318  M01S01305.fsework +++|*                ACCTPRU - INCREMENTED FOR ANY WORK DONE.
01319  M01S01306.fsework +++|*                MAXDA - INCREMENTED IF FILE EXTENDED.
01320  M01S01307.fsework +++|*
01321  M01S01308.fsework +++|*         CALLS  WIOSTAT, PUSHTEMP, POPTEMP, PAUSEIO, BUFAVAIL,
01322  M01S01309.fsework +++|*                MOVEIO, WAIT, DELAY, TRYWRITE, TRAGIC.
01323  M01S01310.fsework +++|*
01324  M01S01311.fsework +++|*         USES   P<FROM>, TEMP(RESTORED).
01325  M01S01312.fsework +++|#
01326  M01S01313.fsework +++|  ITEM TMP1, TMP2, BOOL B;
01327  M01S01314.fsework +++|  CONTROL IFEQ MULTI,1;
01328  M01S01315.fsework +++|    WIOSTAT(5);              # ACCUMULATE CACHE FLUSHES #
01329  M01S01316.fsework +++|  CONTROL FI;
01330  M01S01317.fsework +++|
01331  M01S01318.fsework +++|  PUSHTEMP;
01332  M01S01319.fsework +++|
01333  M01S01320.fsework +++|FLUSHLOOP:
01334  M01S01321.fsework +++|
01335  M01S01322.fsework +++|  TMP1=999999999;
01336  M01S01323.fsework +++|  TEMP=-1;
01337  M01S01324.fsework +++|  FOR TMP2=0 STEP 1 UNTIL MAXCACHE DO
01338  M01S01325.fsework +++|    BEGIN                     # SEARCH FOR OLDEST DIRTY     #
01339  M01S01326.fsework +++|    IF CACHEDIRTY[TMP2] AND CACHEAGE[TMP2] LS TMP1
01340  M01S01327.fsework +++|      AND NOT CACHEOWNED[TMP2] THEN
01341  M01S01328.fsework +++|      BEGIN
01342  M01S01329.fsework +++|      TEMP=TMP2;
01343  M01S01330.fsework +++|      TMP1=CACHEAGE[TMP2];
01344  M01S01331.fsework +++|      END
01345  M01S01332.fsework +++|    END
01346  M01S01333.fsework +++|  IF TEMP LS 0 THEN          # NO MORE FLUSH NEEDED        #
01347  M01S01334.fsework +++|    BEGIN
01348  M01S01335.fsework +++|    POPTEMP;
01349  M01S01336.fsework +++|    IORET
01350  M01S01337.fsework +++|    END
01351  M01S01338.fsework +++|
01352  M01S01339.fsework +++|  CACHEDIRTY[TEMP]=FALSE;
01353  M01S01340.fsework +++|  IF BFDA[TEMP] EQ 0 THEN GOTO FLUSHLOOP;
01354  M01S01341.fsework +++|
01355  M01S01342.fsework +++|  IF IOREAD THEN             # COMPLETE ANY INPUT          #
01356  M01S01343.fsework +++|    BEGIN
01357  M01S01344.fsework +++|    PAUSEIO;
01358  M01S01345.fsework +++|    CONTROL IFEQ MULTI,1;
01359  M01S01346.fsework +++|      WIOSTAT(6);            # ACCUMULATE READ REJECTS #
01360  M01S01347.fsework +++|    CONTROL FI;
01361  M01S01348.fsework +++|    END
01362  M01S01349.fsework +++|
01363  M01S01350.fsework +++|WRITELOOP:
01364  M01S01351.fsework +++|
01365  M01S01352.fsework +++|  WHYLE IOACT AND BUFAVAIL LS O"100" DO
01366  M01S01353.fsework +++|    BEGIN                     # NEED ROOM IN BUFFER         #
01367  M01S01354.fsework +++|    MOVEIO;
01368  M01S01355.fsework +++|    CONTROL IFEQ MULTI,1;
01369  M01S01356.fsework +++|      WAIT;
01370  M01S01357.fsework +++|    CONTROL FI;
01371  M01S01358.fsework +++|    CONTROL IFEQ SINGLE,1;
01372  M01S01359.fsework +++|      IF NOT FETDUN THEN DELAY;
01373  M01S01360.fsework +++|    CONTROL FI;
01374  M01S01361.fsework +++|    END
01375  M01S01362.fsework +++|
01376  M01S01363.fsework +++|  CONTROL IFEQ MULTI,1;
01377  M01S01364.fsework +++|    WIOSTAT(7);              # ACCUMULATE SECTORS WRITTEN #
01378  M01S01365.fsework +++|    ACCTPRU=ACCTPRU+1;
01379  M01S01366.fsework +++|  CONTROL FI;
01380  M01S01367.fsework +++|
01381  M01S01368.fsework +++|  P<FROM>=LOC(BFPRU[TEMP]);
01382  M01S01369.fsework +++|  TRYWRITE(BFDA[TEMP],BOOL);
01383  M01S01370.fsework +++|  IF NOT BOOL THEN
01384  M01S01371.fsework +++|    BEGIN                     # ONE FAILURE ALLOWED, NOT TWO          #
01385  M01S01372.fsework +++|    PAUSEIO;
01386  M01S01373.fsework +++|    CONTROL IFEQ MULTI,1;
01387  M01S01374.fsework +++|      WIOSTAT(8);            # ACCUMULATE DISCONTIGUOUS WRITES #
01388  M01S01375.fsework +++|    CONTROL FI;
01389  M01S01376.fsework +++|    P<FROM>=LOC(BFPRU[TEMP]);
01390  M01S01377.fsework +++|    TRYWRITE(BFDA[TEMP],BOOL);
01391  M01S01378.fsework +++|    IF NOT BOOL THEN TRAGIC(" UNABLE TO WRITE FROM BUFFER.$");
01392  M01S01379.fsework +++|    END
01393  M01S01380.fsework +++|
01394  M01S01381.fsework +++|  # EITHER ADD MORE PADDING FOR THIS FLUSH OR FLUSH ANOTHER #
01395  M01S01382.fsework +++|  IF IOAPEND AND MAXDA LS BFDA[TEMP] THEN
01396  M01S01383.fsework +++|    BEGIN
01397  M01S01384.fsework +++|    CONTROL IFEQ MULTI,1;
01398  M01S01385.fsework +++|      WIOSTAT(9);            # ACCUMULATE PADDING SECTORS #
01399  M01S01386.fsework +++|    CONTROL FI;
01400  M01S01387.fsework +++|    GOTO WRITELOOP;
01401  M01S01388.fsework +++|    END
01402  M01S01389.fsework +++|  IF BUFAVAIL LQ QUARTER THEN MOVEIO;
01403  M01S01390.fsework +++|  GOTO FLUSHLOOP;
01404  M01S01391.fsework +++|
01405  M01S01392.fsework +++|  IOEND                       # OF FLUSHCACHE       #
01406  M01S01393.fsework +++|
01407  M01S01394.fsework +++|
01408  M01S01395.fsework +++|PROC CLOSEOUT;
01409  M01S01396.fsework +++|  IOBEGIN(CLOSEOUT)
01410  M01S01397.fsework +++|#
01411  M01S01398.fsework +++|**        CLOSEOUT - FINISH UPDATE OF DISK.
01412  M01S01399.fsework +++|*
01413  M01S01400.fsework +++|*         WORKFILE CLOSEOUT CONDITIONS HAVE BEEN DETECTED.  UNDER
01414  M01S01401.fsework +++|*         CLOSEOUT CONDITIONS, WE MUST WRITE NOT ONLY THE ZERO-LEVEL
01415  M01S01402.fsework +++|*         SECTOR, BUT ALSO THE DATA SEGMENT (RIGHT AFTER ROOT SECTOR)
01416  M01S01403.fsework +++|*         FOLLOWED BY EOR THEN ARRAY SEGMENT THEN A SECOND EOR.
01417  M01S01404.fsework +++|*
01418  M01S01405.fsework +++|*         THE CLOSEOUT ROUTINE WRITES THE TWO BINARY SEGMENTS, BUT
01419  M01S01406.fsework +++|*         REQUIRES THAT THE CALLER FIRST FLUSH ALL TREE STRUCTURE
01420  M01S01407.fsework +++|*         SECTORS TO DISK OR AT LEAST TO THE CIRCULAR BUFFER.  THE
01421  M01S01408.fsework +++|*         CALLER SHOULD USE THE CLEAN ROUTINE WITH PL=0 TO MEET THAT
01422  M01S01409.fsework +++|*         REQUIREMENT.  THE CLOSEOUT ROUTINE DEPENDS ON THE RULE THAT
01423  M01S01410.fsework +++|*         THE ROOT SECTOR OF THE TREE STRUCTURE MUST BE THE LAST
01424  M01S01411.fsework +++|*         (CHRONOLOGICALLY) TO BE FREED FOR UPDATE TO DISK, AND
01425  M01S01412.fsework +++|*         DEPENDS ON THE RULE THAT THE ROOT SECTOR IS AT DISK ADDRESS
01426  M01S01413.fsework +++|*         1 AND THEREFORE IS CONTIGUOUS WITH NO PREVIOUSLY RELEASED
01427  M01S01414.fsework +++|*         SECTORS.  THUS, CLOSEOUT EXPECTS THAT ALL SECTORS EXCEPT
01428  M01S01415.fsework +++|*         THE ROOT HAVE BEEN ACTUALLY WRITTEN TO DISK, AND THE ROOT
01429  M01S01416.fsework +++|*         SECTOR IS EXPECTED TO BE SCHEDULED FOR UPDATE BUT STILL IS
01430  M01S01417.fsework +++|*         PRESENT IN THE CIRCULAR BUFFER.
01431  M01S01418.fsework +++|*
01432  M01S01419.fsework +++|*         CLOSEOUT INTERCEPTS THE ISSUANCE OF CIO FUNCTION CODES FOR
01433  M01S01420.fsework +++|*         THE UPDATE OF THE ROOT SECTOR, AND AFTER APPENDING THE
01434  M01S01421.fsework +++|*         SCALAR DATA SEGMENT ONTO THE ROOT SECTOR IN THE CIRCULAR
01435  M01S01422.fsework +++|*         BUFFER, CLOSEOUT CALLS PAUSEIO (AND THUS MOVEIO) SUCH THAT
01436  M01S01423.fsework +++|*         ONE WRITE WITH END OF RECORD OCCURS.  THEN CLOSEOUT
01437  M01S01424.fsework +++|*         CONSTRUCTS A NEW CIRCULAR BUFFER IMAGE FOR THE ARRAY
01438  M01S01425.fsework +++|*         SEGMENT, AND USES PAUSEIO A SECOND TIME TO WRITE ANOTHER
01439  M01S01426.fsework +++|*         MULTIPLE SECTOR RECORD.
01440  M01S01427.fsework +++|*
01441  M01S01428.fsework +++|*         ENTRY  CLEAN HAS BEEN CALLED WITH PL=0.
01442  M01S01429.fsework +++|*                IOAPEND - WHETHER FILE PRESENTLY EMPTY.
01443  M01S01430.fsework +++|*                LASTDA, MAXDA - LOGICAL AND PHYSICAL FILE SIZES.
01444  M01S01431.fsework +++|*                DATALEN, ARRAYLEN - LENGTHS OF BINARY SEGMENTS.
01445  M01S01432.fsework +++|*                DATAPRUS, ARRAYPRUS - LENGTHS IN SECTORS.
01446  M01S01433.fsework +++|*
01447  M01S01434.fsework +++|*         EXIT   FILE COMPLETELY DRAINED TO DISK, FET INACTIVE.
01448  M01S01435.fsework +++|*                LASTDA, MAXDA - ONE OF THESE TWO IS INCREMENTED.
01449  M01S01436.fsework +++|*
01450  M01S01437.fsework +++|*         CALLS  FLUSHCACHE, WTWBUF, PAUSEIO, INITFET.
01451  M01S01438.fsework +++|*
01452  M01S01439.fsework +++|*         USES   P<FROM>, IOWRITE, IOWRTEOR, IOAPEND, IOACT.
01453  M01S01440.fsework +++|#
01454  M01S01441.fsework +++|  FLUSHCACHE;        # PUT SECTOR 1 (ROOT PRU) INTO BUFFER   #
01455  M01S01442.fsework +++|  IOWRTEOR=TRUE;     # WRITE ROOT PRU PLUS DATA SEGMENT      #
01456  M01S01443.fsework +++|  P<FROM>=LOC(DATASTART);
01457  M01S01444.fsework +++|  WTWBUF(DATALEN);
01458  M01S01445.fsework +++|  IF IOAPEND THEN MAXDA=MAXDA+DATAPRUS;
01459  M01S01446.fsework +++|  ELSE LASTDA=LASTDA+DATAPRUS;
01460  M01S01447.fsework +++|  PAUSEIO;
01461  M01S01448.fsework +++|  INITFET(DISK,DSKSIZ);        # NOW SET UP FOR ARRAYS       #
01462  M01S01449.fsework +++|  IOACT=TRUE;
01463  M01S01450.fsework +++|  IOWRITE=TRUE;
01464  M01S01451.fsework +++|  IF FETCRI GR MAXDA THEN
01465  M01S01452.fsework +++|    BEGIN
01466  M01S01453.fsework +++|    IOAPEND=TRUE;
01467  M01S01454.fsework +++|    FETRR=LOC(DUMB);
01468  M01S01455.fsework +++|    MAXDA=MAXDA+ARRAYPRUS;
01469  M01S01456.fsework +++|    END
01470  M01S01457.fsework +++|  ELSE
01471  M01S01458.fsework +++|    BEGIN
01472  M01S01459.fsework +++|    IOAPEND=FALSE;
01473  M01S01460.fsework +++|    FETRR=FETCRI;
01474  M01S01461.fsework +++|    LASTDA=LASTDA+ARRAYPRUS;
01475  M01S01462.fsework +++|    END
01476  M01S01463.fsework +++|  IOWRTEOR=TRUE;
01477  M01S01464.fsework +++|  P<FROM>=LOC(ARRAYSTART);
01478  M01S01465.fsework +++|  WTWBUF(ARRAYLEN);
01479  M01S01466.fsework +++|  PAUSEIO;
01480  M01S01467.fsework +++|  IOEND                       # OF CLOSEOUT       #
01481  M01S01468.fsework +++|PAGE
01482  M01S01469.fsework +++|PROC CLEAN;
01483  M01S01470.fsework +++|  IOBEGIN(CLEAN)
01484  M01S01471.fsework +++|#
01485  M01S01472.fsework +++|**        CLEAN - DISCONNECT SECTOR FROM LOWEST TREE LEVEL.
01486  M01S01473.fsework +++|*
01487  M01S01474.fsework +++|*         CLEAN IS CALLED WHENEVER A ROUTINE WISHES TO DISCARD THE
01488  M01S01475.fsework +++|*         SECTOR PRESENTLY ASSOCIATED WITH A TREE LEVEL.  THIS CAN BE
01489  M01S01476.fsework +++|*         DONE ONLY IN THE REVERSE ORDER OF THE TREE HIERARCHY, IE,
01490  M01S01477.fsework +++|*         THE BOTTOM LEVEL FIRST AND THE ROOT LEVEL LAST.  THE EFFECT
01491  M01S01478.fsework +++|*         OF CALLING CLEAN IS TO DISCONNECT THE SECTOR FROM THE TREE
01492  M01S01479.fsework +++|*         STRUCTURE BY FREEING THE CACHE FRAME FROM OWNERSHIP, FIRST
01493  M01S01480.fsework +++|*         DISCONNECTING ANY TREE LEVELS LOWER THAN THE CURRENT LEVEL.
01494  M01S01481.fsework +++|*
01495  M01S01482.fsework +++|*         IF THE TREE LEVEL WAS PREVIOUSLY FLAGGED AS ALTERED, THE
01496  M01S01483.fsework +++|*         FREED CACHE FRAME IS SIMILARLY FLAGGED.  ALL HEADER WORD
01497  M01S01484.fsework +++|*         DATA IS COPIED FROM THE TREE CONTROL VECTOR TO THE SECTOR
01498  M01S01485.fsework +++|*         IMAGE IN CACHE.
01499  M01S01486.fsework +++|*
01500  M01S01487.fsework +++|*         ENTRY  PL - LEVEL TO BE FREED.
01501  M01S01488.fsework +++|*                PALVL - DEEPEST ACTIVE TREE LEVEL.
01502  M01S01489.fsework +++|*                PAHEAD[ALL] - HEADER WORDS IN TREE VECTOR.
01503  M01S01490.fsework +++|*                PACACHE[ALL] - SETUP.
01504  M01S01491.fsework +++|*                CACHEOWNED[ALL] - SETUP.
01505  M01S01492.fsework +++|*                PADIRTY[ALL] - ALTERATION FLAG.
01506  M01S01493.fsework +++|*
01507  M01S01494.fsework +++|*         EXIT   THIS LEVEL AND ALL DEEPER LEVELS FREED.
01508  M01S01495.fsework +++|*                CACHEOWNED[ANY] - FORCED TRUE FOR THOSE FREED.
01509  M01S01496.fsework +++|*                CACHEDIRTY[ANY] - FORCED TRUE FOR THOSE FREED
01510  M01S01497.fsework +++|*                    WITH PADIRTY TRUE.
01511  M01S01498.fsework +++|*                CACHEAGE[ANY] - INITIALIZED FOR THOSE FREED.
01512  M01S01499.fsework +++|*
01513  M01S01500.fsework +++|*         CALLS  DROPIT(INTERNAL), DISOWNCACHE.
01514  M01S01501.fsework +++|*
01515  M01S01502.fsework +++|*         USES   TPL.
01516  M01S01503.fsework +++|#
01517  M01S01504.fsework +++|
01518  M01S01505.fsework +++|  PROC DROPIT;
01519  M01S01506.fsework +++|    BEGIN
01520  M01S01507.fsework +++|    IF CACHEOWNED[PACACHE[TPL]] THEN BFHEAD[PACACHE[TPL]]=PAHEAD[TPL];
01521  M01S01508.fsework +++|    DISOWNCACHE(PACACHE[TPL]);
01522  M01S01509.fsework +++|    END                       # OF DROPIT         #
01523  M01S01510.fsework +++|
01524  M01S01511.fsework +++|  # START OF MAIN CODE #
01525  M01S01512.fsework +++|
01526  M01S01513.fsework +++|  IF PADIRTY[PL] THEN
01527  M01S01514.fsework +++|    BEGIN
01528  M01S01515.fsework +++|    FOR TPL = PALVL STEP -1 UNTIL PL DO
01529  M01S01516.fsework +++|      BEGIN
01530  M01S01517.fsework +++|      IF PADIRTY[TPL] THEN
01531  M01S01518.fsework +++|        BEGIN
01532  M01S01519.fsework +++|        PADIRTY[TPL]=FALSE;
01533  M01S01520.fsework +++|        CACHEDIRTY[PACACHE[TPL]]=TRUE;
01534  M01S01521.fsework +++|        DROPIT;
01535  M01S01522.fsework +++|        END
01536  M01S01523.fsework +++|      ELSE DROPIT;
01537  M01S01524.fsework +++|      END
01538  M01S01525.fsework +++|    END
01539  M01S01526.fsework +++|  ELSE
01540  M01S01527.fsework +++|    BEGIN
01541  M01S01528.fsework +++|    FOR TPL=PALVL STEP -1 UNTIL PL DO DROPIT;
01542  M01S01529.fsework +++|    END
01543  M01S01530.fsework +++|
01544  M01S01531.fsework +++|  IOEND
01545  M01S01532.fsework +++|
01546  M01S01533.fsework +++|
01547  M01S01534.fsework +++|PROC CLEANALL;
01548  M01S01535.fsework +++|  IOBEGIN(CLEANALL)
01549  M01S01536.fsework +++|#
01550  M01S01537.fsework +++|**        CLEANALL - CLEAN ENTIRE TREE STRUCTURE AND DATA SEGEMENTS.
01551  M01S01538.fsework +++|*
01552  M01S01539.fsework +++|*         CLEANALL IS USED TO INITIATE CLOSEOUT OF THE WORKFILE
01553  M01S01540.fsework +++|*         MANAGER.  THE ENTIRE TREE STRUCTURE IS CLEANED WITH ANY
01554  M01S01541.fsework +++|*         ALTERED SECTORS WRITTEN TO DISK, AND THE SCALAR AND ARRAY
01555  M01S01542.fsework +++|*         DATA SEGMENTS ARE UPDATED.
01556  M01S01543.fsework +++|*
01557  M01S01544.fsework +++|*         ENTRY  CACHEOWNED[ALL] - SETUP.
01558  M01S01545.fsework +++|*                PACACHE[ALL] - SETUP.
01559  M01S01546.fsework +++|*                PADIRTY[ALL] - SETUP.
01560  M01S01547.fsework +++|*                PAHEAD[ALL] -SETUP.
01561  M01S01548.fsework +++|*                PALVL - DEEPEST TREE LEVEL.
01562  M01S01549.fsework +++|*
01563  M01S01550.fsework +++|*         EXIT   PL - ZERO.
01564  M01S01551.fsework +++|*                CACHEDIRTY[ALL] - FALSE.
01565  M01S01552.fsework +++|*                FET AND CIRCULAR BUFFER - COMPLETE/EMPTY.
01566  M01S01553.fsework +++|*                PADIRTY[ALL] - FALSE.
01567  M01S01554.fsework +++|*
01568  M01S01555.fsework +++|*         CALLS  CLEAN, CLOSEOUT, RECLAIMCACHE.
01569  M01S01556.fsework +++|#
01570  M01S01557.fsework +++|  PADIRTY[0]=TRUE;
01571  M01S01558.fsework +++|  PL=0;
01572  M01S01559.fsework +++|  CLEAN;
01573  M01S01560.fsework +++|  CLOSEOUT;
01574  M01S01561.fsework +++|  RECLAIMCACHE;
01575  M01S01562.fsework +++|  IOEND                       # OF CLEANALL       #
01576  M01S01563.fsework +++|PAGE
01577  M01S01564.fsework +++|PROC BK;
01578  M01S01565.fsework +++|  IOBEGIN(BK)
01579  M01S01566.fsework +++|#
01580  M01S01567.fsework +++|**        BK - BACK UP ONE LINE.
01581  M01S01568.fsework +++|*
01582  M01S01569.fsework +++|*         BK IS ORGANIZED INTO THREE OPERATIONAL PHASES.  THE FIRST
01583  M01S01570.fsework +++|*         PHASE DETERMINES WHETHER THE CURRENT TREE PATH ALREADY
01584  M01S01571.fsework +++|*         CONTAINS THE SECTOR WITH THE DESIRED LINE OF TEXT, AND IF
01585  M01S01572.fsework +++|*         NOT, IT CLEANS AWAY AS MANY TREE LEVELS AS NECESSARY, FROM
01586  M01S01573.fsework +++|*         THE BOTTOM TOWARDS THE ROOT, UNTIL WE ARE IN A DIRECTORY
01587  M01S01574.fsework +++|*         WHOSE SPHERE OF INFLUENCE INCLUDES THE DESIRED LINE.
01588  M01S01575.fsework +++|*
01589  M01S01576.fsework +++|*         THE SECOND PHASE ASSURES THAT WE HAVE A FULL DEPTH TREE
01590  M01S01577.fsework +++|*         STRUCTURE CONTAINING THE RIGHT SECTOR AT THE DATA (BOTTOM)
01591  M01S01578.fsework +++|*         LEVEL.  IF THE FIRST PHASE WAS NON-TRIVIAL, THEN THE SECOND
01592  M01S01579.fsework +++|*         PHASE WILL ALSO HAVE REAL WORK TO PERFORM, WORKING BACK
01593  M01S01580.fsework +++|*         TOWARD DEEP TREE LEVELS, READING IN EACH SECTOR NEEDED.
01594  M01S01581.fsework +++|*         THE SECOND PHASE IS A NO-OP IF THE FIRST PHASE WAS A NO-OP
01595  M01S01582.fsework +++|*         AND IF THE TREE ALREADY EXISTS ALL THE WAY DOWN TO THE DATA
01596  M01S01583.fsework +++|*         LEVEL.  HOWEVER, THE FIRST PHASE COULD HAVE BEEN A NO-OP
01597  M01S01584.fsework +++|*         FOR AN INCOMPLETE TREE PATH, IN WHICH CASE THE SECOND PHASE
01598  M01S01585.fsework +++|*         MUST DEEPEN THE TREE PATH.
01599  M01S01586.fsework +++|*
01600  M01S01587.fsework +++|*         THE THIRD PHASE SCANS THE DATA SECTOR TO FIND THE RIGHT
01601  M01S01588.fsework +++|*         LINE IMAGE.  THE INTERNAL LINE IMAGE FORMAT USES THE SIGN
01602  M01S01589.fsework +++|*         BIT TO INDICATE WORDS WHICH ARE THE LAST WORDS OF LINES.
01603  M01S01590.fsework +++|*
01604  M01S01591.fsework +++|*         ENTRY  CURRENT - CURRENT LINE.
01605  M01S01592.fsework +++|*                PALVL - DEEPEST TREE LEVEL.
01606  M01S01593.fsework +++|*                ALL PATH AND CACHE CONTROLS SETUP.
01607  M01S01594.fsework +++|*                P<MVLNBUF> - WHERE TO PUT LINE OF TEXT.
01608  M01S01595.fsework +++|*                DISP, CURNW - DESCRIBE WORD OFFSET AND LENGTH OF
01609  M01S01596.fsework +++|*                    PREVIOUS CURRENT LINE.
01610  M01S01597.fsework +++|*
01611  M01S01598.fsework +++|*         EXIT   CURRENT - DECREMENTED.
01612  M01S01599.fsework +++|*                MVLNBUF - CONTAINS LINE OF TEXT.
01613  M01S01600.fsework +++|*                PALVL - NEW VALUE FOR DEEPEST TREE LEVEL.
01614  M01S01601.fsework +++|*                ALL PATH CONTROLS - MAY CONTROL DIFFERENT SECTORS
01615  M01S01602.fsework +++|*                    FOR DEEPER TREE LEVELS.
01616  M01S01603.fsework +++|*                ALL CACHE CONTROLS - MAY CONTROL DIFFERENT SECTORS.
01617  M01S01604.fsework +++|*                FET, CIRCULAR BUFFER, READ LIST - MAY CONTROL
01618  M01S01605.fsework +++|*                    A PREFETCH OPERATION.
01619  M01S01606.fsework +++|*                CURNW - SIZE OF NEW LINE.
01620  M01S01607.fsework +++|*                DISP - OFFSET OF NEW LINE.
01621  M01S01608.fsework +++|*
01622  M01S01609.fsework +++|*         CALLS  TRAGIC, CLEAN, PUSHTEMP, READPA, POPTEMP, PREFETCH,
01623  M01S01610.fsework +++|*                MOVELN.
01624  M01S01611.fsework +++|*
01625  M01S01612.fsework +++|*         USES   TEMP(RESTORED), P<PRU>, PL.
01626  M01S01613.fsework +++|#
01627  M01S01614.fsework +++|  IF CURRENT LQ 0 THEN TRAGIC(" BAK BEFORE START OF FILE.$");
01628  M01S01615.fsework +++|
01629  M01S01616.fsework +++|  CURRENT = CURRENT - 1;
01630  M01S01617.fsework +++|
01631  M01S01618.fsework +++|  FOR PL = PALVL WHILE PAFIRST[PL] GR CURRENT DO
01632  M01S01619.fsework +++|    BEGIN
01633  M01S01620.fsework +++|    CLEAN;
01634  M01S01621.fsework +++|    PL = PL - 1;
01635  M01S01622.fsework +++|    END
01636  M01S01623.fsework +++|
01637  M01S01624.fsework +++|  P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01638  M01S01625.fsework +++|
01639  M01S01626.fsework +++|  DISP = PADISP[PL] - 1;
01640  M01S01627.fsework +++|  CONTROL IFGQ PARANOIA,5;
01641  M01S01628.fsework +++|    IF DISP LQ 0 THEN TRAGIC(" DIRECTORY BLOCK POINTER TOO SMALL.$");
01642  M01S01629.fsework +++|  CONTROL FI;
01643  M01S01630.fsework +++|  PADISP[PL] = DISP;
01644  M01S01631.fsework +++|
01645  M01S01632.fsework +++|  IF PADIR[PL] THEN
01646  M01S01633.fsework +++|    BEGIN
01647  M01S01634.fsework +++|    FOR PL = PL WHILE PADIR[PL] DO
01648  M01S01635.fsework +++|      BEGIN
01649  M01S01636.fsework +++|      PL = PL + 1;
01650  M01S01637.fsework +++|      PALVL = PL;
01651  M01S01638.fsework +++|
01652  M01S01639.fsework +++|      PUSHTEMP;
01653  M01S01640.fsework +++|      TEMP=DIRDA[DISP];
01654  M01S01641.fsework +++|      READPA;
01655  M01S01642.fsework +++|      POPTEMP;
01656  M01S01643.fsework +++|
01657  M01S01644.fsework +++|      PAFIRST[PL] = CURRENT - DIRNL[DISP] + 1;
01658  M01S01645.fsework +++|      PALAST[PL] = CURRENT;
01659  M01S01646.fsework +++|
01660  M01S01647.fsework +++|      P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01661  M01S01648.fsework +++|
01662  M01S01649.fsework +++|      DISP = PAFINAL[PL];
01663  M01S01650.fsework +++|      PADISP[PL] = DISP;
01664  M01S01651.fsework +++|      END
01665  M01S01652.fsework +++|
01666  M01S01653.fsework +++|    PREFETCH(-1);
01667  M01S01654.fsework +++|    END
01668  M01S01655.fsework +++|
01669  M01S01656.fsework +++|  # NOTE THIS CODE REQUIRES INTERNAL CHARSET USAGE OF SIGN BIT #
01670  M01S01657.fsework +++|  FOR DISP = DISP - 1 WHILE DISP NQ 0 AND B<0,1>DATWORD[DISP] EQ 0
01671  M01S01658.fsework +++|    DO DISP = DISP - 1;
01672  M01S01659.fsework +++|
01673  M01S01660.fsework +++|  PADISP[PL] = DISP + 1;
01674  M01S01661.fsework +++|  P<FROM> = LOC(BFPRU[PACACHE[PALVL]]) + PADISP[PALVL];
01675  M01S01662.fsework +++|  CURNW = MOVELN(FROM,MVLNBUF);
01676  M01S01663.fsework +++|
01677  M01S01664.fsework +++|  IOEND
01678  M01S01665.fsework +++|PAGE
01679  M01S01666.fsework +++|PROC FW;
01680  M01S01667.fsework +++|  IOBEGIN(FW)
01681  M01S01668.fsework +++|#
01682  M01S01669.fsework +++|**        FW - ADVANCE ONE LINE.
01683  M01S01670.fsework +++|*
01684  M01S01671.fsework +++|*         FW IS ORGANIZED INTO THREE OPERATIONAL PHASES.  THE FIRST
01685  M01S01672.fsework +++|*         PHASE DETERMINES WHETHER THE CURRENT TREE PATH ALREADY
01686  M01S01673.fsework +++|*         CONTAINS THE SECTOR WITH THE DESIRED LINE OF TEXT, AND IF
01687  M01S01674.fsework +++|*         NOT, IT CLEANS AWAY AS MANY TREE LEVELS AS NECESSARY, FROM
01688  M01S01675.fsework +++|*         THE BOTTOM TOWARDS THE ROOT, UNTIL WE ARE IN A DIRECTORY
01689  M01S01676.fsework +++|*         WHOSE SPHERE OF INFLUENCE INCLUDES THE DESIRED LINE.
01690  M01S01677.fsework +++|*
01691  M01S01678.fsework +++|*         THE SECOND PHASE ASSURES THAT WE HAVE A FULL DEPTH TREE
01692  M01S01679.fsework +++|*         STRUCTURE CONTAINING THE RIGHT SECTOR AT THE DATA (BOTTOM)
01693  M01S01680.fsework +++|*         LEVEL.  IF THE FIRST PHASE WAS NON-TRIVIAL, THEN THE SECOND
01694  M01S01681.fsework +++|*         PHASE WILL ALSO HAVE REAL WORK TO PERFORM, WORKING BACK
01695  M01S01682.fsework +++|*         TOWARD DEEP TREE LEVELS, READING IN EACH SECTOR NEEDED.
01696  M01S01683.fsework +++|*         THE SECOND PHASE IS A NO-OP IF THE FIRST PHASE WAS A NO-OP
01697  M01S01684.fsework +++|*         AND IF THE TREE ALREADY EXISTS ALL THE WAY DOWN TO THE DATA
01698  M01S01685.fsework +++|*         LEVEL.  HOWEVER, THE FIRST PHASE COULD HAVE BEEN A NO-OP
01699  M01S01686.fsework +++|*         FOR AN INCOMPLETE TREE PATH, IN WHICH CASE THE SECOND PHASE
01700  M01S01687.fsework +++|*         MUST DEEPEN THE TREE PATH.
01701  M01S01688.fsework +++|*
01702  M01S01689.fsework +++|*         THE THIRD PHASE IDENTIFIES THE CORRECT LINE IMAGE WITHIN
01703  M01S01690.fsework +++|*         THE DATA SECTOR.  THE MECHANISM USED DEPENDS ON WHETHER THE
01704  M01S01691.fsework +++|*         SECOND PHASE WAS ACTUALLY PERFORMED, SINCE FOR A NO-OP THE
01705  M01S01692.fsework +++|*         DISP AND CURNW PARAMETERS FOR THE PREVIOUS CURRENT LINE
01706  M01S01693.fsework +++|*         PROVIDE ALL INFORMATION REQUIRED TO ADVANCE ONE LINE.
01707  M01S01694.fsework +++|*
01708  M01S01695.fsework +++|*         ENTRY  CURRENT - CURRENT LINE.
01709  M01S01696.fsework +++|*                PALVL - DEEPEST TREE LEVEL.
01710  M01S01697.fsework +++|*                ALL PATH AND CACHE CONTROLS SETUP.
01711  M01S01698.fsework +++|*                P<MVLNBUF> - WHERE TO PUT LINE OF TEXT.
01712  M01S01699.fsework +++|*                DISP, CURNW - DESCRIBE WORD OFFSET AND LENGTH OF
01713  M01S01700.fsework +++|*                    PREVIOUS CURRENT LINE.
01714  M01S01701.fsework +++|*
01715  M01S01702.fsework +++|*         EXIT   CURRENT - INCREMENTED.
01716  M01S01703.fsework +++|*                MVLNBUF - CONTAINS LINE OF TEXT.
01717  M01S01704.fsework +++|*                PALVL - NEW VALUE FOR DEEPEST TREE LEVEL.
01718  M01S01705.fsework +++|*                ALL PATH CONTROLS - MAY CONTROL DIFFERENT SECTORS
01719  M01S01706.fsework +++|*                    FOR DEEPER TREE LEVELS.
01720  M01S01707.fsework +++|*                ALL CACHE CONTROLS - MAY CONTROL DIFFERENT SECTORS.
01721  M01S01708.fsework +++|*                FET, CIRCULAR BUFFER, READ LIST - MAY CONTROL
01722  M01S01709.fsework +++|*                    A PREFETCH OPERATION.
01723  M01S01710.fsework +++|*                CURNW - SIZE OF NEW LINE.
01724  M01S01711.fsework +++|*                DISP - OFFSET OF NEW LINE.
01725  M01S01712.fsework +++|*
01726  M01S01713.fsework +++|*         CALLS  TRAGIC, CLEAN, PUSHTEMP, READPA, POPTEMP, PREFETCH,
01727  M01S01714.fsework +++|*                MOVELN.
01728  M01S01715.fsework +++|*
01729  M01S01716.fsework +++|*         USES   TEMP(RESTORED), P<PRU>, PL.
01730  M01S01717.fsework +++|#
01731  M01S01718.fsework +++|
01732  M01S01719.fsework +++|  IF CURRENT GQ PALAST[0] THEN TRAGIC(" FWD BEYOND END OF FILE.$");
01733  M01S01720.fsework +++|
01734  M01S01721.fsework +++|  CURRENT = CURRENT + 1;
01735  M01S01722.fsework +++|
01736  M01S01723.fsework +++|  FOR PL = PALVL WHILE PALAST[PL] LS CURRENT DO
01737  M01S01724.fsework +++|    BEGIN
01738  M01S01725.fsework +++|    CLEAN;
01739  M01S01726.fsework +++|    PL = PL - 1;
01740  M01S01727.fsework +++|    END
01741  M01S01728.fsework +++|
01742  M01S01729.fsework +++|  P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01743  M01S01730.fsework +++|
01744  M01S01731.fsework +++|  DISP = PADISP[PL];
01745  M01S01732.fsework +++|
01746  M01S01733.fsework +++|  IF PADIR[PL] THEN
01747  M01S01734.fsework +++|    BEGIN
01748  M01S01735.fsework +++|    DISP = DISP + 1;
01749  M01S01736.fsework +++|    CONTROL IFGQ PARANOIA,5;
01750  M01S01737.fsework +++|      IF DISP GR PAFINAL[PL] THEN
01751  M01S01738.fsework +++|        BEGIN
01752  M01S01739.fsework +++|        TRAGIC(" DIRECTORY BLOCK POINTER TOO LARGE (1).$");
01753  M01S01740.fsework +++|        END
01754  M01S01741.fsework +++|    CONTROL FI;
01755  M01S01742.fsework +++|    PADISP[PL] = DISP;
01756  M01S01743.fsework +++|
01757  M01S01744.fsework +++|    FOR PL = PL WHILE PADIR[PL] DO
01758  M01S01745.fsework +++|      BEGIN
01759  M01S01746.fsework +++|      PL = PL + 1;
01760  M01S01747.fsework +++|      PALVL = PL;
01761  M01S01748.fsework +++|
01762  M01S01749.fsework +++|      PUSHTEMP;
01763  M01S01750.fsework +++|      TEMP=DIRDA[DISP];
01764  M01S01751.fsework +++|      READPA;
01765  M01S01752.fsework +++|      POPTEMP;
01766  M01S01753.fsework +++|
01767  M01S01754.fsework +++|      PAFIRST[PL] = CURRENT;
01768  M01S01755.fsework +++|      PALAST[PL] = CURRENT + DIRNL[DISP] - 1;
01769  M01S01756.fsework +++|
01770  M01S01757.fsework +++|      P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01771  M01S01758.fsework +++|
01772  M01S01759.fsework +++|      DISP = 1;
01773  M01S01760.fsework +++|      PADISP[PL] = 1;
01774  M01S01761.fsework +++|      END
01775  M01S01762.fsework +++|
01776  M01S01763.fsework +++|    PREFETCH(+1);
01777  M01S01764.fsework +++|    END
01778  M01S01765.fsework +++|
01779  M01S01766.fsework +++|  ELSE PADISP[PL] = DISP + CURNW;
01780  M01S01767.fsework +++|
01781  M01S01768.fsework +++|  P<FROM> = LOC(BFPRU[PACACHE[PALVL]]) + PADISP[PALVL];
01782  M01S01769.fsework +++|  CURNW = MOVELN(FROM,MVLNBUF);
01783  M01S01770.fsework +++|
01784  M01S01771.fsework +++|  IOEND
01785  M01S01772.fsework +++|PAGE
01786  M01S01773.fsework +++|PROC POSR;
01787  M01S01774.fsework +++|  IOBEGIN(POSR)
01788  M01S01775.fsework +++|#
01789  M01S01776.fsework +++|**        POSR - POSITION TO A RANDOMLY SELECTED LINE.
01790  M01S01777.fsework +++|*
01791  M01S01778.fsework +++|*         POSR IS ORGANIZED INTO THREE OPERATIONAL PHASES.  THE FIRST
01792  M01S01779.fsework +++|*         PHASE DETERMINES WHETHER THE CURRENT TREE PATH ALREADY
01793  M01S01780.fsework +++|*         CONTAINS THE SECTOR WITH THE DESIRED LINE OF TEXT, AND IF
01794  M01S01781.fsework +++|*         NOT, IT CLEANS AWAY AS MANY TREE LEVELS AS NECESSARY, FROM
01795  M01S01782.fsework +++|*         THE BOTTOM TOWARDS THE ROOT, UNTIL WE ARE IN A DIRECTORY
01796  M01S01783.fsework +++|*         WHOSE SPHERE OF INFLUENCE INCLUDES THE DESIRED LINE.
01797  M01S01784.fsework +++|*
01798  M01S01785.fsework +++|*         THE SECOND PHASE ASSURES THAT WE HAVE A FULL DEPTH TREE
01799  M01S01786.fsework +++|*         STRUCTURE CONTAINING THE RIGHT SECTOR AT THE DATA (BOTTOM)
01800  M01S01787.fsework +++|*         LEVEL.  IF THE FIRST PHASE WAS NON-TRIVIAL, THEN THE SECOND
01801  M01S01788.fsework +++|*         PHASE WILL ALSO HAVE REAL WORK TO PERFORM, WORKING BACK
01802  M01S01789.fsework +++|*         TOWARD DEEP TREE LEVELS, READING IN EACH SECTOR NEEDED.
01803  M01S01790.fsework +++|*         THE SECOND PHASE IS A NO-OP IF THE FIRST PHASE WAS A NO-OP
01804  M01S01791.fsework +++|*         AND IF THE TREE ALREADY EXISTS ALL THE WAY DOWN TO THE DATA
01805  M01S01792.fsework +++|*         LEVEL.  HOWEVER, THE FIRST PHASE COULD HAVE BEEN A NO-OP
01806  M01S01793.fsework +++|*         FOR AN INCOMPLETE TREE PATH, IN WHICH CASE THE SECOND PHASE
01807  M01S01794.fsework +++|*         MUST DEEPEN THE TREE PATH.
01808  M01S01795.fsework +++|*
01809  M01S01796.fsework +++|*         THE THIRD PHASE SCANS THE DATA SECTOR TO FIND THE RIGHT
01810  M01S01797.fsework +++|*         LINE IMAGE.  THE INTERNAL LINE IMAGE FORMAT USES THE SIGN
01811  M01S01798.fsework +++|*         BIT TO INDICATE WORDS WHICH ARE THE LAST WORDS OF LINES.
01812  M01S01799.fsework +++|*
01813  M01S01800.fsework +++|*         ENTRY  NEWCURL - DESIRED LINE.
01814  M01S01801.fsework +++|*                PALVL - DEEPEST TREE LEVEL.
01815  M01S01802.fsework +++|*                ALL PATH AND CACHE CONTROLS SETUP.
01816  M01S01803.fsework +++|*                P<MVLNBUF> - WHERE TO PUT LINE OF TEXT.
01817  M01S01804.fsework +++|*                DISP, CURNW - DESCRIBE WORD OFFSET AND LENGTH OF
01818  M01S01805.fsework +++|*                    PREVIOUS CURRENT LINE.
01819  M01S01806.fsework +++|*
01820  M01S01807.fsework +++|*         EXIT   CURRENT - MATCHES NEWCURL.
01821  M01S01808.fsework +++|*                MVLNBUF - CONTAINS LINE OF TEXT.
01822  M01S01809.fsework +++|*                PALVL - NEW VALUE FOR DEEPEST TREE LEVEL.
01823  M01S01810.fsework +++|*                ALL PATH CONTROLS - MAY CONTROL DIFFERENT SECTORS
01824  M01S01811.fsework +++|*                    FOR DEEPER TREE LEVELS.
01825  M01S01812.fsework +++|*                ALL CACHE CONTROLS - MAY CONTROL DIFFERENT SECTORS.
01826  M01S01813.fsework +++|*                FET, CIRCULAR BUFFER, READ LIST - MAY CONTROL
01827  M01S01814.fsework +++|*                    A PREFETCH OPERATION.
01828  M01S01815.fsework +++|*                CURNW - SIZE OF NEW LINE.
01829  M01S01816.fsework +++|*                DISP - OFFSET OF NEW LINE.
01830  M01S01817.fsework +++|*
01831  M01S01818.fsework +++|*         CALLS  TRAGIC, CLEAN, PUSHTEMP, READPA, POPTEMP, PREFETCH,
01832  M01S01819.fsework +++|*                MOVELN.
01833  M01S01820.fsework +++|*
01834  M01S01821.fsework +++|*         USES   TEMP(RESTORED), P<PRU>, PL.
01835  M01S01822.fsework +++|#
01836  M01S01823.fsework +++|
01837  M01S01824.fsework +++|  IF NEWCURL LS 0 OR NEWCURL GR PALAST[0] THEN
01838  M01S01825.fsework +++|    BEGIN
01839  M01S01826.fsework +++|    TRAGIC(" LINE NOT FOUND IN FILE.$");
01840  M01S01827.fsework +++|    END
01841  M01S01828.fsework +++|
01842  M01S01829.fsework +++|  PUSHTEMP;
01843  M01S01830.fsework +++|
01844  M01S01831.fsework +++|  CURRENT = NEWCURL;
01845  M01S01832.fsework +++|
01846  M01S01833.fsework +++|  FOR PL=PALVL WHILE
01847  M01S01834.fsework +++|    NOT(CURRENT GQ PAFIRST[PL] AND CURRENT LQ PALAST[PL]) DO
01848  M01S01835.fsework +++|    BEGIN
01849  M01S01836.fsework +++|    CLEAN;
01850  M01S01837.fsework +++|    PL = PL - 1;
01851  M01S01838.fsework +++|    END
01852  M01S01839.fsework +++|
01853  M01S01840.fsework +++|  P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01854  M01S01841.fsework +++|
01855  M01S01842.fsework +++|  FOR PL = PL WHILE PADIR[PL] DO
01856  M01S01843.fsework +++|    BEGIN
01857  M01S01844.fsework +++|    TEMP = PAFIRST[PL];
01858  M01S01845.fsework +++|
01859  M01S01846.fsework +++|    FOR DISP = 1 WHILE CURRENT GQ TEMP+DIRNL[DISP] DO
01860  M01S01847.fsework +++|      BEGIN
01861  M01S01848.fsework +++|      TEMP = TEMP + DIRNL[DISP];
01862  M01S01849.fsework +++|      DISP = DISP + 1;
01863  M01S01850.fsework +++|      END
01864  M01S01851.fsework +++|
01865  M01S01852.fsework +++|    CONTROL IFGQ PARANOIA,5;
01866  M01S01853.fsework +++|      IF DISP GR PAFINAL[PL] THEN
01867  M01S01854.fsework +++|        BEGIN
01868  M01S01855.fsework +++|        TRAGIC(" DIRECTORY BLOCK POINTER TOO LARGE (2).$");
01869  M01S01856.fsework +++|        END
01870  M01S01857.fsework +++|    CONTROL FI;
01871  M01S01858.fsework +++|    PADISP[PL] = DISP;
01872  M01S01859.fsework +++|
01873  M01S01860.fsework +++|    PL = PL + 1;
01874  M01S01861.fsework +++|    PALVL = PL;
01875  M01S01862.fsework +++|
01876  M01S01863.fsework +++|    PAFIRST[PL] = TEMP;
01877  M01S01864.fsework +++|    PALAST[PL] = TEMP + DIRNL[DISP] - 1;
01878  M01S01865.fsework +++|
01879  M01S01866.fsework +++|    PUSHTEMP;
01880  M01S01867.fsework +++|    TEMP=DIRDA[DISP];
01881  M01S01868.fsework +++|    READPA;
01882  M01S01869.fsework +++|    POPTEMP;
01883  M01S01870.fsework +++|
01884  M01S01871.fsework +++|    P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01885  M01S01872.fsework +++|
01886  M01S01873.fsework +++|    END
01887  M01S01874.fsework +++|
01888  M01S01875.fsework +++|  TEMP = PAFIRST[PL];
01889  M01S01876.fsework +++|
01890  M01S01877.fsework +++|  FOR DISP = 1 WHILE CURRENT NQ TEMP DO
01891  M01S01878.fsework +++|    BEGIN
01892  M01S01879.fsework +++|    # NOTE THIS CODE REQUIRES INTERNAL CHARSET USAGE OF SIGN BIT #
01893  M01S01880.fsework +++|    IF B<0,1>DATWORD[DISP] NQ 0 THEN TEMP = TEMP + 1;
01894  M01S01881.fsework +++|    DISP = DISP + 1;
01895  M01S01882.fsework +++|    END
01896  M01S01883.fsework +++|
01897  M01S01884.fsework +++|  CONTROL IFGQ PARANOIA,5;
01898  M01S01885.fsework +++|    IF DISP GR PAFINAL[PL] THEN
01899  M01S01886.fsework +++|      BEGIN
01900  M01S01887.fsework +++|      TRAGIC(" DIRECTORY BLOCK POINTER TOO LARGE (3).$");
01901  M01S01888.fsework +++|      END
01902  M01S01889.fsework +++|  CONTROL FI;
01903  M01S01890.fsework +++|
01904  M01S01891.fsework +++|  PADISP[PL] = DISP;
01905  M01S01892.fsework +++|
01906  M01S01893.fsework +++|  P<FROM> = LOC(BFPRU[PACACHE[PALVL]]) + PADISP[PALVL];
01907  M01S01894.fsework +++|  CURNW = MOVELN(FROM,MVLNBUF);
01908  M01S01895.fsework +++|
01909  M01S01896.fsework +++|  POPTEMP;
01910  M01S01897.fsework +++|
01911  M01S01898.fsework +++|  IOEND
01912  M01S01899.fsework +++|PAGE
01913  M01S01900.fsework +++|
01914  M01S01901.fsework +++|PROC FWD;
01915  M01S01902.fsework +++|  IOBEGIN(FWD)
01916  M01S01903.fsework +++|#
01917  M01S01904.fsework +++|**        FWD - EXTERNAL INTERFACE FOR FORWARD MOVEMENT.
01918  M01S01905.fsework +++|*
01919  M01S01906.fsework +++|*         FWD INTERFACES TO THE FW ROUTINE TO ADVANCE ONE LINE
01920  M01S01907.fsework +++|*         FROM THE CURRENT POSITION.  FWD ALSO CONTROLS THE BASE
01921  M01S01908.fsework +++|*         ADDRESS FOR MVLNBUF AND ACCUMULATES STATISTICS.
01922  M01S01909.fsework +++|*
01923  M01S01910.fsework +++|*         ENTRY  P<LINEBUF> - WHERE TO PUT TEXT OR ZERO FOR INVISIBLE
01924  M01S01911.fsework +++|*                    POSITIONING FUNCTION.
01925  M01S01912.fsework +++|*                CURRENT - CURRENT LINE.
01926  M01S01913.fsework +++|*
01927  M01S01914.fsework +++|*         EXIT   CURRENT - INCREMENTED.
01928  M01S01915.fsework +++|*                LINEBUF - TEXT MOVE HERE IF BASE ADDRESS NONZERO.
01929  M01S01916.fsework +++|*
01930  M01S01917.fsework +++|*         CALLS  FW.
01931  M01S01918.fsework +++|*
01932  M01S01919.fsework +++|*         USES   P<MVLNBUF>.
01933  M01S01920.fsework +++|#
01934  M01S01921.fsework +++|
01935  M01S01922.fsework +++|  CONTROL IFEQ MULTI,1;
01936  M01S01923.fsework +++|    WIOSTAT(0);               # ACCUMULATE LINE ACCESES #
01937  M01S01924.fsework +++|  CONTROL FI;
01938  M01S01925.fsework +++|
01939  M01S01926.fsework +++|  P<MVLNBUF>=LOC(LINEBUF);
01940  M01S01927.fsework +++|  FW;
01941  M01S01928.fsework +++|  P<MVLNBUF>=0;
01942  M01S01929.fsework +++|  IOEND
01943  M01S01930.fsework +++|
01944  M01S01931.fsework +++|PROC BAK;
01945  M01S01932.fsework +++|  IOBEGIN(BAK)
01946  M01S01933.fsework +++|#
01947  M01S01934.fsework +++|**        FWD - EXTERNAL INTERFACE FOR BACKWARD MOVEMENT.
01948  M01S01935.fsework +++|*
01949  M01S01936.fsework +++|*         BAK INTERFACES TO THE BK ROUTINE TO REGRESS ONE LINE
01950  M01S01937.fsework +++|*         FROM THE CURRENT POSITION.  BAK ALSO CONTROLS THE BASE
01951  M01S01938.fsework +++|*         ADDRESS FOR MVLNBUF AND ACCUMULATES STATISTICS.
01952  M01S01939.fsework +++|*
01953  M01S01940.fsework +++|*         ENTRY  P<LINEBUF> - WHERE TO PUT TEXT OR ZERO FOR INVISIBLE
01954  M01S01941.fsework +++|*                    POSITIONING FUNCTION.
01955  M01S01942.fsework +++|*                CURRENT - CURRENT LINE.
01956  M01S01943.fsework +++|*
01957  M01S01944.fsework +++|*         EXIT   CURRENT - DECREMENTED.
01958  M01S01945.fsework +++|*                LINEBUF - TEXT MOVE HERE IF BASE ADDRESS NONZERO.
01959  M01S01946.fsework +++|*
01960  M01S01947.fsework +++|*         CALLS  BK.
01961  M01S01948.fsework +++|*
01962  M01S01949.fsework +++|*         USES   P<MVLNBUF>.
01963  M01S01950.fsework +++|#
01964  M01S01951.fsework +++|
01965  M01S01952.fsework +++|  CONTROL IFEQ MULTI,1;
01966  M01S01953.fsework +++|    WIOSTAT(0);               # ACCUMULATE LINE ACCESES #
01967  M01S01954.fsework +++|  CONTROL FI;
01968  M01S01955.fsework +++|
01969  M01S01956.fsework +++|  P<MVLNBUF>=LOC(LINEBUF);
01970  M01S01957.fsework +++|  BK;
01971  M01S01958.fsework +++|  P<MVLNBUF>=0;
01972  M01S01959.fsework +++|  IOEND
01973  M01S01960.fsework +++|
01974  M01S01961.fsework +++|PROC POS;
01975  M01S01962.fsework +++|  IOBEGIN(POS)
01976  M01S01963.fsework +++|#
01977  M01S01964.fsework +++|**        POS - EXTERNAL INTERFACE FOR RANDOM MOVEMENT.
01978  M01S01965.fsework +++|*
01979  M01S01966.fsework +++|*         POS INTERFACES TO THE POSR ROUTINE TO GO TO ANY LINE
01980  M01S01967.fsework +++|*         FROM THE CURRENT POSITION.  POS ALSO CONTROLS THE BASE
01981  M01S01968.fsework +++|*         ADDRESS FOR MVLNBUF AND ACCUMULATES STATISTICS.
01982  M01S01969.fsework +++|*
01983  M01S01970.fsework +++|*         ENTRY  P<LINEBUF> - WHERE TO PUT TEXT OR ZERO FOR INVISIBLE
01984  M01S01971.fsework +++|*                    POSITIONING FUNCTION.
01985  M01S01972.fsework +++|*                NEWCURL - DESIRED LINE.
01986  M01S01973.fsework +++|*                CURRENT - PREVIOUS CURRENT LINE.
01987  M01S01974.fsework +++|*
01988  M01S01975.fsework +++|*         EXIT   CURRENT - MATCHES NEWCURL.
01989  M01S01976.fsework +++|*                LINEBUF - TEXT MOVE HERE IF BASE ADDRESS NONZERO.
01990  M01S01977.fsework +++|*
01991  M01S01978.fsework +++|*         CALLS  POSR.
01992  M01S01979.fsework +++|*
01993  M01S01980.fsework +++|*         USES   P<MVLNBUF>.
01994  M01S01981.fsework +++|#
01995  M01S01982.fsework +++|
01996  M01S01983.fsework +++|  CONTROL IFEQ MULTI,1;
01997  M01S01984.fsework +++|    WIOSTAT(0);               # ACCUMULATE LINE ACCESES #
01998  M01S01985.fsework +++|  CONTROL FI;
01999  M01S01986.fsework +++|
02000  M01S01987.fsework +++|  P<MVLNBUF>=LOC(LINEBUF);
02001  M01S01988.fsework +++|  IF NEWCURL EQ CURRENT-1 THEN BK;
02002  M01S01989.fsework +++|  ELSE IF NEWCURL EQ CURRENT+1 THEN FW;
02003  M01S01990.fsework +++|  ELSE IF NEWCURL NQ CURRENT THEN POSR;
02004  M01S01991.fsework +++|  ELSE                       # JUST READOUT SAME LINE      #
02005  M01S01992.fsework +++|    BEGIN
02006  M01S01993.fsework +++|    P<FROM> = LOC(BFPRU[PACACHE[PALVL]]) + PADISP[PALVL];
02007  M01S01994.fsework +++|    DUMB = MOVELN(FROM,LINEBUF);
02008  M01S01995.fsework +++|    END
02009  M01S01996.fsework +++|  P<MVLNBUF>=0;
02010  M01S01997.fsework +++|  IOEND                       # OF POS  #
02011  M01S01998.fsework +++|PAGE
02012  M01S01999.fsework +++|  PROC SPLITTOP;
02013  M01S02000.fsework +++|    IOBEGIN(SPLITTOP)
02014  M01S02001.fsework +++|#
02015  M01S02002.fsework +++|**        SPLITTOP - SPLIT ROOT SECTOR TO MAKE NEW LEVEL.
02016  M01S02003.fsework +++|*
02017  M01S02004.fsework +++|*         SPLITTOP IS USED WHEN THE ROOT SECTOR OVERFLOWS.  THE ROOT
02018  M01S02005.fsework +++|*         SECTOR MUST ALWAYS EXIST AT DISK ADDRESS 1, THUS THE METHOD
02019  M01S02006.fsework +++|*         USED TO SPLIT IT IS DIFFERENT FROM THAT USED FOR ANY OTHER
02020  M01S02007.fsework +++|*         SECTOR.  THE EXISTING CONTENTS OF THE ROOT SECTOR ARE
02021  M01S02008.fsework +++|*         PLACED IN TWO NEW SECTORS, AND THE ROOT SECTOR IS
02022  M01S02009.fsework +++|*         RECONSTRUCTED AS A DIRECTORY POINTING TO THESE TWO NEW
02023  M01S02010.fsework +++|*         SECTORS.  THUS THE OVERALL TREE STRUCTURE IS DEEPENED BY
02024  M01S02011.fsework +++|*         ONE LEVEL.
02025  M01S02012.fsework +++|*
02026  M01S02013.fsework +++|*         HOWEVER, SPLITTOP DOES NOT PROVIDE ALL THIS ALGORITHM.
02027  M01S02014.fsework +++|*         SPLITTOP DOES PRODUCE A NEW TREE LEVEL WITH A REBUILT ROOT,
02028  M01S02015.fsework +++|*         BUT STOPS SHORT OF FITTING THE OVERFLOWED TEXT INTO A PAIR
02029  M01S02016.fsework +++|*         OF SECTORS.  SPLITTOP PLACES THE PRE-OVERFLOW SECTOR
02030  M01S02017.fsework +++|*         CONTENT INTO A SINGLE SECTOR AT THE NEW INTERMEDIATE TREE
02031  M01S02018.fsework +++|*         LEVEL, AND ESTABLISHES THIS AS THE CURRENT TREE PATH LEVEL.
02032  M01S02019.fsework +++|*         THE CALLER IS THEN RESPONSIBLE TO USE ONE OF THE OTHER
02033  M01S02020.fsework +++|*         SECTOR SPLITTING ALGORITHMS TO GET THE TEXT ACTUALLY SPLIT
02034  M01S02021.fsework +++|*         INTO TWO SECTORS.  THESE OTHER ALGORITHMS WILL UPDATE THE
02035  M01S02022.fsework +++|*         NEW ROOT TO POINT TO THE OVERFLOW SECTOR.
02036  M01S02023.fsework +++|*
02037  M01S02024.fsework +++|*         ENTRY  PL - MUST EQUAL ZERO.
02038  M01S02025.fsework +++|*                PADEPTH[0] - INDICATE HIGH WATER MARK OF TREE DEPTH.
02039  M01S02026.fsework +++|*                PALVL - CURRENT DEEPEST TREE LEVEL ON PATH.
02040  M01S02027.fsework +++|*                ALL PATH CONTROLS - SETUP.
02041  M01S02028.fsework +++|*                CACHE - AT LEAST ONE FRAME MUST BE AVAILABLE TO
02042  M01S02029.fsework +++|*                    BE CLAIMED.
02043  M01S02030.fsework +++|*
02044  M01S02031.fsework +++|*         EXIT   PL - ONE.
02045  M01S02032.fsework +++|*                PALVL - INCREMENTED.
02046  M01S02033.fsework +++|*                PADEPTH[0] - INCREMENETED.
02047  M01S02034.fsework +++|*                ALL PATH CONTROLS - SHUFFLED TO DEEPER LEVELS.
02048  M01S02035.fsework +++|*                CACHE - ONE FRAME ALLOCATED FOR NEW LEVEL 0.
02049  M01S02036.fsework +++|*                ROOT SECTOR CACHE FRAME - BUILT AS DIRECTORY WITH
02050  M01S02037.fsework +++|*                    ONE ENTRY POINTING TO INTERMEDIATE SECTOR.
02051  M01S02038.fsework +++|*                PATH LEVEL 1 - BUILT AS INTERMEDIATE TREE LEVEL
02052  M01S02039.fsework +++|*                    USING SAME CACHE FRAME AS FORMER ROOT LEVEL,
02053  M01S02040.fsework +++|*                    BUT ASSIGNED A NEWLY ALLOCATED DISK ADDRESS.
02054  M01S02041.fsework +++|*                    MARKED AS ALTERED SO NEW DISK ADDRESS CAN BE
02055  M01S02042.fsework +++|*                    EVENTUALLY WRITTEN TO DISK.
02056  M01S02043.fsework +++|*
02057  M01S02044.fsework +++|*         CALLS  TRAGIC, ALLOC, ALLOCCACHE, MOVEWD.
02058  M01S02045.fsework +++|*
02059  M01S02046.fsework +++|*         USES   P<PRU>.
02060  M01S02047.fsework +++|#
02061  M01S02048.fsework +++|    IF PADEPTH[0] GQ MAXDEPTH THEN TRAGIC(" FILE TOO LARGE.$");
02062  M01S02049.fsework +++|    PADEPTH[0] = PADEPTH[0] + 1;
02063  M01S02050.fsework +++|
02064  M01S02051.fsework +++|    FOR PL =  PALVL STEP -1 UNTIL 0 DO # SLIDE PATH UP     #
02065  M01S02052.fsework +++|      BEGIN
02066  M01S02053.fsework +++|      PAFIRST[PL+1] = PAFIRST[PL];
02067  M01S02054.fsework +++|      PALAST[PL+1] = PALAST[PL];
02068  M01S02055.fsework +++|      PADISP[PL+1] = PADISP[PL];
02069  M01S02056.fsework +++|      PAHEAD[PL+1] = PAHEAD[PL];
02070  M01S02057.fsework +++|      PACACHE[PL+1] = PACACHE[PL];
02071  M01S02058.fsework +++|      END
02072  M01S02059.fsework +++|
02073  M01S02060.fsework +++|    PL = 1;                  # STEP UP PL & PALVL          #
02074  M01S02061.fsework +++|    PALVL = PALVL + 1;
02075  M01S02062.fsework +++|
02076  M01S02063.fsework +++|    PATOP[1] = FALSE;        # FIX UP OLD TOP    #
02077  M01S02064.fsework +++|    PADIRTY[1] = FALSE;
02078  M01S02065.fsework +++|    PADA[1] = 0;
02079  M01S02066.fsework +++|    ALLOC;
02080  M01S02067.fsework +++|    ALLOCCACHE;
02081  M01S02068.fsework +++|    PADIRTY[1] = TRUE;
02082  M01S02069.fsework +++|    P<FROM> = LOC(BFPRU[PACACHE[0]]) + 1;
02083  M01S02070.fsework +++|    P<TOO> = LOC(BFPRU[PACACHE[1]]) + 1;
02084  M01S02071.fsework +++|    MOVEWD(PAFINAL[0],FROM,TOO);
02085  M01S02072.fsework +++|
02086  M01S02073.fsework +++|    PADATA[0] = FALSE;       # BUILD NEW TOP     #
02087  M01S02074.fsework +++|    PADIR[0] = TRUE;
02088  M01S02075.fsework +++|    PADIRTY[0] = TRUE;
02089  M01S02076.fsework +++|    PAFINAL[0] = 1;
02090  M01S02077.fsework +++|    P<PRU> = LOC(BFPRU[PACACHE[0]]);
02091  M01S02078.fsework +++|    DIRDA[1] = PADA[1];
02092  M01S02079.fsework +++|    DIRNL[1] = PALAST[1] - PAFIRST[1] + 1;
02093  M01S02080.fsework +++|
02094  M01S02081.fsework +++|    PADISP[0] = 1;
02095  M01S02082.fsework +++|    IOEND
02096  M01S02083.fsework +++|PAGE
02097  M01S02084.fsework +++|  PROC SPLITAPEND;
02098  M01S02085.fsework +++|    IOBEGIN(SPLITAPEND)
02099  M01S02086.fsework +++|#
02100  M01S02087.fsework +++|**        SPLITAPEND - SPLIT SECTOR JUST AFTER CURRENT CONTENT.
02101  M01S02088.fsework +++|*
02102  M01S02089.fsework +++|*         SPLITAPEND IS USED TO OVERFLOW ANY NON-ROOT SECTOR UNDER
02103  M01S02090.fsework +++|*         THE CONDITION THAT THE OVERFLOW TEXT BELONGS JUST AFTER ALL
02104  M01S02091.fsework +++|*         OF THE TEXT ALREADY CONTAINED IN THE SECTOR.  THUS, THE
02105  M01S02092.fsework +++|*         SECTOR REMAINS JUST AS IT IS, AND A NEW SECTOR IS
02106  M01S02093.fsework +++|*         CONSTRUCTED WHICH CONTAINS PRECISELY THE OVERFLOW TEXT.
02107  M01S02094.fsework +++|*         SINCE NO EXISTING TEXT LEAVES THE SECTOR, THERE IS NO NEED
02108  M01S02095.fsework +++|*         TO DISCARD IT AND BUILD TWO COMPLETELY NEW SECTORS.  THUS,
02109  M01S02096.fsework +++|*         SPLITAPEND IS MORE EFFICIENT THAN SPLITBEFORE OR
02110  M01S02097.fsework +++|*         SPLITAFTER.
02111  M01S02098.fsework +++|*
02112  M01S02099.fsework +++|*         THE NEWLY BUILT SECTOR BECOMES THE CURRENT SECTOR FOR THIS
02113  M01S02100.fsework +++|*         LEVEL OF THE TREE.  THE ORIGINAL SECTOR IS RELEASED FROM
02114  M01S02101.fsework +++|*         OWNERSHIP.
02115  M01S02102.fsework +++|*
02116  M01S02103.fsework +++|*         SPLITAPEND REQUIRES THAT AT LEAST ONE CACHE FRAME IS
02117  M01S02104.fsework +++|*         AVAILABLE FOR ALLOCATION.
Proceed to Part 1
cdc/nos2.source/opl.opl871/deck/fsework.txt ยท Last modified: by 127.0.0.1