FSECMDS 
PROC FSECMDS; 
  BEGIN 
  
  
# 
***       FSECMDS -- SUPPLEMENTARY COMMANDS.
* 
*         COPYRIGHT CONTROL DATA SYSTEMS INC.  1992.
* 
*         FSECMDS CONTAINS CODE WHICH NORMALLY WOULD BE PART OF THE 
*         LARGE "PROCESS" CASE STATEMENT, BUT WHICH WE HAVE MOVED 
*         OUT TO CONSERVE FIELD LENGTH MOST OF THE TIME.  CODE IN 
*         FSECMDS IS A CANDIDATE FOR ANY OVERLAY STRUCTURING THAT MAY 
*         BE PROVIDED IN THE FUTURE.  CODE IN FSECMDS MUST BE STRICTLY
*         FOR THE SINGLE-USER VERSION ONLY.  REENTRANT PROGRAMMING
*         IS NOT USED IN THIS MODULE. 
# 
  
  DEF LISTCON #0#;
  
CONTROL EJECT;                         # UNIVERSAL DECLARES          #
  
*IFCALL SINGLE,COMFSGL
*IFCALL ONLY,COMFONL
*IFCALL MULTI,COMFMLT 
*CALL COMFFSE 
  
                             # COMMON, DATA      #
  
  
*CALL COMFDS1 
*CALL COMFVD2 
*CALL COMFDS2 
  
  
                             # COMMAND/SYNTAX TABLES       #
  
  
*CALL COMFTAB 
  
  
                             # EXTERNALS         #
  
  
XDEF
  BEGIN 
*CALL COMFXCM 
  END 
  
  
XREF
  BEGIN 
*CALL COMFXFL 
*CALL COMFXSC 
*CALL COMFXED 
*CALL COMFXSB 
*CALL COMFXTI 
*CALL COMFXFO 
*CALL COMFXWK 
  END 
  
XREF                         # SYMPLIB SUPPORT   #
  BEGIN 
  PROC REWIND;
  PROC WRITER;
  PROC READ;
  PROC RETERN;
  PROC RECALL;
  PROC PF;
  PROC WRITEC;
  PROC READC; 
  PROC SKIPEI;
  PROC BKSP;
  END 
  
XREF                         # FSELIB  #
  BEGIN 
  FUNC FIXCTL B;
  FUNC LENGTH;
  PROC FLDLEN;
  END 
  
XREF                         # VIRTERM #
  BEGIN 
  PROC VDTCHR;
  END 
  
XREF                         # BUFFER MAPPING    #
  BEGIN 
  ARRAY WORKBUF;; 
  ARRAY BUILDBF;; 
  ITEM MAXADDR; 
  END 
PAGE                         # DATA LOCAL TO OVERLAY       #
  
  
ITEM RESULT,NWORDS, TMP1, INDEX, KILLUPLOW B, ZERO=0; 
ITEM SAVBLANKS, SAVLINENO;
  
ARRAY STATUSMSGS [0:3] P(2);
  BEGIN 
  ITEM YESORNO    C(0,0,7)=["  NO   ", "  YES  ", " ", " "];
  ITEM CHARTYPE   C(1,0,7)=["DISPLAY", "DISPLAY", " ASCII ",
                            " 8/12  "]; 
  END 
PAGE                         # USEFUL LITTLE ROUTINES      #
  
  
PROC XFRCMOUT;
  BEGIN 
# 
**        XFRCMOUT - OUTWARD LINE TRANSFER FOR COPY/MOVE. 
* 
*         ENTRY  LIN - INTERNAL LINE IMAGE. 
*                FORCEFIELD, CHARRANGE - MODE SETTINGS. 
*                CHRPTR1, CHRPTR2, FIRSTRANGE, LASTRANGE - DITTO. 
*                MOVEFET - FET FOR SCRATCH FILE.
* 
*         EXIT   IMAGE WRITTEN TO SCRATCH IN 6/12 CHARSET.
* 
*         MACROS SETCHAR. 
* 
*         CALLS  LSHIFT, CONVOUT, POSZ, WRITEC. 
# 
  IF FORCEFIELD THEN
    BEGIN 
    SETCHAR(LINE,CHRPTR2+1,CENDLINE); 
    LSHIFT(LIN,CHRPTR1,CHRPTR1);
    CONVOUT(LIN,4); 
    POSZ(CURRENT);         # RE-FRESH LINE BUFFER        #
    END 
  ELSE IF CHARRANGE THEN
    BEGIN                   # TRUNCATE LAST, SHIFT FIRST  # 
    IF LASTRANGE THEN SETCHAR(LINE,CHRPTR2+1,CENDLINE); 
    IF FIRSTRANGE THEN LSHIFT(LIN,CHRPTR1,CHRPTR1); 
    CONVOUT(LIN,4); 
    POSZ(CURRENT);         # RE-FRESH LINE BUFFER        #
    END 
  ELSE CONVOUT(LIN,4);
  WRITEC(MOVEFET,TMPLIN); 
  END                       # OF XFRCMOUT       # 
  
  
PROC XFRCMIN; 
  BEGIN 
# 
**        XFRCMIN - INWARD TRANSFER FOR COPY/MOVE.
* 
*         ENTRY  MOVEFET - SCRATCH FILE FET.
* 
*         EXIT   LIN - LINE IMAGE, INTERNAL CHARSET FROM 6/12.
* 
*         CALLS  READC, CONVIN. 
# 
  ITEM TMP1;
  READC(MOVEFET,TMPLIN,BUFWID2P1,TMP1); 
  IF TMP1 NQ 0 THEN FATAL(" TRANSFER TO THE BUFFER IS INCOMPLETE.$"); 
  CONVIN(LIN,2);
  END                       # OF XFRCMIN        # 
  
  
PROC TTCHAR(CHAR,SYMBOL); 
  BEGIN 
# 
**        TTCHAR - OUTPUT INTERNAL CHARACTER TO TERMINAL. 
* 
*         TTCHAR OUTPUTS A SINGLE CHARACTER, USING SYMBOLIC KEYWORDS
*         FOR (BLANK) AND (NONE) IF REQUESTED.  NOTE THAT SINCE THE 
*         TERMINAL IS DRIVEN IN 6/12 WHILE IN LINE MODE SPECIAL 
*         TRANSLATION MAY BE NEEDED.
* 
*         ENTRY  CHAR       = THE CHARACTER (INTERNAL CSET).
*                SYMBOL     = USE SYMBOLIC NOTATION (TRUE/FALSE). 
* 
*         CALLS  TTST, TTSTR, VDTCHR. 
# 
  ITEM CHAR       I;                 # CHARACTER, AS INTEGER #
  ITEM SYMBOL     B;                 # SYMBOLIC FLAG (TRUE/FALSE) # 
  
  ITEM TMP1       I;                 # TEMPORARY #
  
  IF CHAR EQ CNOTHING THEN
    BEGIN                            # IF NO CHARACTER #
    IF SYMBOL THEN TTSTR("(NONE)$"); # IF SYMBOLIC REQUESTED #
    END 
  ELSE
    BEGIN                            # IF CHARACTER OR BLANK #
    IF SYMBOL AND CHAR EQ CBLANK THEN TTSTR("(BLANK)$"); # IF SYMBOL #
    ELSE
      BEGIN                          # IF CHARACTER OR NORMAL BLANK # 
      IF SCREENMODE THEN
        BEGIN                        # IF SCREEN MODE # 
        TMP1 = XLTINTXP[CHAR];       # TRANSLATE, OUTPUT #
        VDTCHR(TMP1); 
        END 
      ELSE
        BEGIN                        # LINE MODE #
        TMP1=XLTINTDSP[CHAR];        # TRANSLATE TO DISPLAY # 
        IF CHAR EQ CATSIGN OR CHAR EQ CUPARROW OR CHAR EQ CGRAVE THEN 
          BEGIN                      # IF 74XX TRANSLATION NEEDED # 
          TTCHR(O"74");              # OUTPUT ESCAPE CHARACTER #
          TMP1 = O"01";              # ASSUME AT SIGN # 
          IF CHAR EQ CUPARROW THEN TMP1 = O"02";
          IF CHAR EQ CGRAVE THEN TMP1 = O"07";
          END 
        ELSE
          BEGIN                      # NOT 74XX # 
          IF CHAR EQ CLEFTCURL OR CHAR EQ CVERTICAL OR
            CHAR EQ CRITECURL OR  CHAR EQ CTILDE THEN 
            BEGIN                    # IF 76XX TRANSLATION NEEDED # 
            TTCHR(O"76");            # OUTPUT ESCAPE CHARACTER #
            TMP1 = O"33";            # ASSUME LEFT BRACE #
            IF CHAR EQ CVERTICAL THEN TMP1 = O"34"; 
            IF CHAR EQ CRITECURL THEN TMP1 = O"35"; 
            IF CHAR EQ CTILDE THEN TMP1 = O"36";
            END 
          END 
        TTCHR(TMP1);                 # OUTPUT (REST OF) CHARACTER # 
        END 
      END 
    END 
  END  # TTCHAR # 
  
  
PROC UNDODECODE(POS,NUM); 
  BEGIN 
# 
**        UNDODECODE - DECODE AN AUDIT TRAIL DESCRIPTOR.
* 
*         ENTRY  POS - CHARACTER POSITION OF FIELD. 
*                LIN - CONTAINS DESCRIPTOR. 
* 
*         EXIT   NUM - VALUE DECODED FROM FIELD.
* 
*         MACROS GETCHAR. 
# 
  ITEM POS, NUM, TMP1, TMP2;
  NUM=0;
  TMP2=POS; 
  GETCHAR(LINE,TMP2,TMP1);
  WHYLE TMP1 GQ CDIGIT0 AND TMP1 LQ CDIGIT9 DO
    BEGIN 
    NUM=NUM*10+TMP1-CDIGIT0;
    TMP2=TMP2+1;
    GETCHAR(LINE,TMP2,TMP1);
    END 
  END                         # OF UNDODECODE     # 
  
  
PROC UNDOPOS(OFFSET); 
  BEGIN 
# 
**        UNDOPOS - POSITION TO AUDITED DATA LINE.
* 
*         ENTRY  OFFSET - DIFFERENCE BETWEEN LINNUM3 AND TARGET.
*                LINNUM1 - FILE BRACKET NUMBER. 
*                LINNUM3 - LINE ORDINAL IN FILE BRACKET.
* 
*         EXIT   CURFILE - EQUALS LINNUM1.
*                CURRENT - ABSOLUTE LINE ADDRESS. 
*                LIN - THE TEXT OF THE LINE.
*                CURF(CURFILE) - EQUAL TO CURRENT.
*                P<LINEBUF> - POINTS TO LIN.
* 
*         CALLS  POSZ.
# 
  ITEM OFFSET;
  P<LINEBUF>=0;              # POSITION INVISIBLY          #
  POSZ(TOPF(LINNUM1)+LINNUM3+OFFSET); 
  P<LINEBUF>=LOC(LIN);       # RESTORE #
  CURFILE=LINNUM1;           # REMEMBER WHERE WE ARE       #
  CURF(CURFILE)=CURRENT;
  END                         # OF UNDOPOS        # 
  
  
PROC UNDOOPEN(BRACKET,DIRECTORY); 
  BEGIN 
# 
**        UNDOOPEN - GET FILE IMAGE INTO ACTIVE BRACKET.
* 
*         ENTRY  BRACKET - DESIRED BRACKET NUMBER.
*                DIRECTORY - WORKFILE ADDRESS OF FILE DIRECTORY LINE. 
* 
*         EXIT   FILE IS OPENED IN BRACKET. 
*                THIS AFFECTS TOPF(), BOTF(), ETC.
* 
*         CALLS  PUSH, POSZ, SCANFDL, OPENFILE, POP.
* 
*         USES   READNAM, FILNUM, CHARPARM, GETPARM.
# 
  ITEM BRACKET, DIRECTORY;
  IF DIRECTORY EQ 0 OR DIRECTORY EQ FDLF(BRACKET) THEN RETURN;
  PUSH; 
  POSZ(DIRECTORY);
  SCANFDL(READNAM); 
  FILNUM=BRACKET; 
  CHARPARM=0; 
  GETPARM=0;
  OPENFILE; 
  POP;
  END                         # OF UNDOOPEN       # 
  
  
PROC DOFILL;
  BEGIN 
# 
**        DOFILL - MAIN ALGORITHM FOR PARAGRAPH FORMATTING. 
* 
*         DOFILL IS THE MAIN PROCESSING ALGORITHM FOR THE WORD- 
*         PROCESSING COMMAND, ".FILL".  THE UNIVERSAL SYNTAX
*         SCANNER MUST BE CALLED BEFORE BEFORE DOFILL.  DOFILL
*         ACCEPTS EXPLICIT RANGE BOUNDARIES, OR COMPUTE AN IMPLICIT 
*         RANGE AS THE PARAGRAPH SURROUNDING ONE TARGET LINE. 
*         MARGINS MAY BE COLUMN 1 THRU THE WIDTH SETTING, OR A
*         TAB FIELD.
* 
*         ENTRY  SCANNER HAS BEEN CALLED. 
*                LINPTR1 - FIRST LINE OF RANGE IF RANGE EXPLICIT. 
*                          ANY ADDRESS WITHIN PARAGRAPH FOR IMPLICIT. 
*                LINPTR2 - LAST LINE OF RANGE IF RANGE EXPLICIT.
*                LIMIT - RANGE LENGTH LIMIT IF RANGE EXPLICIT.
*                NONDEFAULT - TELLS RANGE IMPLICIT OR EXPLICIT. 
*                FILLLEFT, FILLRIGHT - DEFAULT MARGIN OBJECTIVES. 
*                FILLFIRST - DEFAULT MARGIN OBJECTIVES. 
*                CURFILE - WHICH FILE BRACKET.
*                NUMBERED[CURFILE] - REQUIRED TO BE FALSE.
*                TOPF(CURFILE), BOTF(CURFILE) - FILE BOUNDS.
*                SCREENMODE - CONTROLS FINAL POSITIONING/PRINTING.
* 
*         EXIT   LINPTR1, LINPTR2, LIMIT - POSSIBLY DESTROYED.
*                CURRENT - FRONT OF RESULTANT RANGE IF SCREEN,
*                    ELSE END OF RESULTANT RANGE. 
*                LIN - TEXT OF CURRENT LINE.
*                BOTF(CURFILE) - POSSIBLY RELOCATED.
* 
*         MACROS GETCHAR, SETCHAR.
* 
*         CALLS  TABFN, MIN, MAX, POSZ, LENGTH, BAKZ, FWDZ, TRIMPAD,
*                REPX, LSHIFT, RSHIFT, DOSPLIT, COPYLIN, DORANGE. 
* 
*         USES   TTYLIN.
# 
  ITEM FILLLOOP;             # USED FOR LOOP TESTING       #
  ITEM LMARGIN, RMARGIN;
  ITEM TMP1, TMP2, TMP3, TMP4, TMP5, TMP6;
  ITEM LEFTRIGHT B; 
  
  # PROCESS A PARAGRAPH OF WORDS OF TEXT CENTERED AROUND  # 
  # THE CURRENT LINE (LINPTR1 INITIALLY).  WE LOOK BACK   # 
  # AND FORWARDS FOR BOUNDARIES, THEN PROCESS THE BLOCK   # 
  # MERGING WORDS ONTO LINES TO MATCH "SET WIDTH".        # 
  
  IF NUMBERED[CURFILE] NQ 0 THEN
    BEGIN 
    ERRJUMP("FILE MUST NOT CONTAIN SEQUENCE NUMBERS$"); 
    END 
  
  LMARGIN=FILLFIRST;
  RMARGIN=FILLRIGHT;
  LEFTRIGHT = FALSE;
  
  IF NONDEFAULT THEN         # USE LINPTR1, LINPTR2        #
    BEGIN 
    REGLINE[RNGTOPREG]=LINPTR1-1; 
    REGLINE[RNGBOTREG]=MIN(LINPTR2+1,LINPTR1+LIMIT);
    END 
  ELSE                       # SEARCH FOR PARAGRAPH        #
    BEGIN 
    POSZ(LINPTR1);
    IF NOTEXT THEN RETURN;           # NO TEXT ON THIS LINE # 
    WHYLE CURRENT GR TOPF(CURFILE) AND NOT NOTEXT DO
      BEGIN                   # LOOK BACK FOR BLANK         # 
      BAKZ; 
      IF USRBRK NQ 0 THEN RETURN; 
      END 
    REGLINE[RNGTOPREG]=CURRENT; 
    POSZ(LINPTR1);
    WHYLE CURRENT LS BOTF(CURFILE) AND NOT NOTEXT DO
      BEGIN                   # LOOK FORWARDS FOR BLANK     # 
      FWDZ; 
      IF USRBRK NQ 0 THEN RETURN; 
      END 
    REGLINE[RNGBOTREG]=CURRENT; 
    END 
  
  POSZ(REGLINE[RNGTOPREG]+1); 
  FOR FILLLOOP=FILLLOOP WHILE CURRENT LS REGLINE[RNGBOTREG] 
    AND CURRENT GR REGLINE[RNGTOPREG] AND USRBRK EQ 0 DO
    BEGIN 
  
    IF CURRENT GR REGLINE[RNGTOPREG]+1 THEN 
      BEGIN                          # LOOK BACK FOR START PARA # 
      BAKZ; 
      IF NOTEXT THEN LMARGIN=FILLFIRST; 
      ELSE LMARGIN=FILLLEFT;
      FWDZ; 
      END 
  
    IF LENGTH(LIN) GR EDITFIELD THEN   # KILL PROTECTED    #
      BEGIN 
      SETCHAR(LINE,EDITFIELD,CENDLINE); 
      TRIMPAD;
      REPX; 
      END 
  
    IF LENGTH(LIN) GR 0 THEN           # NORMALIZE SPACING #
      BEGIN 
      TMP1=0;                # CURSOR  #
      TMP2=LMARGIN;          # NUMBER OF EXPECTED BLANKS   #
      TMP3=0;                # FLAG FOR CHANGES MADE       #
      WHYLE TMP1 LS LENGTH(LIN) DO
        BEGIN 
        # FIRST CHECK AND COMPRESS BLANKS BEFORE WORD # 
        TMP4=TMP1;
        GETCHAR(LINE,TMP4,TMP5);
        WHYLE TMP5 EQ CBLANK DO        # SPAN BLANKS BEFORE WORD     #
          BEGIN 
          TMP4=TMP4+1;
          GETCHAR(LINE,TMP4,TMP5);
          END 
        TMP4=TMP4-TMP1;      # NUMBER OF BLANKS  #
        IF TMP4 GR TMP2 THEN          # NEED LESS SPACING # 
          BEGIN 
          LSHIFT(LIN,TMP1+TMP4-TMP2,TMP4-TMP2); 
          TMP3=1;            # FLAG CHANGE       #
          END 
        IF TMP4 LS TMP2 THEN           # NEED MORE SPACING #
          BEGIN 
          RSHIFT(LIN,TMP1,TMP2-TMP4); 
          FOR TMP3=1 STEP 1 UNTIL TMP2-TMP4 
            DO SETCHAR(LINE,TMP1+TMP3-1,CBLANK);
          TMP3=1; 
          END 
        # SECOND SCAN ACROSS WORD TO SET NEW BLANK EXPECTATION       #
        TMP1=TMP1+TMP2;      # POINT TO WORD     #
        GETCHAR(LINE,TMP1,TMP5);
        WHYLE TMP5 NQ CBLANK AND TMP5 NQ CENDLINE DO
          BEGIN 
          TMP4=TMP5;         # NEED TO KNOW LAST CHARACTER OF WORD   #
          TMP1=TMP1+1;
          GETCHAR(LINE,TMP1,TMP5);
          END 
        IF TMP4 EQ CPERIOD OR TMP4 EQ CEXCLAM OR TMP4 EQ CQUESTION
          OR TMP4 EQ XLTDSPINT[CCOLON] THEN TMP2=2; 
        ELSE TMP2=1;
        END 
      IF TMP3 NQ 0 THEN 
        BEGIN 
        TRIMPAD;
        REPX; 
        END 
      END 
  
    IF LENGTH(LIN) EQ RMARGIN OR NOTEXT THEN
      BEGIN                   # SKIP PERFECT OR BLANK LINE  # 
      FWDZ; 
      TEST FILLLOOP;
      END 
  
    IF LENGTH(LIN) GR RMARGIN THEN
      BEGIN                   # SPLIT THIS LINE TO SHORTEN  # 
      TMP1=RMARGIN; 
      GETCHAR(LINE,TMP1,TMP2);
      WHYLE TMP2 NQ CBLANK AND TMP1 GR 0 DO 
        BEGIN                 # LOOK BACK FOR BLANK         # 
        TMP1=TMP1-1;
        GETCHAR(LINE,TMP1,TMP2);
        END 
      IF TMP1 GR LMARGIN THEN    # SPLIT AND WORK ON SECOND HALF     #
        BEGIN 
        CHRPTR3=TMP1+1; 
        DOSPLIT(1); 
        IF RIGHTJUST[0] THEN GOTO JUSTIFY; # IF RIGHT JUSTIFY NEEDED #
        END 
      ELSE FWDZ;             # ALL ONE WORD - JUST MOVE ON           #
      TEST FILLLOOP;
      END 
  
    IF LENGTH(LIN) LS RMARGIN AND CURRENT EQ REGLINE[RNGBOTREG]-1 THEN
      BEGIN                   # CANNOT ENLARGE LAST SO SKIP # 
      FWDZ; 
      TEST FILLLOOP;         # THIS ACTUALLY TERMINATES LOOP         #
      END 
  
    IF LENGTH(LIN) LS RMARGIN AND CURRENT LS REGLINE[RNGBOTREG]-1 THEN
      BEGIN                   # TRY TO ADD WORDS FROM NEXT  # 
      COPYLIN(LIN,TTYLIN);   # TTYLIN = CURRENT LINE       #
      FWDZ;                  # READ UP NEXT LINE #
      IF NOTEXT THEN TEST FILLLOOP;  # NEXT PARAGRAPH # 
      TMP1=0; 
      GETCHAR(LINE,0,TMP2); 
      WHYLE TMP2 EQ CBLANK DO 
        BEGIN                 # SPAN LEADING BLANKS         # 
        TMP1=TMP1+1;
        GETCHAR(LINE,TMP1,TMP2);
        END 
      TMP3=TMP1;             # KEEP START OF WORD          #
      WHYLE TMP2 NQ CBLANK AND TMP2 NQ CENDLINE DO
        BEGIN                 # SPAN WORD         # 
        TMP1=TMP1+1;
        GETCHAR(LINE,TMP1,TMP2);
        END 
      TMP4=LENGTH(TTYLIN);
      GETCHAR(TTYLINE,TMP4-1,TMP5);  # DETERMINE SPACING #
      IF TMP5 EQ CPERIOD OR TMP5 EQ CEXCLAM OR TMP5 EQ CQUESTION
        OR TMP5 EQ XLTDSPINT[CCOLON] THEN TMP5=2; 
      ELSE TMP5=1;
      # ADD WORD IF ROOM FOR OLD LINE, BLANKS, AND WORD # 
      IF (LENGTH(TTYLIN)) + (TMP5) + (TMP1-TMP3-1) LQ RMARGIN THEN
        BEGIN                 # CAN ADD ONE WORD  # 
        FOR TMP2=1 STEP 1 UNTIL TMP5 DO          # ADD 1 OR 2 BLANK  #
          BEGIN 
          SETCHAR(TTYLINE,TMP4,CBLANK); 
          TMP4=TMP4+1;
          END 
        FOR TMP2=TMP3 STEP 1 UNTIL TMP1-1 DO     # ADD ONE WORD      #
          BEGIN 
          GETCHAR(LINE,TMP2,TMP5);
          SETCHAR(TTYLINE,TMP4,TMP5); 
          TMP4=TMP4+1;
          END 
        SETCHAR(TTYLINE,TMP4,CENDLINE); 
        BAKZ;                # RETURN TO CURRENT LINE      #
        COPYLIN(TTYLIN,LIN);
        TRIMPAD;
        REPX;                # SAVE ENLARGED LINE          #
        FWDZ;                # EXTRACT FROM NEXT LINE      #
        GETCHAR(LINE,TMP1,TMP2);
        WHYLE TMP2 EQ CBLANK DO        # KILL LEADER, WORD, TRAILER  #
          BEGIN 
          TMP1=TMP1+1;
          GETCHAR(LINE,TMP1,TMP2);
          END 
        LSHIFT(LIN,TMP1,TMP1);
        TRIMPAD;
        IF LENGTH(LIN) EQ 0 THEN DELX; # DEL AND BACKUP IF EMPTIED   #
        ELSE                 # UPDATE IF STILL EXIST       #
          BEGIN 
          REPX;              # UPDATE REMAINDER OF NEXT LINE         #
          BAKZ;              # TO ORIG TO TRY ANOTHER WORD #
          END 
        END 
      # NOTE - IF NO-OP-ED, WE ARE ALREADY ADVANCED ONE LINE         #
      ELSE IF RIGHTJUST[0] THEN GOTO JUSTIFY; 
      TEST FILLLOOP;
      END 
  
  JUSTIFY:                           # ALIGN WORDS TO RIGHT MARGIN #
      BAKZ; 
      COPYLIN(LIN,TTYLIN);
      TMP2 = 0;                      # NUMBER OF WORDS/BLANKS ADDED # 
      TMP1 = RMARGIN - LENGTH(TTYLIN);
      FOR TMP3 = LMARGIN STEP 1 UNTIL LENGTH(TTYLIN) DO 
         BEGIN
         GETCHAR(TTYLINE,TMP3,TMP5);
         IF TMP5 EQ CBLANK THEN 
           TMP2 = TMP2 + 1; 
         END
      IF TMP2 EQ 0 THEN 
        BEGIN                        # IF NO SPACES DO NOT JUSTIFY #
        FWDZ; 
        TEST FILLLOOP;
        END 
      TMP3 = TMP1/TMP2;              # COMPUTE NUMBER OF BLANKS # 
      TMP4 = TMP1-TMP2*TMP3;         # NUMBER TIMES INSERTED #
      LEFTRIGHT = NOT LEFTRIGHT;
      FOR TMP5 = LMARGIN STEP 1 UNTIL RMARGIN DO
        BEGIN 
        SETCHAR(LINE,TMP5,CBLANK);
        END 
      IF LEFTRIGHT THEN 
        BEGIN                        # IF FROM LEFT TO RIGHT #
        TMP6 = LMARGIN; 
        FOR TMP5 = LMARGIN STEP 1 UNTIL LENGTH(TTYLIN)-1 DO 
          BEGIN 
          GETCHAR(TTYLINE,TMP5,TMP2); 
          SETCHAR(LINE,TMP6,TMP2);
          IF TMP2 EQ CBLANK AND TMP1 NQ 0 THEN
            BEGIN 
            IF TMP4 EQ 0 THEN TMP3 = TMP3 - 1;
            TMP6 = TMP6 + TMP3 + 1; 
            TMP4 = TMP4 - 1;
            TMP1 = TMP1 - TMP3; 
            END 
          TMP6 = TMP6 + 1;
          END 
        END 
      ELSE
        BEGIN                        # JUSTIFY FROM RIGHT TO LEFT # 
        TMP6 = RMARGIN - 1; 
        FOR TMP5 = LENGTH(TTYLIN)-1 STEP -1 UNTIL LMARGIN DO
          BEGIN 
          GETCHAR(TTYLINE,TMP5,TMP2); 
          SETCHAR(LINE,TMP6,TMP2);
          IF TMP2 EQ CBLANK AND TMP1 NQ 0 THEN
            BEGIN 
            IF TMP4 EQ 0 THEN TMP3 = TMP3 - 1;
            TMP6 = TMP6 - TMP3 - 1; 
            TMP4 = TMP4 - 1;
            TMP1 = TMP1 - TMP3; 
            END 
          TMP6 = TMP6 - 1;
          END 
        END 
      SETCHAR(LINE,RMARGIN,CENDLINE); 
      REPX; 
      FWDZ; 
  
    END                       # OF LOOP # 
  
  IF SCREENMODE THEN POSZ(REGLINE[RNGTOPREG]+1);
  ELSE
    BEGIN 
    LINPTR1=REGLINE[RNGTOPREG]+1; 
    LINPTR2=REGLINE[RNGBOTREG]-1; 
    LIMIT=LARGENUM;  EXECNDX=EXECST"TYPE";
    DORANGE;
    END 
  
  END                         # OF DOFILL         # 
PAGE                         # MAIN CODE FOR FSECMDS        # 
  
  
PROC SNGLMOV; 
  BEGIN 
# 
**        SNGLMOV - COMMAND PROCESSOR FOR COPY AND MOVE.
* 
*         ENTRY  COMMAND PROCESSOR HAS RECOGNIZED VERB. 
*                TOKEN ADVANCED BUT NO OTHER SCANNING DONE. 
*                TOKENTYPE, SCANPOS, TOKENPOS, ETC - AS ABOVE.
*                CURFILE, CURSPLIT, CURRENT - DEFAULT ADDRESS.
*                CHARRANGE - CHARACTER OR LINE RANGE BOUNDS.
*                SCREENMODE - FINAL POSITIONING/PRINTING. 
*                WIDTH - THIS SETTING WILL BE IGNORED.
*                DONTPRINT - LINE MODE ECHO OF RESULTS. 
*                BLANKS - THIS SETTING WILL BE IGNORED. 
* 
*         EXIT   CURFILE, CURRENT - FINAL RESTING PLACE.
*                (ANOTHER FILE MAY HAVE BEEN OPENED)
*                SMALLFIELD - TRUE. 
* 
*         CALLS  FLDLEN, SCANNER, FITNUM, MAKEFET, REWIND, RETERN,
*                PUSH, DORANGE, SPLICE, POP, WRITER, READ, TABFN, 
*                DOSPLIT, BAKZ, XFRCMIN, SQUELCH, TRIMPAD, SETLNUM, 
*                INSX, DOJOIN, POSZ, VFYLOCK. 
* 
*         USES   LINPTR1-3, CHRPTR1-3, FILPTR1-3, LINNUM1-3,
*                LINCTR, LIMIT, MOVEFET, FILEBUF. 
* 
*         NOTE   USES THEN RESTORES - LINENO. 
# 
  ITEM LEN; 
  
  SCANNER;
  IF FIELDTARGET NQ 0 THEN CHRPTR3=NUMWIDBLK+TABFN(FIELDTARGET-1);
  
  IF EXECNDX EQ EXECST"MOVE" THEN 
    BEGIN                            # IF MOVE COMMAND #
    VFYLOCK;
    IF SCANMARK THEN KILLMARKS = TRUE;
    END 
  CURFILE = = FILPTR3;
  VFYLOCK;
  CURFILE = = FILPTR3;
  
  IF NUMBERED[FILPTR3] NQ 0 AND CHARRANGE AND LINPTR1 NQ LINPTR2
    AND LIMIT GR 1
    THEN ERRJUMP("FILE MUST NOT CONTAIN SEQUENCE NUMBERS$");
  
  CURFILE = = FILPTR3;
  POSZ(LINPTR3);             # GET FAMILIAR WITH TARGET    #
  FITNUM;                    # ASSURE NUMBERED MODE IS OK  #
  CURFILE = = FILPTR3;
  
  IF CHARRANGE AND LINPTR1 EQ LINPTR2 AND LINPTR1 EQ LINPTR3 THEN 
    BEGIN                            # PHRASE WITHIN LINE # 
    POSZ(LINPTR1);
    IF LENGTH(LIN) EQ 0 THEN
      BEGIN 
      SETCHAR(LINE,0,CBLANK); 
      SETCHAR(LINE,1,CENDLINE); 
      END 
    COPYLIN(LIN,TTYLIN);
    CHRPTR1=MIN(CHRPTR1,LENGTH(LIN)-1); 
    CHRPTR2=MIN(CHRPTR2,LENGTH(LIN)-1); 
    LEN=CHRPTR2-CHRPTR1+1;
    RSHIFT(LIN,CHRPTR3,LEN);
    FOR LINCTR=0 STEP 1 UNTIL LEN-1 DO
      BEGIN 
      GETCHAR(TTYLINE,CHRPTR1+LINCTR,LINPTR2);
      IF CHRPTR3+LINCTR LQ BUFCM1 
        THEN SETCHAR(LINE,CHRPTR3+LINCTR,LINPTR2);
      END 
  
    # NO TRUNCATION AT EDITFIELD HERE SINCE THIS IS CONSIDERED TO # 
    # BE AN IN-PLACE ALTERATION RATHER THAN A CREATION OF NEW TEXT. # 
  
    SETCHAR(LINE,BUFCHAR,CENDLINE); 
    NEWCURSOR=CHRPTR3;
    IF FILCMDNDX EQ FILCMDST"MOVE" THEN 
      BEGIN 
      IF CHRPTR3 LS CHRPTR1 THEN CHRPTR2=CHRPTR2+LEN; 
      ELSE IF CHRPTR3 GR CHRPTR2 THEN NEWCURSOR=CHRPTR3-LEN;
      ELSE NEWCURSOR=CHRPTR1; 
      LSHIFT(LIN,CHRPTR2+1,LEN);
      END 
    TRIMPAD;
    REPX; 
    IF FILCMDNDX EQ FILCMDST"COPY" THEN 
      BEGIN                          # IF MARK MAY NEED TO BE MOVED # 
      IF CHRPTR3 LQ MRKCHAR[1] THEN 
        BEGIN                        # IF SECOND MARK MUST BE MOVED # 
        MRKCHAR[1] = MRKCHAR[1]+LEN;
        IF CHRPTR3 LQ MRKCHAR[0] THEN 
          BEGIN                      # IF FIRST MARK MUST BE MOVED #
          MRKCHAR[0] = MRKCHAR[0]+LEN;
          END 
        END 
      END 
    IF NOT (SCREENMODE OR DONTPRINT) THEN PRINTL; 
    RETURN; 
    END 
  
  FLDLEN(LOC(MAXADDR)+4); 
  SMALLFIELD=FALSE; 
  
  MAKEFET(MOVEFET,"ZZZMOVE",FILEBUF,INIDSKSIZ); 
  REWIND(MOVEFET,1);
  
  SAVLINENO=LINENO; 
  PUSH;                      # SAVE TARGET ADDRESS         #
  
  IF FILCMDNDX EQ FILCMDST"MOVE" AND CHARRANGE THEN 
    BEGIN 
    IF LINPTR2 EQ LINPTR3 
      THEN CHRPTR3=MAX(0,CHRPTR3-(CHRPTR2-CHRPTR1+1));
    DORANGE;                         # COPY RANGE TO ZZZMOVE #
    IF FOUND THEN SPLICE;            # CLOSE BOUNDARIES TOGETHER #
    END 
  ELSE DORANGE;                      # COPY RANGE TO ZZZMOVE #
  
  POP;                       # TO TARGET AREA              #
  LINENO=SAVLINENO; 
  
  WRITER(MOVEFET,1);
  REWIND(MOVEFET,1);
  IF NOT FOUND THEN RETURN; 
  KILLUPLOW=FALSE;
  IF CURFILE NQ FILPTR3 AND ASCII[CURFILE] GQ 2 AND 
    ASCII[FILPTR3] LQ 1 THEN
    BEGIN 
    # IF CHARACTER SETS ARE INCOMPATIBLE, CHANGE CHARSET OF EMPTY # 
    # TARGET FILE, OR FLAG CASE SUPPRESSION # 
    IF BOTF(FILPTR3)-TOPF(FILPTR3)-1 EQ THISEXTEND
      AND ASCII[FILPTR3] EQ 0 
      THEN ASCII[FILPTR3]=ASCII[CURFILE]; 
    ELSE KILLUPLOW=TRUE;
    END 
  CURFILE=FILPTR3;
  READ(MOVEFET,0);           # START FEEDING BUFFER        #
  
  NUMWIDBLK=0;
  IF NUMBERED[CURFILE] NQ 0 THEN NUMWIDBLK=NUMWIDTH+BLANKS; 
  SAVBLANKS=BLANKS; 
  BLANKS=0; 
  LINPTR3=CURRENT+1;         # TAKE NOTE OF RELOCATED TARGET         #
  IF BOTF(CURFILE)-TOPF(CURFILE)-1 EQ THISEXTEND THEN 
    BEGIN                    # IF TARGET FILE IS EMPTY #
    CHARRANGE = FALSE;
    FIELDTARGET = 0;
    END 
  IF CHARRANGE OR FIELDTARGET NQ 0 THEN 
    BEGIN                    # FIRST SEGMENT INTO MIDDLE OF LINE     #
    DOSPLIT(0);              # SPLIT TARGET AT CHRPTR3     #
    BAKZ;                    # INSERTION AFTER FIRST HALF  #
    LINPTR3=CURRENT;
    END 
  FOR LINCTR=1 STEP 1 WHILE LINCTR LQ LCOUNT
    AND NOT (CANINTER AND USRBRK NQ 0) DO 
    BEGIN 
    IF USRBRK NQ 0 THEN DONTPRINT=TRUE; 
    XFRCMIN;
    IF KILLUPLOW THEN SQUELCH(LIN); 
    IF EDITFIELD LS LENGTH(LIN) THEN
      BEGIN 
      SETCHAR(LINE,EDITFIELD,CENDLINE);  # CLEAR TO END OF LINE # 
      TRIMPAD;
      END 
    LINENO=LINENO+INCR; 
    SETLNUM;
    INSX; 
    IF NOT (DONTPRINT OR SCREENMODE) THEN PRINTL; 
    END 
  IF CHARRANGE OR FIELDTARGET NQ 0 THEN 
    BEGIN 
    IF CHARRANGE AND FILCMDNDX EQ FILCMDST"COPY" THEN 
      BEGIN                  # IF MARK MAY NEED TO BE MOVED # 
      IF LINPTR3 EQ REGLINE[MARKREG]
        AND CHRPTR3 LQ MRKCHAR[0] THEN
        BEGIN                # IF FIRST MARK MUST BE MOVED #
        REGLINE[MARKREG] = CURRENT; 
        MRKCHAR[0] = MRKCHAR[0] - CHRPTR3 + LENGTH(LIN);
        END 
      ELSE IF LINPTR3 EQ REGLINE[MARKREG+1] 
        AND CHRPTR3 LQ MRKCHAR[1] THEN
        BEGIN                # IF SECOND MARK MUST BE MOVED # 
        REGLINE[MARKREG+1] = CURRENT; 
        MRKCHAR[1] = MRKCHAR[1] - CHRPTR3 + LENGTH(LIN);
        END 
      END 
    CHRPTR3 == ZERO;         # ASSURE NO EXTENSION IN MERGES         #
    DOJOIN(0);               # MERGE LAST INSERT WITH TRAILER        #
    CHRPTR3 == ZERO;         # RESTORE TARGET CHARACTER ADDRESS # 
    PUSH; 
    POSZ(LINPTR3);
    DOJOIN(0);               # MERGE LEADER WITH FIRST INSERT        #
    POP;
    NEWCURSOR = CHRPTR3;
    END 
  IF SCREENMODE THEN POSZ(LINPTR3);  # POSITION TO TOP OF BLOCK      #
  BLANKS=SAVBLANKS; 
  
  RETERN(MOVEFET,1);
  FLDLEN(LOC(WORKBUF)+DSKSIZ+4);
  SMALLFIELD=TRUE;
  
  END            # OF SNGLMOV  #
  
  
PROC HELPCMD; 
  BEGIN 
# 
**        HELPCMD - COMMAND PROCESSOR FOR HELP FACILITY.
* 
*         ENTRY  PROCESSNDX - INDICATES HELP OR TEACH COMMAND.
*                NO SCANNING BEYOND COMMAND VERB YET. 
*                TOKEN CALLED TO PREPARE NEXT SCAN. 
*                SCANPOS, TOKENPOS, TOKENTYPE, ETC - AS ABOVE.
*                SCREENMODE - PRINTING/POSITIONING MODE.
* 
*         EXIT   HELP FILE BECOMES CURRENT FILE.
*                CURRENT, CURFILE, CURSPLIT - AS ABOVE. 
* 
*         MACROS SETCHAR. 
* 
*         CALLS  MAKEFET, GET, ATTACH, OPENFILE, SCNEQNAME, SCNEOC, 
*                DORANGE, POSZ, SETUPSCREEN, HALT.
* 
*         USES   LINPTR1-3, LINNUM1-3, FILPTR1-3, CHRPTR1-3,
*                PFMFET, FILEBUF, READNAM, FILNUM, CHARPARM, GETPARM, 
*                LOCSTRING1, EXECNDX, WORDSEARCH, ELLIPSIS, DONTPRINT,
*                UPPERSEARCH, FOUND.
# 
  
  READNAM="FSEHELP";
  IF PROCESSNDX EQ KEYST"TCMD" THEN READNAM="FSTEACH";
  
  IF NOT ASSGNFILE(READNAM) THEN
    BEGIN 
    IF READNAM EQ "FSEHELP" THEN
      BEGIN 
      PF("ATTACH",READNAM,READNAM,"RC",PFMERROR,"M","R","UN", 
        HELPUSERNUM,"NA","YES","SR","NF","PN","0",0); 
      END 
    ELSE
      BEGIN 
      C<0,1>READNAM="T";             # LOOK FOR FILE FOR THIS MODEL # 
      C<1,6>READNAM=C<0,6>TABMODNAME; 
      PF("GET","FSTEACH",READNAM,"RC",PFMERROR,"UN",HELPUSERNUM,
        "PN","0",0);
      READNAM="FSTEACH";
      IF PFMERROR NQ 0 THEN 
        BEGIN                        # IF SPECIFIC FILE NOT FOUND # 
        PF("GET",READNAM,READNAM,"RC",PFMERROR,"UN",HELPUSERNUM,
          "PN","0",0);
        END 
      END 
    END 
  
  FILNUM=CURFILE; 
  IF FILENAM[FILNUM] NQ READNAM THEN
    BEGIN 
    FILNUM=1; 
    IF SCREENMODE AND PROCESSNDX EQ KEYST"HCMD" THEN
      BEGIN                          # IF SCREEN MODE HELP #
      FILNUM = 2;                    # SPLIT SCREEN MODE #
      ERRSTRING = "USE 'EDIT' TO UNSPLIT SCREEN$";
      END 
    ELSE
      BEGIN                          # LINE MODE OR TEACH # 
      ERRSTRING = "USE 'EDIT' TO RETURN TO INITIAL FILE$";
      END 
    CHARPARM=2; 
    GETPARM=0;
    OPENFILE; 
    END 
  POSZ(TOPF(FILNUM)+1);            # DEFAULT TO TOP OF FILE # 
  IF SYNTAXCHAR[TOKENCHAR] THEN 
    BEGIN                   # TOPIC SEARCH RATHER THAN DEFAULT      # 
    IF TOKENTYPE EQ TYPST"LETTER" THEN
      BEGIN                          # IF CHARACTER STRING #
      SCNEQNAM(READNAM);
      SCNEOC; 
      SETCHAR(LOCSTR1,0,CLPAREN); 
      LINPTR2=B<0,6>READNAM;
      FOR LINPTR1=0 STEP 1 WHILE LINPTR1 LQ 6 AND 
        LINPTR2 NQ " " DO 
        BEGIN 
        SETCHAR(LOCSTR1,LINPTR1+1,LINPTR2); 
        LINPTR2=B<6*LINPTR1+6,6>READNAM;
        END 
      SETCHAR(LOCSTR1,LINPTR1+1,CRPAREN); 
      END 
    ELSE
      BEGIN                          # NOT ALPHABETIC # 
      LINPTR2 = TOKENCHAR;
      SETCHAR(LOCSTR1,0,CLPAREN); 
      SETCHAR(LOCSTR1,1,LINPTR2); 
      SETCHAR(LOCSTR1,2,CRPAREN); 
      LINPTR1 = 1;
      TOKEN;
      IF SYNTAXCHAR[TOKENCHAR] THEN 
        ERRJUMP("PLEASE ENTER 'HELP DIRECTIVE'$");
      END 
    SETCHAR(LOCSTR1,LINPTR1+2,CENDLINE);
    LOCSTRLEN1=LINPTR1+2; 
    LINPTR1=CURRENT;
    LINPTR3=CURRENT;
    LINPTR2=BOTF(FILNUM)-1; 
    LIMIT=1;
    EXECNDX=EXECST"LOCATE"; 
    WORDSEARCH=FALSE;   ELLIPSIS=FALSE;   DONTPRINT=TRUE; 
    UPPERSEARCH=FALSE;  CHRPTR1=0;  CHRPTR2=BUFCM1; 
    DORANGE;               # SEARCH FOR (KEYWORD)        #
    IF NOT FOUND THEN POSZ(LINPTR3);
    FOUND=TRUE; 
    END 
  IF NOT SCREENMODE THEN
    BEGIN 
    LINPTR1=CURRENT;
    LINPTR2=BOTF(FILNUM)-1; 
    LIMIT=HELPSIZE;                  # HELP FILE LINES TO DISPLAY # 
    EXECNDX=EXECST"TYPE"; 
    DONTPRINT=FALSE;
    DORANGE;
    END 
  IF FILNUM EQ 2 THEN 
    BEGIN 
    IF SPLITFILE[2] NQ 2 THEN SETUPSCREEN(1,2,USRSPLTSZ); 
    END 
  
  
  END            # OF HELPCMD          #
  
  
PROC GETSTATUS; 
  BEGIN 
# 
**        GETSTATUS - COMMAND PROCESSOR FOR GET STATUS SUBCOMMAND.
* 
*         ENTRY  COMMAND FULLY SCANNED EXCEPT TERMINATOR VERIFY.
*                ONE OR BOTH FILE BRACKETS OPENED SOMEWHERE.
* 
*         EXIT   SCREENMODE SCHEDULED FOR TOTAL REPAINT.
*                COMMAND TERMINATOR SCANNED.
*                OPEN FILES UPDATED INTO DIRECTORY.  (SIDE EFFECT)
* 
*         CALLS  SCNEOC, BGNDSPLAY, TTSTR, EOLDSPLAY, PUSH, 
*                PADNAME, CLOSEFILE, POSZ, SCANFDL, TTST, FWDZ, POP,
*                TTDEC, TTCHAR, ENDDSPLAY, TABFN. 
* 
*         USES   FILNUM, READNAM, LINPTR1, LINCTR.
* 
*         NOTE -
* 
*         THIS BLOCK OF CODE IS SUBJECT TO CERTAIN RESTRICTIONS IN
*         ORDER TO DRIVE THE TERMINAL IN BOTH LINE MODE AND SCREEN
*         MODE.  TTLIN CANNOT BE USED.  THE ONLY ALLOWABLE WAY TO 
*         ADVANCE TO A NEW LINE OF OUTPUT IS TO CALL EOLDSPLAY AS 
*         A LOGICAL REPLACEMENT FOR TTBRK.  EOLDSPLAY WILL IN TURN
*         USE EITHER TTBRK (FOR LINE MODE) OR VDTPOS (SCREEN MODE)
*         TO CONTROL THE OUTPUT DEVICE.  BGNDSPLAY IS USED TO INIT
*         THE DISPLAY AND ENDDSPLAY CLEANS UP AFTERWARD.  EOLDSPLAY 
*         INCLUDES SCREEN-OVERFLOW LOGIC. 
# 
  ITEM TMP1, TMP2, TMP3, TMP4, TMP5;
  BASED ARRAY KEYLIN[0:99]; ITEM KEYLINE; 
  
  
  PROC DSPLFKEY(WHICH); 
    BEGIN 
    ITEM WHICH; 
    ITEM TMP1, TMP2;
    P<KEYLIN>=LOC(FKEYSTRING[WHICH]); 
    IF WHICH LS 0 THEN TTSTR("  SHIFT F$"); 
    ELSE TTSTR("        F$"); 
    TTDEC(ABS(WHICH));
    IF ABS(WHICH) LS 10 THEN TTSTR(" $"); 
    TTSTR("  $"); 
    TTST(FKEYNAME[WHICH],6);
    TTSTR("  $"); 
    FOR TMP1=0 STEP 1 UNTIL 15 DO 
      BEGIN 
      IF TMP1 LS LENGTH(KEYLIN) THEN
        BEGIN 
        GETCHAR(KEYLINE,TMP1,TMP2); 
        TMP2=XLTINTDSP[TMP2]; 
        C<0,1>TMP2=C<9,1>TMP2;
        TTST(TMP2,1); 
        END 
      ELSE TTSTR(" $"); 
      END 
    END                              # OF DSPLFKEY #
  
  
  # ACTUAL GETSTATUS CODE STARTS HERE # 
  
  SCNEOC; 
  BGNDSPLAY;
  TTSTR("                   $");
  TTSTR("  EDITOR STATUS INFORMATION:$"); 
  EOLDSPLAY;
  EOLDSPLAY;
  TTSTR(" FILES:    NAME    LOCK  CHANGE $"); 
  TTSTR("CHARSET NUMBERED SIZE POSITION$"); 
  EOLDSPLAY;
  PUSH; 
  FOR FILNUM=1 STEP 1 UNTIL 2 DO
    BEGIN 
    IF PADNAME(FILENAM[FILNUM]) NQ " " THEN CLOSEFILE;
    END 
  POSZ(TOPC(FILECTL)+1);
  WHYLE CURRENT LS BOTC(FILECTL) DO 
    BEGIN 
    SCANFDL(READNAM); 
    IF READNAM NQ "ZZZNULL" THEN
      BEGIN 
      IF CURRENT EQ FDLF(CURFILE) THEN
        BEGIN                        # IF CURRENT FILE, INDICATE #
        TTSTR(" (CURRENT) $");
        END 
      ELSE
        BEGIN                        # JUST ANOTHER FILE #
        TTSTR("           $");
        END 
      FOR FILNUM=0 STEP 1 UNTIL 6 DO TTST(C<FILNUM,1>READNAM,1);
      TTST(YESORNO[SCNFDLOCK],7); 
      TTST(YESORNO[SCNFDCHNG],7); 
      TTST(CHARTYPE[SCNFDASCI],7);
      TTST(YESORNO[SCNFDNUMB],7); 
      TTLPAD(SCNFDSIZE,7," ");
      TTLPAD(SCNFDCURF,7," ");
      EOLDSPLAY;
      END 
    FWDZ; 
    END 
  POP;
  EOLDSPLAY;
  TTSTR(" SET VIEW IN: $"); 
  TTDEC(DFINBGN); 
  TTSTR(" $");
  TTDEC(DFINEND); 
  TTSTR("  $"); 
  TTSTR(" TAB COLUMNS: $"); 
  LINPTR1=TABFN(1); 
  FOR LINCTR=1 STEP 1 WHILE LINCTR LQ USERTABS AND LINPTR1 NQ 0 DO
    BEGIN 
    TTDEC(LINPTR1+1); TTSTR("  $"); 
    LINPTR1=TABFN(LINCTR+1);
    END 
  EOLDSPLAY;
  TTSTR(" SET VIEW WARN: $"); 
  TTDEC(WIDTH); 
  TTSTR("   $");
  TTSTR("SET UNDO: $"); 
  IF AUDITOFF THEN TTSTR(" NO$"); ELSE TTSTR("YES$"); 
  TTSTR("   $");
  TTSTR("TAB CHARACTER: $");
  TTCHAR(TABCHAR,TRUE); 
  TTSTR("  $"); 
  TTSTR("CNTRL CHRS: $"); 
  TTCHAR(UNPRINT,TRUE); 
  EOLDSPLAY;
  TTSTR(" SET VIEW EDIT: $"); 
  TTDEC(EDITFIELD); 
  TTSTR("   $");
  TTSTR("SET JUMP: $"); 
  IF AUTOINDENT THEN TTSTR("YES$"); ELSE TTSTR(" NO$"); 
  TTSTR("   $");
  TTSTR("SET WORD FILL: $");
  TTDEC(FILLLEFT+1);
  TTSTR(" $");
  TTDEC(FILLRIGHT+1); 
  TTSTR(" $");
  TTDEC(FILLFIRST+1); 
  TTSTR("   JUSTIFY:$");
  IF RIGHTJUST[0] THEN TTSTR(" YES$"); ELSE TTSTR("  NO$"); 
  EOLDSPLAY;
  TTSTR(" SEARCH STRING: '$");
  FOR TMP1=0 STEP 1 UNTIL LOCSTRLEN1-1 DO 
    BEGIN 
    GETCHAR(LOCSTR1,TMP1,TMP2); 
    TTCHAR(TMP2,FALSE); 
    END 
  IF ELLIPSIS THEN
    BEGIN 
    TTSTR("'..'$"); 
    FOR TMP1=0 STEP 1 UNTIL LOCSTRLEN2-1 DO 
      BEGIN 
      GETCHAR(LOCSTR2,TMP1,TMP2); 
      TTCHAR(TMP2,FALSE); 
      END 
    END 
  TTSTR("'$");
  EOLDSPLAY;
  IF SCREENMODE THEN
    BEGIN 
    EOLDSPLAY;
    TTSTR(" FUNCTIONS: KEY$");
    TTSTR("  LABEL   DIRECTIVES      $"); 
    TTSTR("  KEY        LABEL   DIRECTIVES$");
    FOR TMP1=1 STEP 1 UNTIL POSFKEYS DO 
      BEGIN 
      TMP2=0; 
      P<KEYLIN>=LOC(FKEYSTRING[TMP1]);
      FOR TMP4=0 STEP 1 UNTIL LENGTH(KEYLIN)-1 DO 
        BEGIN 
        GETCHAR(KEYLINE,TMP4,TMP5); 
        IF TMP5 NQ CBLANK THEN TMP2=1;
        END 
      TMP3=0; 
      P<KEYLIN>=LOC(FKEYSTRING[-TMP1]); 
      FOR TMP4=0 STEP 1 UNTIL LENGTH(KEYLIN)-1 DO 
        BEGIN 
        GETCHAR(KEYLINE,TMP4,TMP5); 
        IF TMP5 NQ CBLANK THEN TMP3=1;
        END 
      IF TMP2 NQ 0 OR FKEYNAME[TMP1] NQ " " 
        OR TMP3 NQ 0 OR FKEYNAME[-TMP1] NQ " " THEN 
        BEGIN 
        EOLDSPLAY;
        TTSTR("    $"); 
        DSPLFKEY(TMP1); 
        IF TMP3 NQ 0 OR FKEYNAME[-TMP1] NQ " " THEN DSPLFKEY(-TMP1);
        END 
      END 
    END 
  ENDDSPLAY;
  END            # OF GETSTATUS  #
  
  
PROC UNDOCMD; 
  BEGIN 
# 
**        UNDOCMD - COMMAND PROCESSOR FOR UNDO FACILITY.
* 
*         ENTRY  COMMAND SCANNED EXCEPT TERMINATOR VERIFY.
*                CURA(AUDITCTL) AT MOST RECENT CHANGE RECORD. 
*                TOPA(AUDITCTL) BOUNDS AUDIT TRAIL. 
*                NUMMARKS - WHETHER MARKS ARE CURRENTLY ON. 
* 
*         EXIT   COMMAND TERMINATOR VERIFIED. 
*                SELECTION OF OPENED FILES MAY CHANGE.
*                CURA(AUDITCTL) BACKED UP.
*                NUMMARKS - ZEROED. 
* 
*         MACROS GETCHAR. 
* 
*         CALLS  ERRJUMP, AUDITSYNCH, POSZ, UNDODECODE, UNDOOPEN, 
*                BAKZ, FATAL, PUSH, UNDOPOS, INSX, POP, DELX, REPX, 
*                PAINTMARKS.
* 
*         USES   AUDITOFF, AUDITUSED, LINPTR1, LINNUM1, LINNUM2,
*                LINNUM3, USRBRK. 
# 
  
  IF SYNTAXCHAR[TOKENCHAR] THEN 
    BEGIN                            # IF MORE SYNTAX # 
    TOKEN;
    IF NUMMARKS NQ 0 THEN 
      BEGIN                          # IF MARKS ACTIVE #
      PAINTMARKS(3);
      NUMMARKS=0; 
      ERRSTRING="MARKS CANCELLED$"; 
      END 
    ELSE
      BEGIN                          # NO MARKS ACTIVE #
      ERRSTRING="NO MARK(S) ACTIVE$"; 
      END 
    SCNEOC;                          # SCAN FOR END OF COMMAND #
    RETURN; 
    END 
  
  SCNEOC;                            # SCAN FOR END OF COMMAND #
  
  IF AUDITOFF THEN ERRJUMP("SET UNDO YES - TO ENABLE UNDO$"); 
  AUDITOFF=TRUE;
  AUDITSYNCH;                # CLEAR STAGING BUFFER        #
  AUDITUSED=FALSE;           # NO CHKPT TRANSACT CANCELLED IN MIDDLE #
  POSZ(CURA(AUDITCTL)); 
  GETCHAR(LINE,0,LINPTR1);
  IF LINPTR1 EQ CLETTERC THEN          # ACCESS PREVIOUS FILES       #
    BEGIN 
    UNDODECODE(1,LINNUM1);             # FIRST FILE        #
    UNDODECODE(12,LINNUM2);            # SECOND FILE       #
    UNDODECODE(23,LINNUM3);            # SCREEN SPLIT      #
    UNDOOPEN(1,LINNUM1);
    UNDODECODE(12,LINNUM1); 
    UNDOOPEN(2,LINNUM1);
    BAKZ; 
    END 
  GETCHAR(LINE,0,LINPTR1);
  WHYLE CURRENT GR TOPA(AUDITCTL) AND LINPTR1 NQ CLETTERC 
    AND LINPTR1 NQ CLETTERE AND USRBRK EQ 0 DO
    BEGIN 
    UNDODECODE(1,LINNUM1);
    UNDODECODE(12,LINNUM2); 
    UNDODECODE(23,LINNUM3); 
    IF LINNUM2 NQ FDLF(LINNUM1) THEN UNDOOPEN(LINNUM1,LINNUM2); 
    IF LINPTR1 EQ CLETTERD THEN 
      BEGIN 
      BAKZ; 
      PUSH; 
      UNDOPOS(-1);
      INSX; 
      POP;
      END 
    ELSE IF LINPTR1 EQ CLETTERI THEN
      BEGIN 
      PUSH; 
      UNDOPOS(+1);
      DELX; 
      POP;
      END 
    ELSE IF LINPTR1 EQ CLETTERR THEN
      BEGIN 
      BAKZ; 
      PUSH; 
      UNDOPOS(0); 
      REPX; 
      CURF(CURFILE)=CURF(CURFILE)-1;
      POP;
      END 
    BAKZ; 
    GETCHAR(LINE,0,LINPTR1);
    END 
  CURA(AUDITCTL)=CURRENT; 
  CURF(CURFILE)=MAX(MIN(CURF(CURFILE)+1,BOTF(CURFILE)-1),TOPF(CURFILE));
  POSZ(CURF(CURFILE));
  AUDITOFF=FALSE; 
  NEWCURSOR = 0;
  END            # OF UNDOCMD  #
  
  
PROC WORDCMD; 
  BEGIN 
# 
**        WORDCMD - COMMAND PROCESSOR FOR WORD PROCESSING.
* 
*         ENTRY  COMMAND VERB SCANNED, TOKEN ADVANCED FOR NEXT. 
*                USUAL DEFAULTS AVAILABLE.  (CURRENT, ETC.) 
* 
*         EXIT   COMMAND PROCESSED. 
* 
*         CALLS  VFYLOCK, TOKEN, ERRJUMP, SCANNER,
*                DOFILL.
* 
*         USES   LCOUNT, SCANPOS, KEYWDTYPE.
# 
  IF TOKENTYPE NQ TYPST"LETTER" OR KEYWDNDX LS 0
    THEN ERRJUMP("CHARACTER SEQUENCE NOT RECOGNIZED$"); 
  LCOUNT=KEYWDNDX;
  TOKEN;                     # ADVANCE TO NEXT SYNTAX      #
  SCANNER;
  VFYLOCK;
  IF NOT FOUND THEN RETURN;            # OUT OF BOUNDS     #
  IF LCOUNT EQ KEYST"WFIL" THEN 
    BEGIN 
    DOFILL; 
    NEWCURSOR=0;
    RETURN; 
    END 
  ELSE IF LCOUNT EQ KEYST"WCEN" THEN
    BEGIN 
    EXECNDX=EXECST"CENTER"; 
    DORANGE;
    RETURN; 
    END 
  END            # OF WORDCMD  #
  
  
END TERM
