FSESCRN 
PROC FSESCRN; 
  BEGIN 
# 
***       FSESCRN - SCREEN EDITING MODULE.
* 
*         COPYRIGHT CONTROL DATA SYSTEMS INC.  1992.
# 
  
  DEF LISTCON #0#;
  
*IFCALL SINGLE,COMFSGL
*IFCALL ONLY,COMFONL
*IFCALL MULTI,COMFMLT 
*CALL COMFFSE 
*CALL COMFDS1 
*CALL COMFVD2 
*CALL COMFDS2 
*CALL COMFTAB 
  
*CALL COMFVDT 
  
CONTROL IFEQ MULTI,1; 
  XREF ARRAY RENTSTK [1:MAXREENT];     # SUBROUTINE STACK  #
    BEGIN 
    ITEM RSTK;
    END 
  XREF ITEM RSTKPTR;
CONTROL FI; 
  
  
XDEF
  BEGIN 
*CALL COMFXSC 
  END 
  
XREF
  BEGIN 
*CALL COMFXVT 
*CALL COMFXTI 
*CALL COMFXFO 
*CALL COMFXSB 
*CALL COMFXED 
  END 
  
XREF FUNC LENGTH;   # COMPASS ROUTINES #
XREF PROC MOVEWD;   XREF PROC EXCHWD; 
# 
  MASKS FOR SETTING THE VARIOUS ATTRIBUTES IN ATTRIBMASK (COMFVD2)
# 
  DEF MSKLOGICAL #O"4000"#;          # LOGICAL ATTRIBUTE #
  DEF MSKPROTECT #O"2000"#;          # PROTECT #
  DEF MSKGUARDMD #O"1000"#;          # GUARD MODE # 
  DEF MSKUNDERLN #O"0010"#;          # UNDERLINE #
  DEF MSKALTERIN #O"0004"#;          # ALTERNATE INTENSITY #
  DEF MSKINVERSE #O"0002"#;          # INVERSE #
  DEF MSKBLINKMD #O"0001"#;          # BLINK MODE # 
PAGE                         # DOSCREEN - SCREEN MANIPULATIONS       #
  
  
PROC DOSCREEN;
  IOBEGIN(DOSCREEN) 
# 
**        DOSCREEN - MIMIC ON-SCREEN MANIPULATIONS IN INPUT.
* 
*         DOSCREEN PROCESSES ALL SCREEN MODE INPUT.  IT PERFORMS
*         FILE MANIPULATIONS TO MIMIC SCREEN MANIPULATIONS.  IT 
*         KEEPS FILE POSITIONING UP TO DATE WITH THE USERS CURSOR 
*         POSITIONING.  IT COMPUTES NEW DEFAULT CURSOR POSITIONING
*         BETWEEN TRANSACTIONS.  IT PROCESS SOME FUNCTION KEYS
*         INTERNALLY AND CONVERTS OTHER FUNCTION KEYS INTO COMMAND
*         STRINGS.  DOSCREEN SHOULD BE CALLED ALTERNATING WITH THE
*         COMMAND SCANNER AND THE SCREEN PAINTER. 
* 
*         ENTRY  CMDLIN - REPAIRABLE COMMANDS IF ANY OR NULL. 
*                OUTPUT CYCLE (PAINTSCREEN) EXECUTED. 
*                VTXCUR, VTYCUR - CURSOR AS SET BY OUTPUT.
*                CURFILE, CURSPLIT, CURRENT - AS SET BY 
*                    COMMAND PROCESSING.
*                FILENAM[1-2], FILEATTR[1-2] - SET UP.
*                XSHIFT[1-2], YSHIFT[1-2] - SHIFT FACTORS.
*                TOPS(1-2), BOTS(1-2), BOTF(1-2) - SCREEN BOUNDARIES. 
*                SETUPSCREEN ALREADY CALLED. (TITLEROW[1-2],
*                    NUMROWS[1-2], ROWTYPE[1-2], ETC, SETUP)
*                ROWPAINT[ALL] - FALSE SINCE PAINTSCREEN CALLED.
*                FKEYNAME[ALL,ALL] - SETUP. 
*                CHARRANGE - INDICATES LINE OR CHARACTER MARKING. 
*                TABVTPROTM[0] - SETUP. 
*                COMMANDROW - SETUP.
*                PROMPTING - INDICATES NORMAL OR SPECIAL PROMPT.
*                EDITFIELD - LOGICAL RIGHT LIMIT ON CHANGES.
* 
*         EXIT   CMDLIN - REPAIRED OR NEWLY ENTERED COMMANDS. 
*                ROWPAINT[ANY] - POSSIBLY TRUE. 
*                VTXCUR, VTYCUR - CURSOR AS MOVED BY USER.
*                XCURSOR, YCURSOR - SET BY USER THEN POSSIBLY 
*                    UPDATED TO ADVANCE THRU FILE OR TO STAY
*                    WITH DATA UPON AUTO HALF-PAGE ADVANCE. 
*                XSHIFT[1-2], YSHIFT[1-2] - POSSIBLY UPDATED. 
*                TOPS(1-2), BOTS(1-2), BOTF(1-2) - UPDATED. 
*                CURFILE, CURSPLIT, CURRENT - AS SELECTED BY USER.
*                CURCURSOR - USERS LAST VTXCUR, SHIFTED.
*                HARDFN - FALSE TO ALLOW PROPER COMMAND OPERATION.
*                LIN - TEXT CORRESPONDING TO CURRENT, CURFILE.
* 
*         MACROS GETCHAR, SETCHAR, YTOL, LTOY.
* 
*         CALLS  (INTERNAL) - ALIGN, CLEANLINE, DELTEXT, DSERRJMP,
*                EXTEND, INCRCURSOR, INSTEXT, MOVETEXT, REJECT, 
*                SETCMD, SETCURSOR. 
*                (EXTERNAL) - BAKZ, DELX, INSX, LENGTH, PAINTALL, 
*                PAINTREST, PAINTSPLIT, SETBOTS, SETMARK, SETTOPS,
*                TRIMPAD, VDTBOO, VDTEOO, VDTINP, VDTPPI, VFYLOCK.
* 
*         USES   ALIGNGOOD, COMPUTEDPOS, FKEYNDX, HARDFN, LINECHANGED,
*                OLDVTXCUR, OLDVTYCUR, READNAM, SCREENLIMIT, SCRNPT1, 
*                SCRNPT2, SCRNPT3, SCRNPT4, SCRNPT5, SOFTTAB. 
* 
*         NOTE -
* 
*         DOSCREEN MUST PROCESS ALL INPUT CHARACTERS.  THE ONLY UN- 
*         FINISHED BUSINESS IT MAY LEAVE WOULD BE THE CONTENTS OF THE 
*         COMMAND BUFFER LINE.  DOSCREEN CAN EXIT ONLY THROUGH THE
*         "DSEOI" SECTION OR THRU THE DSERRJMP ROUTINE.  DOSCREEN MUST
*         THEREFORE BE FUNCTIONALLY EQUIVALENT IN BOTH SINGLE AND MULTI 
*         USER VERSIONS.  THE ONLY SINGLE/MULTI COMPILE-TIME DIFFERENCE 
*         ALLOWABLE WOULD BE MODULE-DEPENDENT OPTIMIZATIONS WHICH CAUSE 
*         NO TRANSITIONS TO OCCUR.
# 
  
  # NOTE -- SCREENSW AND VIRTERMATR MUST MATCH SCREENST # 
  
  SWITCH SCREENSW  DSCLRALL, DSCHAR, DSINSC, DSDELC, DSINSL,
    DSDELL, DSCLRPAG, DSCLREOP, DSCLRUNP, DSCLREOL, DSPOS,
    DSHOME, DSUP, DSDOWN, DSLEFT, DSRIGHT, DSFTAB, DSBTAB,
    DSRET, DSERAC, DSERAL, DSEOI, DSRESET, DSFKEY, DSGENERIC, 
    DSBAD, DSNOOP, DSCOORD, DSPROTECT, DSFIELD, DSCLRTAB, DSSETTAB; 
  
  ARRAY VIRTERMATR [0:31];    # VIRTUAL TERMINAL ATTRIBUTES # 
    BEGIN                      # INDEXED BY VDT ORDINAL      #
    ITEM NEEDALIGN  B(0,0,1)=[
      FALSE, TRUE,  TRUE,  TRUE,     # CLRALL, CHAR, IC, DC          #
      TRUE,  TRUE,  TRUE,  TRUE,     # IL, DL, CLRPAG, CLREOP        #
      TRUE,  TRUE,  FALSE, FALSE,    # CLRUNP, CLREOL, POS, HOME     #
      FALSE, FALSE, FALSE, FALSE,    # UP, DOWN, LEFT, RIGHT         #
      FALSE, FALSE, FALSE, TRUE,     # FTAB, BTAB, RET, ERAC         #
      TRUE,  FALSE, FALSE, TRUE,     # ERAL, EOI, RESET, FUNCTION    #
      TRUE,  FALSE, FALSE, FALSE,    # GENERIC, BAD, NOOP, COORD     #
      FALSE, TRUE,  FALSE, FALSE     # PROTECT, FIELD, CLRTAB, SETTAB#
                              ];
    ITEM NEEDCLEAN  B(0,1,1)=[
      FALSE, FALSE, FALSE, FALSE,    # CLRALL, CHAR, IC, DC          #
      TRUE,  TRUE,  FALSE, FALSE,    # IL, DL, CLRPAG, CLREOP        #
      FALSE, FALSE, FALSE, FALSE,    # CLRUNP, CLREOL, POS, HOME     #
      FALSE, FALSE, FALSE, FALSE,    # UP, DOWN, LEFT, RIGHT         #
      FALSE, FALSE, FALSE, FALSE,    # FTAB, BTAB, RET, ERAC         #
      FALSE, TRUE,  FALSE, TRUE,     # ERAL, EOI, RESET, FUNCTION    #
      TRUE,  FALSE, FALSE, FALSE,    # GENERIC, BAD, NOOP, COORD     #
      FALSE, TRUE,  FALSE, FALSE     # PROTECT, FIELD, CLRTAB, SETTAB#
                              ];
    ITEM NEEDUNLOCK B(0,2,1)=[
      FALSE, TRUE,  TRUE,  TRUE,     # CLRALL, CHAR, IC, DC          #
      TRUE,  TRUE,  FALSE, FALSE,    # IL, DL, CLRPAG, CLREOP        #
      FALSE, TRUE,  FALSE, FALSE,    # CLRUNP, CLREOL, POS, HOME     #
      FALSE, FALSE, FALSE, FALSE,    # UP, DOWN, LEFT, RIGHT         #
      FALSE, FALSE, FALSE, TRUE,     # FTAB, BTAB, RET, ERAC         #
      TRUE,  FALSE, FALSE, FALSE,    # ERAL, EOI, RESET, FUNCTION    #
      FALSE, FALSE, FALSE, FALSE,    # GENERIC, BAD, NOOP, COORD     #
      FALSE, TRUE,  FALSE, FALSE     # PROTECT, FIELD, CLRTAB, SETTAB#
                              ];
    ITEM NEEDCURSOR B(0,3,1)=[
      FALSE, TRUE,  TRUE,  TRUE,     # CLRALL, CHAR, IC, DC          #
      TRUE,  TRUE,  TRUE,  TRUE,     # IL, DL, CLRPAG, CLREOP        #
      TRUE,  TRUE,  FALSE, FALSE,    # CLRUNP, CLREOL, POS, HOME     #
      FALSE, FALSE, FALSE, FALSE,    # UP, DOWN, LEFT, RIGHT         #
      FALSE, FALSE, FALSE, TRUE,     # FTAB, BTAB, RET, ERAC         #
      TRUE,  FALSE, FALSE, TRUE,     # ERAL, EOI, RESET, FUNCTION    #
      TRUE,  FALSE, FALSE, FALSE,    # GENERIC, BAD, NOOP, COORD     #
      FALSE, TRUE,  FALSE, FALSE     # PROTECT, FIELD, CLRTAB, SETTAB#
                              ];
    ITEM NEEDLIMIT  U(0,6,6)=[
      0,     1,     1,     1,        # CLRALL, CHAR, IC, DC          #
      1,     1,     1,     1,        # IL, DL, CLRPAG, CLREOP        #
      2,     1,     1,     1,        # CLRUNP, CLREOL, POS, HOME     #
      1,     1,     1,     1,        # UP, DOWN, LEFT, RIGHT         #
      1,     1,     0,     1,        # FTAB, BTAB, RET, ERAC         #
      1,     0,     0,     2,        # ERAL, EOI, RESET, FUNCTION    #
      2,     0,     0,     0,        # GENERIC, BAD, NOOP, COORD     #
      0,     1,     0,     0         # PROTECT, FIELD, CLRTAB, SETTAB#
                              ];
    END 
  
  BASED ARRAY KEYLIN[0:99]; ITEM KEYLINE; 
PAGE                          # SUBROUTINES INTERNAL TO DOSCREEN #
  
  
  PROC SETCURSOR; 
    BEGIN 
# 
**        SETCURSOR - SET CURSOR CONTROLS.
* 
*         ENTRY  ROWTYPE[ALL], ROWSPLIT[ALL] - SETUP. 
* 
*         EXIT   XCURSOR, YCURSOR, COMPUTEDPOS - SETUP. 
*                CURCURSOR - SET IF YCURSOR ON TEXT ROW.
# 
    XCURSOR=VTXCUR; 
    YCURSOR=VTYCUR; 
    COMPUTEDPOS=TRUE; 
    IF ROWTYPE[YCURSOR] EQ ROWST"TEXT"
      OR ROWTYPE[YCURSOR] EQ ROWST"TITLE" THEN
      BEGIN 
      CURCURSOR=XCURSOR+XSHIFT[ROWSPLIT[YCURSOR]];
      CURSPLIT=ROWSPLIT[YCURSOR]; 
      END 
    END                        # OF SETCURSOR    #
  
  PROC ALIGN; 
    IOBEGIN(ALIGN)
# 
**        ALIGN - ASSURE FILE ALIGNED WITH CURSOR.
* 
*         ENTRY  YCURSOR - WHERE THE CURSOR IS. 
*                CURRENT - MOST RECENT FILE POSITION. 
*                ROWTYPE[ALL], ROWSPLIT[ALL] - SETUP. 
*                TOPS(1-2), BOTF(1-2) - SETUP.
*                NUMROWS[1-2], SPLITFILE[1-2] - SETUP.
*                PROMPTING - WHETHER NORMAL OR SPECIAL DISPLAY. 
* 
*         EXIT   ALIGNGOOD - TRUE IF PROMPTING AND SUCCEEDED
*                    IN GETTING TO RIGHT LINE.  FALSE IF CURSOR NOT 
*                    ON TEXT OR IN AREA BEYOND LAST EXTANT LINE.
*                CURRENT, CURFILE, CURSPLIT - WHERE WE ARE. 
*                CURF(CURFILE) - WHERE WE ARE.
* 
*         MACROS YTOL.
* 
*         CALLS  CLEANLINE, POSZ. 
* 
*         USES   SCRNPT1. 
# 
    ALIGNGOOD=FALSE;
    IF ROWTYPE[YCURSOR] EQ ROWST"TEXT" OR 
      (ROWTYPE[YCURSOR] EQ ROWST"TITLE" AND 
       ROWSPLIT[YCURSOR] EQ CURSPLIT) THEN
      BEGIN 
      EXTENDSIZE=0; 
      CURSPLIT=ROWSPLIT[YCURSOR]; 
      CURSPLIT=MIN(MAX(CURSPLIT,1),2);
      SCRNPT1=YTOL(YCURSOR,CURSPLIT); 
      IF SCRNPT1 LQ MIN(TOPS(CURSPLIT)+NUMROWS[CURSPLIT], 
        BOTF(SPLITFILE[CURSPLIT])-1) THEN 
        BEGIN 
        IF NOT PROMPTING AND ROWTYPE[YCURSOR] EQ
          ROWST"TEXT" THEN ALIGNGOOD=TRUE;
        IF CURRENT NQ SCRNPT1 
           OR CURFILE NQ SPLITFILE[CURSPLIT] THEN 
          BEGIN 
          CLEANLINE;
          CURF(CURFILE)=CURRENT;
          POSZ(SCRNPT1);
          CURFILE=SPLITFILE[CURSPLIT];
          END 
        END 
      ELSE
        BEGIN 
        CLEANLINE;
        CURFILE=SPLITFILE[CURSPLIT];
        POSZ(BOTF(CURFILE)-1);
        CURF(CURFILE)=CURRENT;
        EXTENDSIZE=SCRNPT1-BOTF(CURFILE)+1; 
        END 
      END 
    IOEND                   # OF ALIGN         #
  
  PROC EXTEND;
    IOBEGIN(EXTEND) 
# 
**        EXTEND - LENGTHEN FILE TO MATCH CURSOR ALIGNMENT. 
* 
*         ENTRY  ALIGN ROUTINE RECENTLY CALLED. 
*                ALIGNGOOD - RESULT OF ALIGN ROUTINE. 
*                ROWTYPE[ALL], ROWSPLIT[ALL] - SETUP. 
*                BOTF(1-2), SPLITFILE[1-2] - SETUP. 
*                CURRENT - MOST RECENT FILE POSITION. 
*                PROMPTING - NORMAL OR SPECIAL DISPLAY. 
* 
*         EXIT   ALIGNGOOD - ASSURED TRUE UNLESS PROMPTING. 
*                CURSPLIT, CURRENT, CURFILE - WHERE WE ARE. 
*                CURF(CURFILE) - WHERE WE WERE BEFORE CHANGING CURFILE. 
*                HARDFN - FALSE IF WE EXTENDED THE FILE.
*                FILE IS POSSIBLY LONGER. 
* 
*         MACROS YTOL.
* 
*         CALLS  CLEANLINE, POSZ, INSZ. 
* 
*         USES   LIN. 
* 
*         NOTE   ALGORITHM ASSUMES CURSOR INDICATES FILE EXTENSION
*                ANYTIME IT IS ON A TEXT ROW BUT ALIGNGOOD IS OFF AND 
*                THE FILE POSITION EXCEEDS BOTF(SPLITFILE[CURSPLIT]). 
# 
    IF NOT ALIGNGOOD THEN 
      BEGIN 
      IF ROWTYPE[YCURSOR] EQ ROWST"TEXT" THEN 
        BEGIN 
        CURSPLIT=ROWSPLIT[YCURSOR]; 
        CURSPLIT=MIN(MAX(CURSPLIT,1),2);
        IF YTOL(YCURSOR,CURSPLIT) GQ BOTF(SPLITFILE[CURSPLIT]) THEN 
          BEGIN 
          CLEANLINE;
          CURF(CURFILE)=CURRENT;
          POSZ(BOTF(SPLITFILE[CURSPLIT])-1);
          LINE[0]=NULLIN; 
          HARDFN=FALSE; 
          FOR SCRNPT4=LTOY(CURRENT,CURSPLIT)+1 STEP 1 
            UNTIL YCURSOR DO INSZ;
          IF NOT PROMPTING THEN ALIGNGOOD=TRUE; 
          CURFILE=SPLITFILE[CURSPLIT];
          END 
        END 
      END 
    IOEND                      # OF EXTEND        # 
  
  PROC CLEANLINE; 
    IOBEGIN(CLEANLINE)
# 
**        CLEANLINE - CLEAN UP LINE BUFFER AND FILE BEFORE MOVING.
* 
*         ENTRY  LINECHANGED - LINE BUFFER RECENTLY ALTERED.
*                LIN - THE LINE BUFFER. 
*                CURRENT - WHERE WE ARE IN THE FILE.
*                SOFTTAB - TRUE IF ANY CHANGE WAS SOFT-TAB OVERSTRIKE.
*                CURFILE - WHICH FILE BRACKET WE ARE IN.
*                CURSPLIT - WHICH SCREEN BRACKET WE ARE IN. 
*                NUMBERED[CURFILE] - SEQUENCING MODE FOR THIS FILE. 
*                WIDTH - USERS LINE WIDTH THRESHHOLD. 
* 
*         EXIT   ANY CHANGES TO LINE BUFFER ARE IN WORKFILE.
*                SEQUENCE NUMBERS ADJUSTED TO NUMWIDTH. 
*                OUT-OF-SEQUENCE NUMBERS BLANKED OUT. 
*                LINECHANGED, SOFTTAB - CLEARED.
*                ERRSTRING - POSSIBLE WIDE LINE WARNING.
*                ROWPAINT[THIS LINE] - POSSIBLY TRUE. 
* 
*         MACROS SETCHAR, LTOY. 
* 
*         CALLS  COPYLIN, DOTAB, TRIMPAD, REPX, GETLNUM, SETLNUM, 
*                PUSH, BAKNUM, POP, FWDNUM, LENGTH. 
* 
*         USES   WIDTHFOUND, LINENO, SCRNPT2, SCRNPT3.
# 
    IF LINECHANGED THEN 
      BEGIN 
      LINECHANGED=FALSE;
      IF SOFTTAB THEN 
        BEGIN 
        SOFTTAB=FALSE;
        COPYLIN(LIN,TTYLIN);
        DOTAB(NUMWIDBLK,NUMWIDBLK,NUMWIDBLK); 
        COPYLIN(TTYLIN,LIN);
        END 
      TRIMPAD;
      REPX; 
      IF NUMBERED[CURFILE] NQ 0 THEN
        BEGIN                 # ASSURE ASCENDING NUMBERS    # 
        GETLNUM;             # SEE IF ANY NUMBER TO FIX    #
        IF WIDTHFOUND NQ 0 THEN 
          BEGIN 
          IF WIDTHFOUND NQ NUMWIDTH THEN  # NOT STANDARD   #
            BEGIN 
            SETLNUM;
            HARDFN=FALSE; 
            REPX; 
            END 
          ELSE                       # DIGITS OK BUT CHECK BLANK #
            BEGIN 
            GETCHAR(LINE,NUMWIDTH,SCRNPT2); 
            IF BLANKS NQ 0 AND SCRNPT2 NQ CBLANK THEN 
              BEGIN 
              RSHIFT(LIN,NUMWIDTH,1); 
              SETCHAR(LINE,NUMWIDTH,CBLANK);
              END 
            END 
          SCRNPT2=LINENO;    # VERIFY BOUNDARIES #
          PUSH; 
          BAKNUM; 
          POP;
          SCRNPT3=LINENO; 
          PUSH; 
          FWDNUM; 
          POP;
          IF SCRNPT2 LQ SCRNPT3 OR SCRNPT2 GQ LINENO THEN 
            BEGIN             # NOT ASCEND SO BLANKOUT      # 
            FOR SCRNPT2=1 STEP 1 UNTIL NUMWIDTH 
              DO SETCHAR(LINE,SCRNPT2-1,CBLANK);
            END 
          HARDFN=FALSE; 
          REPX; 
          END 
        END 
      IF LENGTH(LIN) GR WIDTH+NUMWIDBLK AND ERRSTRING EQ " $" THEN
        BEGIN 
        ERRSTRING="WIDE LINE$"; 
        END 
      END 
    IOEND                     # OF CLEANLINE      # 
  
  
  PROC REJECT;
# TITLE REJECT - REJECT CHANGE. # 
  
    BEGIN  # REJECT # 
  
# 
**        REJECT - REJECT CHANGE. 
* 
*         A KEYBOARD CHANGE WAS MADE ON A ROW THAT IN NOT ALLOWED.
*         FLAG THE ROW FOR REPAINT AND IF ITS A TITLE ROW, INDICATE 
*         A TOTAL REPAINT.
* 
*         PROC REJECT 
# 
  
    ROWPAINT[YCURSOR]=TRUE; 
    IF ROWTYPE[YCURSOR] EQ ROWST"TITLE" THEN
      BEGIN 
      IF ROWSPLIT[YCURSOR] EQ 1 THEN TITLE1LINE[0]=NULLIN;
      ELSE TITLE2LINE[0]=NULLIN;
      END 
    IF ROWTYPE[YCURSOR] EQ ROWST"TITLE" 
      OR ROWTYPE[YCURSOR] EQ ROWST"LABEL" 
      OR ROWTYPE[YCURSOR] EQ ROWST"RESPONSE" THEN 
      BEGIN 
      ERRSTRING = "CHANGES OUTSIDE OF TEXT AREA DISCARDED$";
      END 
  
    END  # REJECT # 
  
  
  PROC MOVETEXT(TEXTLIN,OFFSET,FENCE);
    BEGIN 
# 
**        MOVETEXT - UPDATE LINE BUFFER WITH OVERSTRIKE.
* 
*         ENTRY  TEXTLIN - WHICH LINE BUFFER TO UPDATE. 
*                XCURSOR, OFFSET - WHERE TO UPDATE. 
*                CURSPLIT, YCURSOR - WHERE WE ARE.
*                FENCE - RIGHT HAND BOUNDARY FOR CHANGES. 
*                ASCII[CURFILE] - INDICATES CASE SUPPRESSION. 
*                TABCHAR - SOFT TAB CHARACTER.
*                VTCHAR - THE CHARACTER TO OVERSTRIKE.
* 
*         EXIT   THE CHARACTER IS IN PLACE IF POSSIBLE. 
*                SOFTTAB - POSSIBLY TRUE. 
*                ROWPAINT[YCURSOR] - POSSIBLY TRUE. 
* 
*         MACROS SETCHAR. 
* 
*         CALLS  EXTENDC, DSPLCOD.
# 
  
    ARRAY TEXTLIN[0:99];
      BEGIN # ARRAY TEXTLIN # 
      ITEM TEXTLINE   I;             # LINE BUFFER TO UPDATE #
      END # ARRAY TEXTLIN # 
  
    ITEM OFFSET     I;               # COLUMN OFFSET #
    ITEM FENCE      I;               # RIGHT SIDE BOUNDARY #
    ITEM TMP1       I;               # TEMPORARY STORAGE #
    ITEM TMP2       I;               # TEMPORARY STORAGE #
  
    TMP2=XCURSOR+OFFSET;
    IF TMP2 GQ FENCE THEN RETURN; 
    EXTENDC(TEXTLIN,TMP2);
    TMP1=XLTXPINT[VTCHAR];
    IF ASCII[CURFILE] LQ 1 THEN      # SUPPRESS LOWER CASE #
      BEGIN 
      # NEXT CODE IS DEPENDENT ON PRECISE VALUES OF INTERNAL CHARSET #
      CONTROL IFNQ CLEFTCURL,O"133"; DEFERROR; CONTROL FI;
      CONTROL IFNQ CVERTICAL,O"134"; DEFERROR; CONTROL FI;
      CONTROL IFNQ CRITECURL,O"135"; DEFERROR; CONTROL FI;
      CONTROL IFNQ CTILDE,O"136"; DEFERROR; CONTROL FI; 
      CONTROL IFNQ CGRAVE,O"100"; DEFERROR; CONTROL FI; 
      CONTROL IFNQ CCOLON,O"000"; DEFERROR; CONTROL FI; 
      # ISSUE WARNING FOR NON-EXISTENT DISPLAY CODE CHARACTERS #
      IF (TMP1 GQ O"133" AND TMP1 LQ O"136")
        OR (TMP1 EQ O"100") THEN ROWPAINT[YCURSOR]=TRUE;
      IF (B<00,01>MEM[CSMR] EQ 0) 
        AND (TMP1 EQ O"000") THEN ROWPAINT[YCURSOR]=TRUE; 
      DSPLCOD(TMP1);                 # SUPPRESS LOWER CASE #
      END 
    SETCHAR(TEXTLINE,TMP2,TMP1);
    IF TMP1 EQ TABCHAR THEN 
      BEGIN 
      SOFTTAB=TRUE; 
      ROWPAINT[YCURSOR]=TRUE; 
      END 
    END  # MOVETEXT # 
  
  
  PROC INSTEXT(TEXTLIN,OFFSET,FENCE); 
    BEGIN 
# 
**        INSTEXT - OPEN UP SPACE FOR CHARACTER INSERTION.
* 
*         ENTRY  SAME AS MOVETEXT ROUTINE.
* 
*         EXIT   THE CHARACTER SPACE IS OPENED UP.
* 
*         MACROS SETCHAR. 
* 
*         CALLS  RSHIFT, LSHIFT.
# 
  
    ARRAY TEXTLIN[0:99];
      BEGIN # ARRAY TEXTLIN # 
      ITEM TEXTLINE   I;             # LINE BUFFER TO UPDATE #
      END # ARRAY TEXTLIN # 
  
    ITEM OFFSET     I;               # COLUMN OFFSET #
    ITEM FENCE      I;               # RIGHT SIDE BOUNDARY #
    ITEM TMP1       I;               # TEMPORARY STORAGE #
    ITEM TMP2       I;               # TEMPORARY STORAGE #
  
    TMP1=XCURSOR+OFFSET;
    IF TMP1 GQ FENCE THEN RETURN; 
    RSHIFT(TEXTLIN,TMP1,1); 
    TMP2=XLTXPINT[VTCHAR];
    IF ASCII[CURFILE] LQ 1 THEN      # SUPPRESS LOWER CASE #
      BEGIN 
      # NEXT CODE IS DEPENDENT ON PRECISE VALUES OF INTERNAL CHARSET #
      CONTROL IFNQ CLEFTCURL,O"133"; DEFERROR; CONTROL FI;
      CONTROL IFNQ CVERTICAL,O"134"; DEFERROR; CONTROL FI;
      CONTROL IFNQ CRITECURL,O"135"; DEFERROR; CONTROL FI;
      CONTROL IFNQ CTILDE,O"136"; DEFERROR; CONTROL FI; 
      CONTROL IFNQ CGRAVE,O"100"; DEFERROR; CONTROL FI; 
      CONTROL IFNQ CCOLON,O"000"; DEFERROR; CONTROL FI; 
      # ISSUE WARNING FOR NON-EXISTENT DISPLAY CODE CHARACTERS #
      IF (TMP2 GQ O"133" AND TMP2 LQ O"136")
        OR (TMP2 EQ O"100") THEN ROWPAINT[YCURSOR]=TRUE;
      IF (B<00,01>MEM[CSMR] EQ 0) 
        AND (TMP2 EQ O"000") THEN ROWPAINT[YCURSOR]=TRUE; 
      DSPLCOD(TMP2);                 # SUPPRESS LOWER CASE #
      END 
    SETCHAR(TEXTLINE,TMP1,TMP2);
    IF TMP2 EQ TABCHAR THEN 
      BEGIN 
      SOFTTAB=TRUE; 
      ROWPAINT[YCURSOR]=TRUE; 
      END 
    IF FENCE LS BUFCM1 THEN 
      BEGIN 
      LSHIFT(TEXTLIN,EDITFIELD+1,1);
      END 
    END  # INSTEXT #
  
  
  PROC DELTEXT(TEXTLIN,OFFSET,FENCE); 
    BEGIN 
# 
**        DELTEXT - DELETE ONE CHARACTER. 
* 
*         ENTRY  SAME AS MOVETEXT.
* 
*         EXIT   TEXT SHIFTED TO CLOSEUP ONE PLACE. 
* 
*         MACROS SETCHAR. 
* 
*         CALLS  LSHIFT, RSHIFT.
# 
  
    ARRAY TEXTLIN[0:99];
      BEGIN # ARRAY TEXTLIN # 
      ITEM TEXTLINE   I;             # LINE BUFFER TO UPDATE #
      END # ARRAY TEXTLIN # 
  
    ITEM OFFSET     I;               # COLUMN OFFSET #
    ITEM FENCE      I;               # RIGHT SIDE BOUNDARY #
    ITEM TMP1       I;               # TEMPORARY STORAGE #
  
    TMP1=XCURSOR+OFFSET;
    IF TMP1 GQ FENCE THEN RETURN; 
    LSHIFT(TEXTLIN,TMP1+1,1); 
    IF FENCE LS BUFCM1 THEN 
      BEGIN 
      RSHIFT(TEXTLIN,EDITFIELD-1,1);
      SETCHAR(TEXTLINE,EDITFIELD-1,CBLANK); 
      END 
    END  # DELTEXT #
  
  
  PROC DSERRJMP(STR);        # DOSCREEN ERROR JUMP         #
    IOBEGIN(DSERRJMP) 
# 
**        DSERRJMP - ERROR JUMP FROM DOSCREEN.
* 
*         ENTRY  STR - ERROR MESSAGE. 
*                PROMPTING - NORMAL OR SPECIAL DISPLAY. 
*                COMMANDROW - SETUP.
* 
*         EXIT   VIA ERRJUMP. 
*                CMDLIN - NULLED OUT. 
*                ERRSTRING - CONTAINS MESSAGE.
*                TOKENPOS - MINUS ONE FOR ERRJUMP.
*                ROWPAINT[COMMANDROW] - TRUE. 
*                ROWPAINT[ALL] - POSSIBLY TRUE. 
* 
*         CALLS  PAINTALL, VDTBEL, VDTDRN, ERRJUMP. 
* 
*         NOTE   THIS ROUTINE UNCONDITIONALLY USES ERRJUMP, THUS
*                CONTROL WILL NEVER RETURN TO THE CALLER.  DSERRJMP 
*                IS THE ONLY WAY TO CALL ERRJUMP FROM DOSCREEN OR 
*                ANY OF ITS INTERNAL ROUTINES.
# 
    ITEM STR C(40); 
    ERRSTRING=STR;
    ROWPAINT[COMMANDROW]=TRUE;
    IF PROMPTING THEN PAINTALL; 
    VDTBEL; 
    VDTDRN;                 # ASSURE INPUT BUFFER CLEAN   # 
    TOKENPOS=-1;             # ASSURE OLD CURSOR POSITION  #
    CMDLINE[0]=NULLIN;
    ERRJUMP(ERRSTRING);      # CONTROL DOES NOT RETURN     #
    IOEND                     # OF DSERRJMP       # 
  
  PROC SETCMD(CMD); 
    BEGIN 
# 
**        SETCMD - ADD CHARACTER STRING TO COMMAND BUFFER.
* 
*         ENTRY  CMD - STRING TO BE ADDED, 10 CHARS IN DISPLAY CODE.
*                CMDLIN - ANY EXISTING COMMAND CONTENT. (INTERNAL CODE) 
* 
*         EXIT   CMDLIN - UPDATED.
* 
*         MACROS SETCHAR. 
* 
*         CALLS  LENGTH.
* 
*         USES   SCRNPT3, SCRNPT4, SCRNPT5. 
# 
    ITEM CMD C(10); 
    SCRNPT4=LENGTH(CMDLIN); 
    IF SCRNPT4+10 LS BUFCM1 THEN
      BEGIN 
      SETCHAR(CMDLINE,SCRNPT4,CSEMCOLON); 
      FOR SCRNPT5=0 STEP 1 UNTIL 9 DO 
        BEGIN 
        SCRNPT3=XLTDSPINT[C<SCRNPT5,1>CMD]; 
        SETCHAR(CMDLINE,SCRNPT4+1+SCRNPT5,SCRNPT3); 
        END 
      SETCHAR(CMDLINE,SCRNPT4+11,CENDLINE); 
      END 
    END                       # OF SETCMD         # 
  
  
  PROC ADDTOCMD;
    BEGIN 
    # ADD TEXT FROM KEYLINE TO CMDLINE #
    SCRNPT3=LENGTH(CMDLIN); 
    SCRNPT2=LENGTH(KEYLIN); 
    IF SCRNPT3+SCRNPT2 LS BUFCM1 THEN 
      BEGIN 
      SETCHAR(CMDLINE,SCRNPT3,CSEMCOLON); 
      FOR SCRNPT4=0 STEP 1 UNTIL SCRNPT2 DO 
        BEGIN 
        GETCHAR(KEYLINE,SCRNPT4,SCRNPT5); 
        SETCHAR(CMDLINE,SCRNPT3+SCRNPT4+1,SCRNPT5); 
        IF (SCRNPT5 EQ CAMPER) AND (NOT PROMPTING)
          AND (EXPANDAT LS 0) THEN EXPANDAT=SCRNPT3+SCRNPT4+1;
        END 
      END 
    END  # ADDTOCMD # 
  
  
  PROC INCRCURSOR;
# TITLE INCRCURSOR - INCREMENT CURSOR. #
  
    BEGIN  # INCRCURSOR # 
  
# 
**        INCRCURSOR - INCREMENT CURSOR.
* 
*         EXIT   XCURSOR - ZERO.
*                YCURSOR - USERS CURSOR OR ONE PLACE BEYOND.
* 
*         CALLS  SETCURSOR. 
# 
  
    SETCURSOR;
    XCURSOR=0;
    IF ROWTYPE[YCURSOR] EQ ROWST"TEXT" THEN YCURSOR=YCURSOR+1;
  
    END  # INCRCURSOR # 
PAGE                         # START OF DOSCREEN MAIN CODE #
  
  
  SCREENLIMIT=0;
  COMPUTEDPOS=FALSE;
  VDTEOO;                    # ISSUE INPUT CONTROL PROMPT  #
  VDTPPI;                    # GET INPUT, VERIFY XPARENT   #
  VDTBOO;                    # START NEW OUTPUT CYCLE      #
  IF VTORDN NQ 0 THEN 
    BEGIN                    # IF SOME INPUT WAS LOST      #
    VDTBEL; 
    TOKENPOS=0; 
    SETCMD("SS"); 
    ERRSTRING="PLEASE RE-ENTER INPUT$"; 
    GOTO DSEOI;              # SIMULATE *ENTER*            #
    END 
  XCURSOR=0;
  
  FIRSTEVENT=TRUE;
  GOTO DSLOOP2; 
  
# 
      SCREEN ROUTINES RETURN BASED UPON WHERE THEY WOULD LIKE 
      THE CURSOR IF <EOL> WERE ENTERED IMMEDIATELY AFTER THE
      ROUTINE.  THE CHOICES ARE 
  
         DSLOOP:  LEAVE THE CURSOR WHERE IT IS. 
         DSX0Y1:  SET X TO ZERO, INCREMENT Y IF IN VALID TEXT.
                  LEAVE Y WHERE IT IS IF CANNOT INCREMENT.
# 
  
DSX0Y1: 
  INCRCURSOR; 
DSLOOP: 
  FIRSTEVENT=FALSE; 
DSLOOP2:  
  OLDVTXCURS=VTXCUR;
  OLDVTYCURS=VTYCUR;
  VDTIINP;
DSLOOP3:  
  IF SCREENLIMIT LS 2 THEN
    BEGIN 
    IF NEEDCURSOR[VTORDN] THEN SETCURSOR; 
    IF NEEDALIGN[VTORDN] THEN ALIGN;
    IF NEEDCLEAN[VTORDN] THEN CLEANLINE;
    END 
  IF NEEDLIMIT[VTORDN] NQ 0 THEN
    BEGIN 
    IF NEEDLIMIT[VTORDN] LS SCREENLIMIT AND SCREENLIMIT NQ 0 THEN 
      BEGIN 
      PAINTALL; 
      VTINCR = 0;                    # DISABLE CURSOR ADVANCE # 
      DSERRJMP("RETURN MUST FOLLOW FUNCTION KEY$"); 
      END 
    SCREENLIMIT=NEEDLIMIT[VTORDN];
    END 
  IF NEEDUNLOCK[VTORDN] AND ROWTYPE[YCURSOR] EQ ROWST"TEXT" THEN
    BEGIN 
    IF LOCKED[CURFILE] NQ 0 THEN
      BEGIN 
      ROWPAINT[YCURSOR]=TRUE;        # CURRENT LINE IS SPOILED #
      IF VTORDN EQ SCREENST"INSL" OR VTORDN EQ SCREENST"DELL" THEN
        BEGIN                        # LOWER LINES ARE SPOILED #
        PAINTSPLIT;                  # AT LEAST TILL FIELD PROTECT #
        IF NOT TABVTPROTM[0] THEN PAINTREST(YCURSOR); 
        END 
      DSERRJMP("CANNOT CHANGE READ-ONLY FILE$");
      END 
    END 
  HARDFN=TRUE;
  GOTO SCREENSW[VTORDN];
  
DSUP: 
DSDOWN: 
DSRET:  
DSNOOP: 
DSCOORD:  
DSPROTECT:  
  GOTO DSLOOP;
  
  
DSPOS:  
DSRESET:  
  GOTO DSBAD; 
  
DSEOI:  
  # NOTE THAT AN EOI VDT EVENT IS NOT TAGGED FOR EITHER CURSOR  # 
  # SETTING OR FILE POSITION ALIGNMENT.  THE DSEOI SECTION DOES # 
  # THIS MANUALLY TO ALLOW FOR REACTION TO VARYING CONDITIONS.  # 
  CLEANLINE;
  IF SCREENLIMIT LS 2 THEN
    BEGIN 
    IF COMPUTEDPOS THEN SETCURSOR;
    ALIGN;
    INCRCURSOR; 
    IF LENGTH(CMDLIN) EQ 0 AND YCURSOR EQ VTYCUR+1 AND
      VTYCUR EQ TITLEROW[CURSPLIT]+NUMROWS[CURSPLIT] AND
      NOT PROMPTING THEN
      BEGIN                          # IF AUTO HALF PAGE FORWARD #
      TOPS(CURSPLIT)=BOTS(CURSPLIT)-NUMROWS[CURSPLIT]/2;
      SETTOPS(CURSPLIT);
      XCURSOR=0;
      YCURSOR=BOTS(CURSPLIT); 
      YCURSOR=LTOY(YCURSOR,CURSPLIT); 
      SETBOTS(CURSPLIT);
      PAINTSPLIT; 
      END 
    ALIGN;
    END 
  HARDFN = FALSE;                    # CLEAR HARD FUNCTION PRESSED #
  VDTDRN;                            # ASSURE CLEAN INPUT BUFFER #
  IF FIRSTEVENT THEN CMDLINE[0]=NULLIN; 
  IF AUTOINDENT THEN
    BEGIN                            # IF SET JUMP ENABLED #
    IF XCURSOR EQ 0 AND YCURSOR NQ COMMANDROW 
      AND LENGTH(CMDLIN) EQ 0 THEN
      BEGIN                          # IF REASONABLE TO DO #
      SCRNPT3 = 0;
      SCRNPT4 = 0;
      IF NOTEXT THEN
        BEGIN                        # IF CURRENT LINE IS EMPTY # 
        SCRNPT4 = 1;                 # CHECK PREVIOUS LINE #
        BAKZ; 
        END 
      IF NOT NOTEXT THEN
        BEGIN                        # IF LINE IS NOT EMPTY # 
        GETCHAR(LINE,XSHIFT[CURSPLIT],SCRNPT2); 
        WHYLE SCRNPT2 EQ CBLANK DO
          BEGIN                      # IF LEADING BLANK(S) #
          SCRNPT3 = SCRNPT3 + 1;
          GETCHAR(LINE,XSHIFT[CURSPLIT]+SCRNPT3,SCRNPT2); 
          END 
        END 
      IF SCRNPT4 EQ 1 THEN FWDZ;     # RESET IF NECESSARY # 
      XCURSOR = SCRNPT3;
      END 
    END 
  IORET 
  
DSHOME: 
  XCURSOR=VTOXPOS;
  YCURSOR=VTOYPOS;
  IF ROWTYPE[YCURSOR] EQ ROWST"TEXT" OR ROWTYPE[YCURSOR]
    EQ ROWST"TITLE" THEN CURSPLIT=ROWSPLIT[YCURSOR];
  CURCURSOR=XCURSOR+XSHIFT[CURSPLIT]; 
  ALIGN;
  GOTO DSLOOP;
  
DSCLREOL: 
  IF ROWTYPE[YCURSOR] EQ ROWST"COMMAND" THEN
    BEGIN 
    SETCHAR(CMDLINE,XCURSOR,CENDLINE);
    IF XCURSOR EQ 0 THEN ROWPAINT[COMMANDROW] = FALSE;
    END 
  ELSE IF ALIGNGOOD THEN
    BEGIN 
    FOR SCRNPT1=XCURSOR+XSHIFT[CURSPLIT] STEP 1 
      UNTIL EDITFIELD-1 DO SETCHAR(LINE,SCRNPT1,CBLANK);
    SETCHAR(LINE,BUFCHAR,CENDLINE); 
    TRIMPAD;
    LINECHANGED=TRUE; 
    END 
  ELSE REJECT;
  GOTO DSX0Y1;
  
DSCLRPAG:  DSCLRUNP:  DSCLREOP: 
  PAINTALL; 
  SETCMD("SETSCR"); 
  GOTO DSLOOP;
  
DSCHAR: 
  IF YCURSOR EQ COMMANDROW THEN 
    BEGIN 
    MOVETEXT(CMDLIN,0,BUFCM1);
    ROWPAINT[COMMANDROW] = TRUE;
    END 
  ELSE
    BEGIN 
    EXTEND; 
    IF ALIGNGOOD THEN 
      BEGIN 
      SCRNPT1=LENGTH(LIN);
      MOVETEXT(LIN,XSHIFT[CURSPLIT],EDITFIELD); 
      LINECHANGED=TRUE; 
      END 
    ELSE REJECT;
    END 
  GOTO DSX0Y1;
  
DSINSC: 
  IF YCURSOR EQ COMMANDROW THEN 
    BEGIN                            # IF COMMANDROW #
    ROWPAINT[COMMANDROW] = TRUE;
    INSTEXT(CMDLIN,0,BUFCM1); 
    END 
  ELSE
    BEGIN 
    EXTEND; 
    IF ALIGNGOOD THEN 
      BEGIN 
      INSTEXT(LIN,XSHIFT[CURSPLIT],EDITFIELD);
      IF CURRENT EQ REGLINE[MARKREG] AND VTXCUR LS MRKCHAR[0] THEN
        MRKCHAR[0] = MRKCHAR[0] + 1; # IF INSERT BEFORE FIRST MARK #
      IF CURRENT EQ REGLINE[MARKREG+1] AND VTXCUR LQ MRKCHAR[1] THEN
        MRKCHAR[1] = MRKCHAR[1] + 1; # IF INSERT BEFORE LAST MARK # 
      LINECHANGED=TRUE; 
      END 
    ELSE REJECT;
    END 
  GOTO DSX0Y1;
  
DSDELC: 
  IF YCURSOR EQ COMMANDROW THEN 
    BEGIN 
    DELTEXT(CMDLIN,0,BUFCM1); 
    IF LENGTH(CMDLIN) EQ 0 THEN ROWPAINT[COMMANDROW] = FALSE; 
    END 
  ELSE IF ALIGNGOOD THEN
    BEGIN 
    IF HARDFN AND LENGTH(LIN) GR XSHIFT[CURSPLIT]+USRNUMCOL 
      THEN ROWPAINT[YCURSOR]=TRUE;
    DELTEXT(LIN,XSHIFT[CURSPLIT],EDITFIELD);
    IF CURRENT EQ REGLINE[MARKREG] AND VTXCUR LS MRKCHAR[0] THEN
      MRKCHAR[0] = MRKCHAR[0] - 1;   # IF DELETE BEFORE FIRST MARK #
    IF CURRENT EQ REGLINE[MARKREG+1] AND VTXCUR LQ MRKCHAR[1] THEN
      BEGIN                          # IF DELETE BEFORE LAST MARK # 
      MRKCHAR[1] = MRKCHAR[1] - 1;
      IF REGLINE[MARKREG] LS CURRENT THEN 
        BEGIN                        # IF MORE THAN ONE MARKED LINE # 
        IF MRKCHAR[1] LS 0 THEN 
          BEGIN                      # IF NO MARKS LEFT ON LAST LINE #
          REGLINE[MARKREG+1] = CURRENT - 1; 
          END 
        END 
      ELSE
        BEGIN                        # IF ONLY ONE MARKED LINE #
        IF MRKCHAR[1] LS MRKCHAR[0] OR MRKCHAR[1] LS 0 THEN 
          KILLMARKS = TRUE;          # IF NO MARKS LEFT # 
        END 
      END 
    LINECHANGED=TRUE; 
    END 
  ELSE REJECT;
  GOTO DSX0Y1;
  
DSINSL: 
  EXTEND; 
  IF ALIGNGOOD THEN 
    BEGIN 
    IF CURRENT NQ TOPS(CURSPLIT) THEN BAKZ; 
    LINE[0]=NULLIN; 
    HARDFN = TRUE;
    INSX; 
    END 
  ELSE
    BEGIN 
    REJECT; 
    IF HARDFN AND NOT TABVTPROTM[0] THEN PAINTREST(YCURSOR);
    END 
  GOTO DSX0Y1;
  
DSLEFT: 
  IF TABVTPROTM[0] THEN 
    BEGIN 
    IF ROWTYPE[VTYCUR] EQ ROWST"TITLE"
      OR (ROWTYPE[VTYCUR] EQ ROWST"LABEL" AND VTXCUR LS FKEYLEN) THEN 
      BEGIN                          # IF CURSOR IN PROTECTED AREA #
      VDTCOR(VTYCUR-1,VTXMAX);       # CURSOR IS UP ONE LINE #
      END 
    END 
  GOTO DSLOOP;
  
DSRIGHT:  
  IF TABVTPROTM[0] THEN 
    BEGIN 
    IF ROWTYPE[VTYCUR] EQ ROWST"TITLE" THEN 
      BEGIN                          # IF ON TITLE LINE # 
      VDTCOR(VTYCUR+1,0);            # CURSOR ONE LINE DOWN # 
      END 
    ELSE IF ROWTYPE[VTYCUR] EQ ROWST"LABEL" AND VTXCUR LS FKEYLEN THEN
      BEGIN                          # IF ON FUNCTION KEY LABEL LINE #
      VDTCOR(VTYCUR,FKEYLEN);        # CURSOR IS PAST LABELS #
      END 
    END 
  GOTO DSLOOP;
  
DSCLRALL: 
  VDTSTS(0);                         # RESTORE COLUMN 1 TAB STOP #
  FOR SCRNPT2=1 STEP 1 UNTIL TABWORDS DO
    BEGIN                            # MARK ALL OTHER TABS CLEAR #
    TABVCTWRD[SCRNPT2] = 0; 
    END 
  GOTO DSLOOP;
  
DSCLRTAB: 
DSSETTAB: 
  FOR SCRNPT3=1 STEP 1 UNTIL USERTABS DO
    BEGIN 
    SCRNPT2 = TABFN(SCRNPT3); 
    IF SCRNPT2 GQ VTXCUR OR SCRNPT2 EQ 0 THEN 
      BEGIN                          # IF FOUND THE SPOT #
      IF VTORDN EQ SCREENST"SETTAB" THEN
        BEGIN                        # IF SETTING TAB STOP #
        IF SCRNPT2 NQ VTXCUR AND VTXCUR GR 0 THEN 
          BEGIN                      # IF TAB STOP NOT ALREADY SET #
          SCRNPT4 = VTXCUR; 
          FOR SCRNPT3 = SCRNPT3-1 STEP 1
            WHILE SCRNPT3 LS USERTABS AND SCRNPT4 GR 0 DO 
            BEGIN 
            SCRNPT2 = SCRNPT4;
            SCRNPT4 = TABFN(SCRNPT3+1); 
            SCRNPT5 = SCRNPT3/7;
            SCRNPT6 = MOD(SCRNPT3,7); 
            B<SCRNPT6*8,8>TABVCTWRD[SCRNPT5+1] = SCRNPT2; 
            END 
          END 
        END 
      ELSE
        BEGIN                        # IF CLEARING TAB STOP # 
        IF VTXCUR GR 0 THEN 
          BEGIN                      # IF NOT IN COLUMN 1 # 
          IF SCRNPT2 EQ VTXCUR THEN 
            BEGIN                    # IF TAB STOP ACTUALLY SET # 
            FOR SCRNPT3 = SCRNPT3 STEP 1
              WHILE SCRNPT3 LS USERTABS AND SCRNPT2 GR 0 DO 
              BEGIN                  # REMOVE THE TAB STOP #
              SCRNPT2 = TABFN(SCRNPT3+1); 
              SCRNPT5 = (SCRNPT3-1)/7;
              SCRNPT6 = MOD(SCRNPT3-1,7); 
              B<SCRNPT6*8,8>TABVCTWRD[SCRNPT5+1] = SCRNPT2; 
              END 
            END 
          END 
        ELSE
          BEGIN                      # IF COLUMN 1 TAB STOP CLEARED # 
          VDTSTS(0);                 # RESTORE COLUMN 1 TAB STOP #
          END 
        END 
      GOTO DSLOOP;
      END 
    END 
  GOTO DSLOOP;
  
DSFTAB: 
  SCRNPT4 = TABFN(1); 
  FOR SCRNPT3=1 STEP 1 UNTIL USERTABS DO
    BEGIN 
    SCRNPT2 = TABFN(SCRNPT3); 
    IF SCRNPT2 LS SCRNPT4 OR SCRNPT2 GR VTXMAX THEN 
      BEGIN                          # WRAPAROUND # 
      GOTO DSFTAB2; 
      END 
    IF SCRNPT2 GR VTXCUR THEN 
      BEGIN                          # THIS IS IT # 
      SCRNPT4 = VTYCUR; 
      GOTO DSFTAB3; 
      END 
    END 
DSFTAB2:  
  IF TABUNDWFLN[0] THEN GOTO DSLOOP; # IF FORWARD TABS DO NOT WRAP #
  IF ROWTYPE[VTYCUR] EQ ROWST"LABEL"
    AND TABVTPROTM[0] 
    AND VTXCUR LS FKEYLEN THEN
    BEGIN                            # IF WITHIN PROTECTED LABEL LINE # 
    VDTCOR(VTYCUR,FKEYLEN); 
    GOTO DSLOOP;
    END 
  SCRNPT2 = 0;
  SCRNPT4 = VTYCUR + 1; 
  IF SCRNPT4 GR VTYMAX THEN SCRNPT4 = 0;
DSFTAB3:  
  IF TABVTPROTM[0] THEN 
    BEGIN                            # IF EDITOR USES PROTECT # 
    IF ROWTYPE[SCRNPT4] EQ ROWST"TITLE" THEN
      BEGIN                          # IF PROTECTED TITLE LINE #
      SCRNPT4 = SCRNPT4 + 1;         # ADVANCE PAST TITLE LINE #
      SCRNPT2 = 0;
      END 
    ELSE IF ROWTYPE[SCRNPT4] EQ ROWST"LABEL"
      AND SCRNPT2 LS FKEYLEN THEN 
      BEGIN                          # IF IN PROTECTED LABEL AREA # 
      SCRNPT2 = FKEYLEN;
      END 
    END 
  VDTCOR(SCRNPT4,SCRNPT2);
  GOTO DSLOOP;
  
DSBTAB: 
  IF TABUNDWBLN[0] AND VTXCUR EQ 0 THEN GOTO DSLOOP;  # IF NO WRAP #
  SCRNPT1=-1; 
  SCRNPT2=TABFN(TABSTOPS);
  FOR SCRNPT3=USERTABS STEP -1 UNTIL 1 DO 
    BEGIN 
    SCRNPT4 = TABFN(SCRNPT3); 
    IF SCRNPT1 LS 0 THEN
      BEGIN                          # IF LAST VALID TAB NOT FOUND #
      IF SCRNPT4 LQ SCRNPT2 OR SCRNPT4 GR VTXMAX THEN TEST SCRNPT3; 
      SCRNPT1 = SCRNPT4;
      END 
    IF SCRNPT4 LS VTXCUR THEN 
      BEGIN                          # IF LEFT OF CURRENT POSITION #
      IF TABVTPROTM[0] THEN 
        BEGIN                        # IF EDITOR USES PROTECT # 
        IF ROWTYPE[VTYCUR] EQ ROWST"TITLE" THEN GOTO DSBTAB2; 
        IF ROWTYPE[VTYCUR] EQ ROWST"LABEL" THEN 
          BEGIN                      # IF PROTECTED LABEL LINE #
          IF VTXCUR LQ FKEYLEN THEN GOTO DSBTAB2; 
          SCRNPT4 = MAX(SCRNPT4,FKEYLEN); 
          END 
        END 
      VDTCOR(VTYCUR,SCRNPT4); 
      GOTO DSLOOP;
      END 
    END 
  IF VTXCUR GR 0
    AND NOT (TABVTPROTM[0] AND ROWTYPE[VTYCUR] EQ ROWST"LABEL") THEN
    BEGIN 
    VDTCOR(VTYCUR,0); 
    GOTO DSLOOP;
    END 
DSBTAB2:  
  SCRNPT1=MAX(SCRNPT1,0); 
  SCRNPT4=VTYCUR-1; 
  IF SCRNPT4 LS 0 THEN SCRNPT4=VTYMAX;
  IF TABVTPROTM[0] THEN 
    BEGIN                            # IF EDITOR USES PROTECT # 
    IF ROWTYPE[SCRNPT4] EQ ROWST"TITLE" THEN
      BEGIN                          # IF PROTECTED TITLE LINE #
      SCRNPT4 = SCRNPT4 - 1;         # BACK UP PAST TITLE LINE #
      END 
    ELSE IF ROWTYPE[SCRNPT4] EQ ROWST"LABEL" THEN 
      BEGIN                          # IF PROTECTED LABEL LINE #
      SCRNPT1 = MAX(SCRNPT1,FKEYLEN); 
      END 
    END 
  VDTCOR(SCRNPT4,SCRNPT1);
  GOTO DSLOOP;
  
DSDELL: 
  IF ALIGNGOOD THEN 
    BEGIN 
    IF CURRENT LS BOTS(CURSPLIT) THEN DELX; 
    END 
  ELSE
    BEGIN 
    REJECT; 
    IF HARDFN AND NOT TABVTPROTM[0] THEN PAINTREST(YCURSOR);
    IF ROWTYPE[YCURSOR] EQ ROWST"COMMAND" THEN
      BEGIN                          # IF DELETE ON COMMAND LINE #
      SETCHAR(CMDLINE,0,CENDLINE);
      END 
    END 
  LINECHANGED=FALSE;
  GOTO DSX0Y1;
  
DSGENERIC:  
  IF FIRSTEVENT THEN CMDLINE[0]=NULLIN; 
  IF ABS(VTCHAR) EQ GENERICST"GHELP" THEN SETCMD("HELP"); 
  ELSE IF ABS(VTCHAR) EQ GENERICST"GBACK" THEN SETCMD("BACK");
  ELSE IF ABS(VTCHAR) EQ GENERICST"GDATA" THEN SETCMD("DATA");
  ELSE IF ABS(VTCHAR) EQ GENERICST"GEDIT" THEN SETCMD("EDIT");
  ELSE IF ABS(VTCHAR) EQ GENERICST"GSTOP" THEN
    BEGIN 
    SETCMD("SETSCR"); 
    IF NOT PROMPTING THEN SETCMD("SETLIN"); 
    END 
  ELSE IF VTCHAR EQ GENERICST"GFWD" THEN SETCMD("VNS"); 
  ELSE IF VTCHAR EQ GENERICST"GBKW" THEN SETCMD("VPS"); 
  ELSE IF -VTCHAR EQ GENERICST"GFWD" THEN SETCMD("VL"); 
  ELSE IF -VTCHAR EQ GENERICST"GBKW" THEN SETCMD("PF"); 
  ELSE IF VTCHAR EQ GENERICST"GUP" THEN SETCMD("VN"); 
  ELSE IF VTCHAR EQ GENERICST"GDOWN" THEN SETCMD("VP"); 
  ELSE IF TABCURADDT[0] EQ 2 AND
    TABVTFKLSM[0] NQ 0 AND
    VTCHAR EQ GENERICST"GPOS" THEN
    ROWPAINT[YCURSOR] = TRUE;        # 721 FULL DUPLEX TOUCH PANEL #
  ELSE GOTO DSLOOP; 
  GOTO DSFKEY2; 
  
DSFKEY: 
  IF FIRSTEVENT THEN CMDLINE[0]=NULLIN; 
  IF ABS(VTCHAR) GR POSFKEYS OR VTCHAR EQ 0 
    THEN DSERRJMP("UNSUPPORTED FUNCTION KEY$"); 
  P<KEYLIN>=LOC(FKEYSTRING[VTCHAR]);
  SCRNPT2=LENGTH(KEYLIN); 
  IF SCRNPT2 GQ 15 THEN 
    BEGIN 
    PUSH; 
    POSZ(TOPK(FKEYS)+VTCHAR+POSFKEYS);
    P<KEYLIN>=LOC(LIN); 
    ADDTOCMD; 
    POP;
    END 
  ELSE ADDTOCMD;
DSFKEY2:  
  HARDFN=FALSE; 
  IF TABVTFKLSM[0] NQ 0 THEN ROWPAINT[YCURSOR] = TRUE;
  IF PROMPTING THEN                  # SIGNAL OVERRIDE OF SECONDARY # 
    BEGIN 
    HALT("DIRECTIVE CANCELLED BY FUNCTION KEY$"); 
    ESCAPE=TRUE;
    END 
  GOTO DSLOOP;
  
DSERAC: 
  VTCHAR=X"20";  # BLANK #
  VTORDN=SCREENST"CHAR";
  GOTO DSCHAR;
  
DSERAL: 
  IF ROWTYPE[YCURSOR] EQ ROWST"COMMAND" THEN
    BEGIN 
    SETCHAR(CMDLINE,0,CENDLINE);
    ROWPAINT[COMMANDROW] = FALSE; 
    END 
  ELSE IF ALIGNGOOD THEN
    BEGIN 
    FOR SCRNPT1=XSHIFT[CURSPLIT] STEP 1 
      UNTIL EDITFIELD-1 DO SETCHAR(LINE,SCRNPT1,CBLANK);
    SETCHAR(LINE,BUFCHAR,CENDLINE); 
    TRIMPAD;
    LINECHANGED=TRUE; 
    END 
  ELSE REJECT;
  GOTO DSX0Y1;
  
DSFIELD:  
  IF YCURSOR EQ COMMANDROW THEN 
    BEGIN 
    VDTIINP;                         # GET FIRST CHARACTER OF FIELD # 
    FOR SCRNPT1 = 0 STEP 1 WHILE VTORDN EQ SCREENST"CHAR" DO
      BEGIN 
      MOVETEXT(CMDLIN,SCRNPT1,BUFCM1);
      VDTIINP;                       # GET NEXT CHARACTER OF FIELD #
      END 
    SETCHAR(CMDLINE,SCRNPT1,CENDLINE);
    ROWPAINT[COMMANDROW] = TRUE;
    END 
  ELSE
    BEGIN 
    EXTEND; 
    IF ALIGNGOOD THEN 
      BEGIN                          # IF ALIGN IS O.K. # 
      SCRNPT2 = LENGTH(LIN);         # SAVE CURRENT LINE LENGTH # 
      VDTIINP;                       # GET FIRST CHARACTER OF FIELD # 
      FOR XCURSOR = 0 STEP 1 WHILE VTORDN EQ SCREENST"CHAR" DO
        BEGIN 
        IF XCURSOR + XSHIFT[CURSPLIT] LS EDITFIELD THEN 
          BEGIN                      # IF WITHIN EDITING WINDOW # 
          SCRNPT1 = XLTXPINT[VTCHAR]; 
          IF ASCII[CURFILE] LQ 1 THEN 
            BEGIN                    # IF SUPPRESSING LOWER CASE #
            # CODE IS DEPENDENT ON PRECISE VALUES OF INTERNAL CHARSET # 
            CONTROL IFNQ CLEFTCURL,O"133"; DEFERROR; CONTROL FI;
            CONTROL IFNQ CVERTICAL,O"134"; DEFERROR; CONTROL FI;
            CONTROL IFNQ CRITECURL,O"135"; DEFERROR; CONTROL FI;
            CONTROL IFNQ CTILDE,O"136"; DEFERROR; CONTROL FI; 
            CONTROL IFNQ CGRAVE,O"100"; DEFERROR; CONTROL FI; 
            CONTROL IFNQ CCOLON,O"000"; DEFERROR; CONTROL FI; 
            # REPAINT IF NON-EXISTENT DISPLAY CODE CHARACTER #
            IF (SCRNPT1 GQ O"133" AND SCRNPT1 LQ O"136")
              OR (SCRNPT1 EQ O"100") THEN ROWPAINT[YCURSOR] = TRUE; 
            IF (B<00,01>MEM[CSMR] EQ 0) 
              AND (SCRNPT1 EQ O"000") THEN ROWPAINT[YCURSOR]=TRUE;
            DSPLCOD(SCRNPT1);        # SUPRESS LOWER CASE # 
            END 
          SETCHAR(LINE,XCURSOR+XSHIFT[CURSPLIT],SCRNPT1); 
          IF SCRNPT1 EQ TABCHAR THEN
            BEGIN                    # IF SOFT TAB #
            SOFTTAB = TRUE; 
            ROWPAINT[YCURSOR] = TRUE; 
            END 
          END 
        VDTIINP;                     # GET NEXT CHARACTER OF FIELD #
        END 
# 
      PERFORM NECESSARY PADDING AND SET END OF LINE.
# 
      SCRNPT1 = XSHIFT[CURSPLIT] + XCURSOR; 
      IF SCRNPT1 LS SCRNPT2 THEN
        BEGIN                        # IF LINE WAS SHORTENED #
        FOR SCRNPT3 = SCRNPT1 STEP 1 UNTIL
          MIN(SCRNPT2-1,MIN(EDITFIELD-1,XSHIFT[CURSPLIT]+USRNUMCOL)) DO 
          BEGIN 
          SETCHAR(LINE,SCRNPT3,CBLANK); 
          END 
        TRIMPAD;
        END 
      ELSE
        BEGIN                        # LINE NOT SHORTENED # 
        IF SCRNPT2 LS XSHIFT[CURSPLIT] THEN 
          BEGIN                      # IF LINE LENGTHENED # 
          IF EDITFIELD GQ XSHIFT[CURSPLIT] THEN 
            BEGIN                    # IF WITHIN EDITING WINDOW # 
            FOR SCRNPT3 = SCRNPT2 STEP 1 UNTIL XSHIFT[CURSPLIT] - 1 DO
              SETCHAR(LINE,SCRNPT3,CBLANK); 
            SETCHAR(LINE,MIN(SCRNPT1,EDITFIELD),CENDLINE);
            END 
          END 
        ELSE
          BEGIN                      # NO CHANGE IN LINE LENGTH # 
          SETCHAR(LINE,MIN(SCRNPT1,MAX(SCRNPT2,EDITFIELD)),CENDLINE); 
          END 
        END 
      LINECHANGED = TRUE;            # TEXT OF LINE ALTERED # 
      END 
    ELSE
      BEGIN                          # ALIGN BAD #
      REJECT;                        # REJECT CHANGE #
      END 
    END 
  GOTO DSLOOP3;                      # CONTINUE WITH INPUT #
  
  
DSBAD:  
  ERRSTRING = "UNKNOWN CONTROL KEY, CHECK SCREEN$"; 
  ROWPAINT[VTYCUR] = TRUE;           # SIGNAL REPAINT OF LINE # 
  GOTO DSLOOP;
  
  IOEND  # DOSCREEN # 
PAGE                         # SCREEN OUTPUT/CONTROL   #
  
  
PROC PAINTMARKS(MARKTYPE);
  BEGIN 
# 
**        PAINTMARKS - SET SCREEN PAINT BITS FOR MARKS. 
* 
*         ENTRY  MARKTYPE - 1=FORCE HIGHLIGHTING ON.
*                           2=MAINTAIN EXISTING HIGHLIGHTS. 
*                           3=FORCE HIGHLIGHTING OFF. 
*                TOPS(BOTH), BOTS(BOTH) - SETUP.
*                REGLINE[MARKREG AND MARKREG+1] - ALREADY SET.
*                SPLITFILE[2] - WHETHER TWO SPLITS ARE ON SCREEN. 
* 
*         EXIT   ROWPMARK[ALL] - FORCED ON OR OFF BY REGIONS. 
*                ROWPAINT[ANY] - FORCED TRUE AS NEEDED. 
* 
*         CALLS  DOMARK (INTERNAL). 
# 
  ITEM MARKTYPE;
  
  PROC DOMARK(SPLT);
    BEGIN 
# 
**        DOMARK - WORKING PORTION OF PAINTMARKS. 
* 
*         NOTE   REFER TO PAINTMARKS HEADER.
# 
    ITEM L1, L2, SPLT;
    FOR L1=TOPS(SPLT)+1 STEP 1 UNTIL BOTS(SPLT)-1 DO
      BEGIN 
      L2=LTOY(L1,SPLT); 
      ROWPMARK[L2]=FALSE; 
      IF L1 GQ REGLINE[MARKREG] AND L1 LQ REGLINE[MARKREG+1] THEN 
        BEGIN 
        IF MARKTYPE NQ 2 THEN ROWPAINT[L2]=TRUE;
        IF MARKTYPE NQ 3 THEN ROWPMARK[L2]=TRUE;
        END 
        IF TABATTRCHR[0] THEN 
          BEGIN                      # IF ATTRIBUTE TAKES A POS # 
          IF L1 EQ REGLINE[MARKREG] AND MARKTYPE EQ 3 THEN
            BEGIN                    # IF CLEARING MARKS #
            ROWPAINT[L2-1] = TRUE;   # FLAG FOR REPAINT # 
            END 
          END 
      END 
    END 
  
  IF NUMMARKS GR 0 THEN        # SEE IF NEED TO HIGHLIGHT ANY # 
    BEGIN 
    DOMARK(1);
    IF SPLITFILE[2] NQ 0 THEN DOMARK(2);
    END 
  
  END                             # OF PAINTMARKS # 
  
  
PROC PAINTSCREEN; 
  IOBEGIN(PAINTSCREEN)
# 
**        PAINTSCREEN - OUTPUT NORMAL AND SECONDARY DISPLAYS. 
* 
*         PAINTSCREEN IS CALLED TO FILL A DISPLAY PAGE.  THE
*         PROMPTING FLAG INDICATES WHETHER THIS IS A NORMAL 
*         (PRIMARY) DISPLAY OR A SECONDARY DISPLAY.  THE ROWPAINT 
*         BITS INDICATE WHICH PORTIONS OF THE SCREEN ARE ALREADY
*         CORRECT AND WHICH REALLY NEED TO BE PAINTED.  THE YCURSOR 
*         IS FORCED TO POINT TO EITHER TEXT OR THE COMMAND AREA IF
*         IT DOES NOT ALREADY.  ANY MESSAGE IN THE ERROR STRING 
*         BUFFER IS OUTPUT AND CLEARED.  IF AN ERROEOUS COMMAND WAS 
*         PREVIOUSLY ATTEMPTED, PAINTSCREEN RECOGNIZES THIS AND 
*         RE-PRINTS THE OLD COMMAND BUFFER WITH THE CURSOR FLASHING 
*         AT THE ILLEGAL SYNTAX.  FILE POSITIONING IS FORCED TO 
*         ALIGN WITH THE CURSOR FOR ON-TEXT CURSORS.  TITLE LINES 
*         ARE VERIFIED FOR CORRECTNESS AND POSSIBLY PAINTED.
* 
*         ENTRY  YCURSOR - COMMAND PROCESSOR'S FAVORITE CURSOR. 
*                    NEGATIVE=SELECT CURSOR FOR CURRENT LINE. 
*                    ON TEXT OR COMMAND ROW=USE THAT. 
*                XCURSOR - ALSO WHERE COMMAND PROCESSOR WANT IT.
*                VTXMAX - MAXIMUM COLUMN POSITION.
*                ROWTYPE[ALL], ROWSPLIT[ALL] - SETUP. 
*                SPLITFILE[1-2] - SETUP.
*                CURRENT, CURFILE, CURSPLIT - WHERE WE ARE. 
*                PROMPTING - PRIMARY OR SECONDARY DISPLAY.
*                LTPS(1-2), LASTBOTS, LASTSIZE, LASTNAME - MUST 
*                    BE LEFT OVER FROM PREVIOUS PAINTSCREEN OR -1.
*                COMMANDROW - SETUP.
*                ROWORIG[ALL] - MUST BE AS LEFT BY LAST CALL HERE 
*                    EXCEPT AS UPDATED BY DELX AND INSX.
*                ROWPAINT[ALL] - WHICH LINES NEED PAINTING. 
*                TOPS(1-2), BOTS(1-2) - SETUP.
*                ROWCOLUM[ALL] - WHERE WANT SCALE PATTERN PAINTED.
*                XSHIFT[1-2] - SETUP. 
*                MRKCHAR[0-1] - SETUP.
*                USRNUMCOL, USRNUMLIN - LOGICAL DIMENSIONS. 
*                ERRSTRING - ERROR MESSAGE BUFFER.
*                CMDLIN - RESIDUAL COMMAND BUFFER.
*                TOPF(1-2), BOTF(1-2) - SETUP.
*                FKEYSHOW - HOW MANY FUNCTION KEYS TO DISPLAY.
*                SHIFTFKEY - FLAG TO DISPLAY SHIFTED FUNCTION KEYS. 
*                ERRCURSOR - IF POSITIVE, XCURSOR FOR SYNTAX ERROR. 
* 
*         EXIT   XCURSOR, YCURSOR - POSSIBLY AT NEW LOCATION. 
*                TOPS(1-2), BOTS(1-2) - POSSIBLY UPDATED. 
*                CURFILE - UPDATED IF YCURSOR UPDATED.
*                CURSPLIT - UPDATED IF YCURSOR UPDATED. 
*                ERRSTRING - POSSIBLY WIDE LINE WARNING.
*                ROWPAINT[ALL] - FALSE EXCEPT POSSIBLY COMMANDROW.
*                ROWORIG[ALL] - REDEFINED.
*                ROWCOLUM[ALL] - FALSE. 
*                ROWPMARK[ALL] - FALSE. 
*                LTPS(1-2), LASTBOTS, LASTSIZE, LASTNAME - REDEFINED. 
* 
*         MACROS GETCHAR, SETCHAR, LTOY.
* 
*         CALLS  GENDECIMAL, GENLITERAL, GENNAME, GENTITLE, LENGTH, 
*                PAINTMARKS, PAINTSPLIT, POSZ, SETTOPBOTS, TRIMPAD, 
*                TTLCSTR, TTDEC, TTLFN, TTSTR, TTST, VDTCHR, VDTCLL 
*                VDTPOS, VDTSAM.
* 
*         USES   SPLIT, FILNUM, FKEYNDX, SCRNPT1, SCRNPT2,
*                SCRNPT3, SCRNPT4, SCRNPT5, SCRNPT6, LIN. 
# 
  
  SWITCH PAINTSW
    PTEMPTY,                         # EMPTY LINE # 
    PTCMD,                           # COMMAND LINE # 
    PTTITLE,                         # TITLE LINE # 
    PTLABEL,                         # FUNCTION KEY LABEL LINE #
    PTTEXT,                          # TEXT LINE #
    PTRESPONSE;                      # FSE COMMAND RESPONSE LINE #
  
  
  PROC GENDECIMAL(POS,VALUE); 
# TITLE GENDECIMAL - GENERATE A DECIMAL NUMBER. # 
  
    BEGIN  # GENDECIMAL # 
  
# 
**        GENDECIMAL - GENERATE A DECIMAL NUMBER. 
* 
*         CONVERT A DISPLAY CODE VALUE TO DECIMAL AND POSITION
*         IT IN THE TTYLINE.
* 
*         PROC GENDECIMAL(POS,VALUE)
* 
*         EXIT   TTYLINE - SETUP. 
* 
*         CALLS  SETCHAR. 
* 
*         USES   TTYLINE. 
# 
  
    ITEM POS        I;               # POSITION OF NUMBER # 
    ITEM QUIT       B;               # FINISHED FLAG #
    ITEM TMP1       I;               # TEMPORARY STORAGE #
    ITEM TMP2       I;               # TEMPORARY STORAGE #
    ITEM TMP3       I;               # TEMPORARY STORAGE #
    ITEM VALUE      I;               # VALUE TO CONVERT # 
  
    TMP1=ABS(VALUE);
    TMP2=0;                          # COUNT DIGITS # 
    QUIT=FALSE; 
    WHYLE NOT QUIT DO                # NOT DONE YET # 
      BEGIN 
      C<TMP2>TMP3=MOD(TMP1,10)+O"33";  # GET A DIGIT #
      TMP1=TMP1/10;                  # REDUCE NUMBER #
      TMP2=TMP2+1;                   # BUMP POINTER # 
      IF TMP1 EQ 0 THEN QUIT=TRUE;
      END 
  
    FOR TMP1=1 STEP 1 UNTIL TMP2 DO 
      BEGIN 
      SETCHAR(TTYLINE,POS,XLTDSPINT[C<TMP2-TMP1>TMP3]); 
      POS=POS+1;
      END 
  
    END  # GENDECIMAL # 
  
  
  PROC GENLITERAL(POS,STR); 
# TITLE GENLITERAL - GENERATE A LITERAL STRING. # 
  
    BEGIN  # GENLITERAL # 
  
# 
**        GENLITERAL - GENERATE A LITERAL STRING. 
* 
*         GENERATE A LITERAL STRING AND POSITION IT IN THE
*         TTYLINE.
* 
*         PROC GENLITERAL(POS,STR)
* 
*         EXIT   TTYLINE - SETUP. 
* 
*         CALLS  SETCHAR. 
* 
*         USES   TTYLINE. 
# 
  
    ITEM BEGINWORD  B;               # BEGINNING WORD # 
    ITEM POS        I;               # POSITION OF STRING # 
    ITEM STR        C(40);           # STRING TO CONVERT #
    ITEM TMP1       I;               # TEMPORARY STORAGE #
    ITEM TMP2       I;               # TEMPORARY STORAGE #
  
    BEGINWORD=TRUE; 
    TMP1=0; 
    WHYLE TMP1 LS 40 AND C<TMP1>STR NQ "$" DO 
      BEGIN 
      TMP2=C<TMP1>STR;
      TMP2=XLTDSPINT[TMP2]; 
      IF TMP2 GQ CLETTERA AND TMP2 LQ CLETTERZ THEN 
        BEGIN 
        IF NOT BEGINWORD THEN TMP2=TMP2+CLOWERA-CLETTERA; 
        BEGINWORD=FALSE;
        END 
      ELSE BEGINWORD=TRUE;
      SETCHAR(TTYLINE,POS,TMP2);
      POS=POS+1;
      TMP1=TMP1+1;
      END 
  
    END  # GENLITERAL # 
  
  
  PROC GENNAME(POS,NAME); 
# TITLE GENNAME - GENERATE A NAME. #
  
    BEGIN  # GENNAME #
  
# 
**        GENNAME - GENERATE A NAME.
* 
*         GENERATE A NAME AND POSITION IT IN THE TTYLINE. 
* 
*         PROC GENNAME(POS,NAME)
* 
*         EXIT   TTYLINE - SETUP. 
* 
*         CALLS  SETCHAR. 
* 
*         USES   TTYLINE. 
# 
  
    ITEM NAME       C(07);           # NAME TO CONVERT #
    ITEM POS        I;               # POSITION OF NAME # 
    ITEM TMP1       I;               # TEMPORARY STORAGE #
    ITEM TMP2       I;               # TEMPORARY STORAGE #
  
    FOR TMP1=0 STEP 1 UNTIL 6 DO
      BEGIN 
      TMP2=C<TMP1>NAME; 
      IF TMP2 NQ 0 AND TMP2 NQ O"55" THEN 
        BEGIN 
        TMP2=XLTDSPINT[TMP2]; 
        SETCHAR(TTYLINE,POS,TMP2);
        POS=POS+1;
        END 
      END 
  
    END  # GENNAME #
  
  
  PROC GENTITLE(SPLIT); 
# TITLE GENTITLE - GENERATE TITLE LINE TEXT. #
  
    BEGIN  # GENTITLE # 
  
# 
**        GENTITLE - GENERATE TITLE LINE TEXT.
* 
*         GIVEN A SPLIT, GENERATE THE TITLE LINE. 
* 
*         PROC GENTITLE(SPLIT)
* 
*         ENTRY  SPLIT - WHICH SPLIT TO GENERATE TITLE FOR. 
* 
*         EXIT   TTYLIN - TEXT FOR TITLE LINE.
* 
*         CALLS  GENDECIMAL, GENLITERAL, GENNAME, SETCHAR.
* 
          USES   TTYLIN.
# 
  
    ITEM FILE       I;               # FILE SPLIT # 
    ITEM POS        I;               # POSITION OF TEXT # 
    ITEM SPLIT      I;               # TITLE SPLIT #
  
    POS=0;
    IF TABATTRCHR[0] THEN GENLITERAL(POS," $"); 
    FILE=SPLITFILE[SPLIT];
    IF ASCII[FILE] LQ 1 THEN GENLITERAL(POS,"UPPER CASE $");
    GENLITERAL(POS,"FILE $"); 
    GENNAME(POS,FILENAM[FILE]); 
    GENLITERAL(POS,"  $");
    IF NOT SHORTTITLE THEN
      BEGIN 
      IF TOPF(FILE)+1 EQ BOTF(FILE) THEN GENLITERAL(POS," EMPTY$"); 
      ELSE
        BEGIN 
        IF TOPS(SPLIT)+1 NQ BOTS(SPLIT) THEN
          BEGIN 
          GENLITERAL(POS,"LINES $");
          GENDECIMAL(POS,TOPS(SPLIT)+1-TOPF(FILNUM)); 
          GENLITERAL(POS," - $"); 
          GENDECIMAL(POS,BOTS(SPLIT)-1-TOPF(FILNUM)); 
          END 
        GENLITERAL(POS," SIZE $");
        GENDECIMAL(POS,BOTF(FILE)-1-TOPF(FILE));
        END 
      IF XSHIFT[SPLIT] NQ 0 THEN
        BEGIN                        # IF SET VIEW OFFSET ENABLED # 
        GENLITERAL(POS,"  OFFSET $"); 
        GENDECIMAL(POS,XSHIFT[SPLIT]+1);
        END 
      IF FILENAM[1] EQ FILENAM[2] THEN
        BEGIN                        # IF SAME FILE IN BOTH SPLITS #
        CHANGED[1] = CHANGED[1] LOR CHANGED[2]; 
        CHANGED[2] = CHANGED[1];
        END 
      IF CHANGED[SPLIT] NQ 0 THEN 
        BEGIN                        # IF FILE HAS BEEN CHANGED # 
        GENLITERAL(POS," (CHANGED)$");
        END 
      ELSE
        BEGIN                        # NO CHANGE #
        IF LOCKED[SPLIT] NQ 0 THEN
          BEGIN                      # IF FILE IS LOCKED #
          GENLITERAL(POS," (READ-ONLY)$");
          END 
        ELSE
          BEGIN                      # NO LOCK #
          GENLITERAL(POS," (NO CHANGES)$"); 
          END 
        END 
      IF NUMMARKS GR 0 AND MRKFILE[0] EQ FDLF(FILE) THEN
        BEGIN 
        IF NUMMARKS EQ 1 THEN 
          GENLITERAL(POS," <MARK ACTIVE>$");
        ELSE
          GENLITERAL(POS," <MARKS ACTIVE>$"); 
        END 
      END 
    FOR POS = POS STEP 1 UNTIL(VTXMAX - ATTCOUNT) DO
      BEGIN                          # UNTIL END OF LINE #
      SETCHAR(TTYLINE,POS,CBLANK);
      END 
    SETCHAR(TTYLINE,POS,CENDLINE);
  
    END  # GENTITLE # 
  
  
  
  
  # MAIN PAINTSCREEN CODE STARTS HERE # 
  
  IF NOT PROMPTING THEN 
    BEGIN 
  
    IF FORCEAUTOP[0] THEN 
      BEGIN                          # IF AUTO HALF PAGE #
      TOPS(CURSPLIT) = BOTS(CURSPLIT) - NUMROWS[CURSPLIT] / 2;
      SETTOPS(CURSPLIT);
      XCURSOR = 0;
      YCURSOR = BOTS(CURSPLIT); 
      YCURSOR = LTOY(YCURSOR,CURSPLIT); 
      SETBOTS(CURSPLIT);
      PAINTSPLIT; 
      END 
    FORCEAUTOP[0] = FALSE;
  
    # DETERMINE WHETHER RESIDUAL CURSOR IS OUT OF TEXT AREAS #
  
    SCRNPT2=0;
    IF YCURSOR LS 0 OR YCURSOR GR VTYMAX THEN SCRNPT2=1;
    IF SCRNPT2 EQ 0 THEN
      BEGIN 
      IF ROWTYPE[YCURSOR] NQ ROWST"TEXT"
        AND ROWTYPE[YCURSOR] NQ ROWST"COMMAND" THEN SCRNPT2=1;
      END 
  
    # VERIFY VALIDITY OF SCREEN BOUNDS, MAKE GOOD CURSOR POSITION # 
  
    IF SCRNPT2 EQ 0 THEN
      BEGIN                          # SIMPLY VERIFY SCREEN BOUNDS #
      SETTOPBOTS(1);
      IF SPLITFILE[2] NQ 0 THEN SETTOPBOTS(2);
      END 
    ELSE
      BEGIN                          # RECOMPUTE CURSOR WHEN OFF TEXT # 
      IF SPLITFILE[2] EQ 0 THEN CURFILE=SPLITFILE[1]; 
      CURSPLIT=MIN(MAX(CURSPLIT,1),2);
      IF SPLITFILE[CURSPLIT] NQ CURFILE 
        THEN CURSPLIT=CURSPLIT LXR 3; 
      IF SPLITFILE[2] NQ 0
        AND FDLF(SPLITFILE[1]) EQ FDLF(SPLITFILE[2]) THEN 
        BEGIN 
        SETTOPBOTS(CURSPLIT); 
        YCURSOR=CURF(CURFILE);
        YCURSOR=LTOY(YCURSOR,CURSPLIT); 
        IF ROWTYPE[YCURSOR] EQ ROWST"TITLE" AND NUMROWS[CURSPLIT] 
          GR 0 THEN YCURSOR=YCURSOR+1;
        END 
      ELSE
        BEGIN 
        FOR SCRNPT1=1 STEP 1 UNTIL 2 DO 
          BEGIN 
          IF SPLITFILE[SCRNPT1] NQ 0 THEN 
            BEGIN 
            SETTOPBOTS(SCRNPT1);
            IF SPLITFILE[SCRNPT1] EQ CURFILE THEN 
              BEGIN 
              YCURSOR=CURF(CURFILE);
              YCURSOR=LTOY(YCURSOR,SCRNPT1);
              IF ROWTYPE[YCURSOR] EQ ROWST"TITLE" AND 
                NUMROWS[SCRNPT1] GR 0 THEN YCURSOR=YCURSOR+1; 
              CURSPLIT=SCRNPT1; 
              END 
            END 
          END 
        END 
      END 
    IF FORCEAUTOR[0] THEN 
      BEGIN                          # IF FORCED TO NEXT LINE # 
      XCURSOR = 0;
      YCURSOR = YCURSOR + 1;
      FORCEAUTOR[0] = FALSE;
      END 
    IF YCURSOR LS 0 OR YCURSOR GR VTYMAX THEN YCURSOR=COMMANDROW; 
  
    # SEE IF LAST TITLE NOW OBSOLETE #
  
    GENTITLE(1);
    SCRNPT4=MAX(LENGTH(TITLE1LIN),LENGTH(TTYLIN));
    FOR SCRNPT1=0 STEP 1 UNTIL SCRNPT4 DO 
      BEGIN 
      GETCHAR(TITLE1LINE,SCRNPT1,SCRNPT2);
      GETCHAR(TTYLINE,SCRNPT1,SCRNPT3); 
      IF SCRNPT2 NQ SCRNPT3 THEN ROWPAINT[TITLEROW[1]]=TRUE;
      END 
    IF SPLITFILE[2] NQ 0 THEN 
      BEGIN 
      GENTITLE(2);
      SCRNPT4=MAX(LENGTH(TITLE2LIN),LENGTH(TTYLIN));
      FOR SCRNPT1=0 STEP 1 UNTIL SCRNPT4 DO 
        BEGIN 
        GETCHAR(TITLE2LINE,SCRNPT1,SCRNPT2);
        GETCHAR(TTYLINE,SCRNPT1,SCRNPT3); 
        IF SCRNPT2 NQ SCRNPT3 THEN ROWPAINT[TITLEROW[2]]=TRUE;
        END 
      END 
    FOR SPLIT=1 STEP 1 UNTIL 2 DO 
      BEGIN 
      FILNUM=SPLITFILE[SPLIT];
      IF FILNUM NQ 0 THEN 
        BEGIN 
        IF LTPS(SPLIT) NQ TOPS(SPLIT) 
          OR LASTNAME[SPLIT] NQ FILENAM[FILNUM] THEN
          BEGIN 
          PAINTONESPLT(SPLIT);
          END 
        END 
      END 
    END 
  
  PAINTMARKS(2);
  
  FOR SCRNPT1=0 STEP 1 UNTIL USRNUMLIN DO 
    BEGIN 
    IF ROWPAINT[SCRNPT1] OR ROWORIG[SCRNPT1] NQ SCRNPT1 THEN
      BEGIN 
      ROWPAINT[SCRNPT1]=FALSE;
      ROWORIG[SCRNPT1]=SCRNPT1; 
      GOTO PAINTSW[ROWTYPE[SCRNPT1]]; 
  
PTTEXT: 
      IF ROWPMARK[SCRNPT1] THEN 
        BEGIN                        # IF ONLY LOGICALLY MARKED # 
        IF NUMMARKS EQ 0 THEN ROWPMARK[SCRNPT1] = FALSE;
        END 
CONTROL IFEQ MULTI,1;                # IF MULTI USER FSE #
      VDTPOS(0,SCRNPT1);             # POSITION # 
CONTROL FI;                          # END OF IF MULTI #
CONTROL IFEQ SINGLE,1;               # IF NOT MULTI USER FSE #
      IF TABLOCKMDE[0] THEN 
        BEGIN                        # IF BLOCK MODE TERMINAL # 
        VDTSAP(DUMB,0,SCRNPT1);      # SET ATTRIBUTE POSITION # 
        END 
      ELSE
        BEGIN                        # NOT BLOCK MODE # 
        VDTPOS(0,SCRNPT1);           # POSITION # 
        END 
CONTROL FI;                          # END OF NOT MULTI # 
      SPLIT=ROWSPLIT[SCRNPT1];
      SCRNPT2=YTOL(SCRNPT1,SPLIT);
      IF VTCLRFRST[0] THEN VDTCLL(0,SCRNPT1); 
      SCRNPT6=XSHIFT[SPLIT]-1;      # PRESET COLUMN LENGTH #
      IF SCRNPT2 LS BOTS(SPLIT) THEN
        BEGIN 
        POSZ(SCRNPT2);
        SCRNPT6=LENGTH(LIN);
        IF SCRNPT6 GR NUMWIDBLK+WIDTH AND ERRSTRING EQ " $" THEN
          BEGIN 
          ERRSTRING="WIDE LINE$"; 
          YCURSOR=SCRNPT1;
          END 
        IF USRNUMCOL+XSHIFT[SPLIT] LS SCRNPT6 AND NOT ROWPMARK[SCRNPT1] 
          THEN
          BEGIN 
          SETCHAR(LINE,USRNUMCOL+XSHIFT[SPLIT]+1,CENDLINE); 
          TRIMPAD;
          SCRNPT6=LENGTH(LIN);
          END 
        IF ROWCOLUM[SCRNPT1] THEN 
          BEGIN 
CONTROL IFEQ SINGLE,1;               # IF NOT MULTI USER FSE #
          IF TABLOCKMDE[0] THEN VDTSAM(0);
CONTROL FI; 
          ROWCOLUM[SCRNPT1] = FALSE;
          SCRNPT6 = 1;
          FOR SCRNPT4 = XSHIFT[SPLIT] STEP 1 UNTIL
            XSHIFT[SPLIT] + USRNUMCOL DO
            BEGIN 
            SCRNPT5 = MOD(SCRNPT4+1,10) + CDIGIT0;
CONTROL IFEQ MULTI,1;                # IF MULTI USER FSE #
            IF SCRNPT5 EQ CDIGIT1 AND NOT TABATTRCHR[0] THEN
CONTROL FI;                          # END OF IF MULTI #
CONTROL IFEQ SINGLE,1;               # IF NOT MULTI USER FSE #
            IF SCRNPT5 EQ CDIGIT1 AND NOT TABATTRCHR[0] 
              AND NOT TABLOCKMDE[0] THEN
CONTROL FI;                          # END OF IF NOT MULTI #
              BEGIN 
              SCRNPT6 = SCRNPT6 LXR 1;
              IF SCRNPT6 EQ 0 THEN
                BEGIN 
                VDTSAM(0);
                END 
              ELSE
                BEGIN 
                VDTSAM(MSKINVERSE); 
                END 
              END 
            SCRNPT5 = XLTINTXP[SCRNPT5];
            VDTCHR(SCRNPT5);
            END 
CONTROL IFEQ MULTI,1;                # IF MULTI USER FSE #
          IF SCRNPT6 EQ 1 AND NOT TABATTRCHR[0] THEN VDTSAM(0); 
CONTROL FI;                          # END OF IF MULTI #
CONTROL IFEQ SINGLE,1;               # IF NOT MULTI USER FSE #
          IF SCRNPT6 EQ 1 AND NOT TABATTRCHR[0] AND NOT TABLOCKMDE[0] 
            THEN VDTSAM(0); 
CONTROL FI;                          # END OF IF NOT MULTI #
          GOTO PTDONE;               # FINISHED WITH THIS LINE #
          END 
        ELSE IF ROWPMARK[SCRNPT1] THEN
          BEGIN 
          IF SCRNPT6 EQ 0 THEN
            BEGIN 
            LINE[0]=BLANKLIN; 
            SCRNPT6=LENGTH(LIN);
            END 
          SCRNPT4=XSHIFT[SPLIT];
          SCRNPT5=MIN(SCRNPT6-1,USRNUMCOL+XSHIFT[SPLIT]); 
          SCRNPT2 = SCRNPT4;         # SAVE DEFAULT VALUES #
          SCRNPT3 = SCRNPT5;
          IF CURRENT EQ REGLINE[MARKREG] AND MRKCHAR[0] 
            GQ 0 THEN SCRNPT4=MAX(MRKCHAR[0],XSHIFT[SPLIT]);
          IF CURRENT EQ REGLINE[MARKREG+1] AND MRKCHAR[1] 
            GQ 0 THEN SCRNPT5=MIN(MRKCHAR[1],SCRNPT5);
              IF SCRNPT4 GR SCRNPT5 THEN
                BEGIN                # IF BEYOND MARKED AREA #
                SCRNPT4 = - 1;
                SCRNPT5 = - 1;
                END 
          IF TABLOCKMDE[0] THEN 
            BEGIN                    # IF BLOCK MODE TYPE TERMINAL #
            IF (SCRNPT2 EQ SCRNPT4) AND (SCRNPT3 EQ SCRNPT5) THEN 
              BEGIN                  # IF MARKING # 
              VDTSAM(MSKINVERSE); 
              END 
            ELSE
              BEGIN                  # NOT MARKING #
              VDTSAM(0);
              END 
            END 
          SCRNPT6=MIN(SCRNPT6-1,USRNUMCOL+XSHIFT[SPLIT]); 
          FOR SCRNPT2=XSHIFT[SPLIT] STEP 1 UNTIL SCRNPT6 DO 
            BEGIN 
            IF SCRNPT2 EQ SCRNPT4 AND NOT TABLOCKMDE[0] THEN
              BEGIN 
              IF TABATTRCHR[0] THEN 
                BEGIN                # IF ATTRIBUTE TAKES A SPACE # 
                IF TABNOTCHAR[0] AND SCRNPT2 EQ XSHIFT[SPLIT] 
                  AND SCRNPT2 NQ SCRNPT5 THEN 
                  BEGIN              # IF A CHARACTER MUST BE SKIPPED # 
                  SCRNPT2 = SCRNPT2 + 1;
                  END 
                ELSE
                  BEGIN              # MOVE CURSOR BACK FOR ATTRIBUTE # 
                  VDTOUT(X"08");
                  END 
                END 
              VDTSAM(MSKINVERSE); 
              END 
            GETCHAR(LINE,SCRNPT2,SCRNPT3);
            SCRNPT3=XLTINTXP[SCRNPT3];
            IF SCRNPT3 LS O"4040" THEN SCRNPT3 = XLTINTXP[UNPRINT]; 
            VDTCHR(SCRNPT3);
            IF SCRNPT2 EQ SCRNPT5 AND NOT TABLOCKMDE[0] THEN
              BEGIN 
              IF TABATTRCHR[0] THEN 
                BEGIN                # IF ATTRIBUTE TAKES A BYTE #
                IF SCRNPT2 EQ VTXMAX THEN 
                  BEGIN              # IF AT END OF CURRENT LINE #
                  VDTOUT(X"08");     # CURSOR MUST MOVE BACK #
                  END 
                ELSE
                  BEGIN              # SKIP AN OUTPUT CHARACTER # 
                  IF SCRNPT2 NQ SCRNPT6 THEN SCRNPT2 = SCRNPT2 + 1; 
                  END 
                END 
              VDTSAM(0);
              END 
            END 
          ROWPMARK[SCRNPT1]=FALSE;
          END 
        ELSE
          BEGIN                         # ALL TEXT THAT FITS WINDOW   # 
            IF TABATTRCHR[0] THEN 
              BEGIN                  # IF ATTRIBUTE TAKES A BYTE #
              IF ROWTYPE[SCRNPT1-1] EQ ROWST"TITLE" THEN
                BEGIN                # IF FIRST LINE AFTER TITLE #
                VDTPOS(VTXMAX,SCRNPT1-1); 
                ATTRIBMASK = MSKINVERSE;
                END 
              END 
          VDTSAM(0);                 # CLEAR ATTRIBUTES # 
          SCRNPT6=MIN(SCRNPT6-1,USRNUMCOL+XSHIFT[SPLIT]); 
          SCRNPT4 = -1;              # NUMBER OF BLANKS SO FAR, - 1 # 
          FOR SCRNPT2=XSHIFT[SPLIT] STEP 1 UNTIL SCRNPT6 DO 
            BEGIN 
            GETCHAR(LINE,SCRNPT2,SCRNPT3);
            IF VTCLRFRST[0] AND SCRNPT3 EQ CBLANK THEN
              BEGIN                  # IF LINE CLEAR, CHAR. A BLANK # 
              SCRNPT4 = SCRNPT4 + 1;
              END 
            ELSE
              BEGIN                  # NOT A BLANK, OR NO CLEAR LINE #
              IF SCRNPT4 GQ 0 THEN
                BEGIN                # IF SOME BLANKS HAVE BEEN SEEN #
                IF SCRNPT4 GQ VTNUMBLNK[0] THEN 
                  BEGIN              # IF AT OR PAST THRESHOLD #
                  VDTPOS(SCRNPT2-XSHIFT[SPLIT],SCRNPT1);
                  END 
                ELSE
                  BEGIN              # NOT WORTH VDTPOS # 
                  SCRNPT5 = XLTINTXP[CBLANK]; 
                  FOR SCRNPT4 = SCRNPT4 STEP -1 UNTIL 0 DO
                    BEGIN            # SEND BLANKS #
                    VDTCHR(SCRNPT5);
                    END 
                  END 
                SCRNPT4 = -1;        # RESET BLANK COUNT #
                END 
              SCRNPT3 = XLTINTXP[SCRNPT3];
              IF SCRNPT3 LS O"4040" THEN SCRNPT3 = XLTINTXP[UNPRINT]; 
              VDTCHR(SCRNPT3);
              END 
            END 
          END 
        END 
      ELSE
        BEGIN 
        VDTSAM(0);                   # CLEAR ATTRIBUTES # 
        ROWPMARK[SCRNPT1] = FALSE;
        END 
      SCRNPT6=SCRNPT6-XSHIFT[SPLIT]+1;
      SCRNPT6=MAX(SCRNPT6,0); 
      IF SCRNPT6 LQ VTXMAX AND       # IF NOT CLEARED (AT PTTEXT)#
         NOT VTCLRFRST[0] THEN       # BEFORE PRINTING OR BY THE #
         VDTCLL(SCRNPT6,SCRNPT1);    # ACTUAL PRINTING OF OUTPUT #
      GOTO PTDONE;
  
PTTITLE:  
      SPLIT=ROWSPLIT[SCRNPT1];
      FILNUM=SPLITFILE[SPLIT];
      IF TABLOCKMDE[0] THEN 
        BEGIN                        # IF NOT CHARACTER MODE #
        SCRNPT6 = 1;                 # WRITE TITLE LINE # 
        VDTSAP(DUMB,0,SCRNPT1); 
        VDTSAM(MSKPROTECT+MSKUNDERLN);
        END 
      ELSE
        BEGIN                        # CHARACTER MODE TERMINAL #
        SCRNPT6 = 0;                 # NO CHANGE YET TO TITLE LINE #
        END 
      GENTITLE(SPLIT);
      SCRNPT5=LENGTH(TTYLIN); 
      IF TABATTRCHR[0] THEN SCRNPT5 = SCRNPT5 - 3;
      IF SPLIT EQ 1 THEN
        BEGIN                        # IF TOP SPLIT # 
        FOR SCRNPT2=LENGTH(TITLE1LIN) STEP 1 UNTIL SCRNPT5 DO 
          BEGIN 
          SETCHAR(TITLE1LINE,SCRNPT2,CENDLINE); 
          END 
        END 
      ELSE                           # IF BOTTOM SPLIT #
        BEGIN 
        FOR SCRNPT2=LENGTH(TITLE2LIN) STEP 1 UNTIL SCRNPT5 DO 
          BEGIN 
          SETCHAR(TITLE2LINE,SCRNPT2,CENDLINE); 
          END 
        END 
      SCRNPT2 = 0;
      IF TABATTRCHR[0] THEN SCRNPT2 = 1;
      FOR SCRNPT2 = SCRNPT2 STEP 1 UNTIL SCRNPT5 DO 
        BEGIN                        # UNTIL DONE FOR TITLE LINE #
        IF SPLIT EQ 1 THEN GETCHAR(TITLE1LINE,SCRNPT2,SCRNPT3); 
        ELSE GETCHAR(TITLE2LINE,SCRNPT2,SCRNPT3); 
        GETCHAR(TTYLINE,SCRNPT2,SCRNPT4); 
        IF SCRNPT3 NQ SCRNPT4 AND SCRNPT4 NQ CENDLINE THEN
          BEGIN                      # IF CHARACTER HAS CHANGED # 
          SCRNPT4=XLTINTXP[SCRNPT4];
          IF SCRNPT6 EQ 0 THEN
            BEGIN                    # IF FIRST CHANGE (CHAR. MODE) # 
            IF TABNOTCHAR[0] THEN 
              BEGIN                  # IF ATTRIBUTE IS "EMBEDDED" # 
              VDTPOS(0,SCRNPT1);
              END 
            ELSE
              BEGIN                  # ATTRIBUTE WILL NOT OVERWRITE # 
              VDTPOS(SCRNPT2,SCRNPT1);
              END 
            IF TABVTPROTM[0] THEN 
              BEGIN                  # IF PROTECT AVAILABLE FOR FSE # 
              VDTSAM(MSKPROTECT+MSKUNDERLN);
              END 
            ELSE
              BEGIN                  # NO PROTECT # 
              VDTSAM(MSKUNDERLN); 
              END 
            IF TABNOTCHAR[0] THEN 
              BEGIN                  # IF ATTRIBUTE IS "EMBEDDED" # 
              VDTPOS(SCRNPT2,SCRNPT1);
              END 
            SCRNPT6 = 1;
            END 
          ELSE
            BEGIN                    # NOT FIRST CHANGED CHARACTER #
            IF SCRNPT2 NQ VTXCUR THEN VDTPOS(SCRNPT2,SCRNPT1);
            END 
          VDTCHR(SCRNPT4);
          END 
        END 
      IF NOT TABLOCKMDE[0] THEN 
        BEGIN                        # IF CHARACTER MODE TERMINAL # 
        IF SCRNPT6 EQ 1 THEN
          BEGIN                      # IF CHANGE MADE TO TITLE LINE # 
          IF TABNOTCHAR[0] AND TABATTRCHR[0] THEN 
            BEGIN                    # IF ATTRIBUTE TAKES SPACE # 
            VDTPOS(VTXMAX-1,SCRNPT1); 
            END 
          ELSE
            BEGIN                    # IF ATTRIBUTE TAKES NO SPACE #
            VDTPOS(VTXMAX,SCRNPT1); 
            END 
          VDTSAM(0);
          SCRNPT6 = 0;
          END 
        END 
      ATTRIBMASK[0] = 0;             # CLEAR MASK # 
      FOR SCRNPT2 = 0 STEP 1 UNTIL TTLLNLEN DO
        BEGIN 
        IF SPLIT EQ 1 THEN TITLE1LINE[SCRNPT2]=TTYLINE[SCRNPT2];
        ELSE TITLE2LINE[SCRNPT2]=TTYLINE[SCRNPT2];
        END 
      LTPS(SPLIT)=TOPS(SPLIT);
      LASTNAME[SPLIT]=FILENAM[FILNUM];
      GOTO PTDONE;
  
PTLABEL:  
      VDTSAP(DUMB,0,SCRNPT1);        # SET ATTR POSITION #
      IF NOT TABLOCKMDE[0] THEN 
        BEGIN                        # IF NOT BLOCK MODE #
        VDTCLL(0,SCRNPT1);           # CLEAR LINE # 
        END 
      IF TABVTPROTM[0] THEN VDTSAM(MSKPROTECT); 
      SCRNPT3=1;
      IF SHIFTFKEY NQ 0 AND (SCRNPT1 EQ FKEYROW OR SCRNPT1 EQ FKEYROW+3 
        OR SCRNPT1 EQ FKEYROW+6) THEN SCRNPT3 = -1; 
      IF SCRNPT1 LS FKEYROW+1+SHIFTFKEY THEN SCRNPT4 = 0; 
      ELSE IF SCRNPT1 LS FKEYROW+2*(2+SHIFTFKEY)-1 THEN 
        SCRNPT4 = FKEYSHOW; 
      ELSE SCRNPT4 = FKEYSHOW+FKEYSHOW; 
      FOR SCRNPT2=1 STEP 1 WHILE SCRNPT2 LQ FKEYSHOW
        AND SCRNPT1 NQ FKEYROW+1+SHIFTFKEY
        AND SCRNPT1 NQ FKEYROW+2*(2+SHIFTFKEY)-1 DO 
        BEGIN 
        SCRNPT5 = FKEYNUMS[SCRNPT2+SCRNPT4];
        IF SCRNPT5 EQ 0 THEN SCRNPT3 = -1;
        IF SCRNPT3 GQ 0 THEN
          BEGIN 
          IF SCRNPT5 LS 10 THEN TTSTR("F$");
          TTDEC(SCRNPT5); 
          TTSTR(FKEYSPC1);           # " $" OR "$" #
          END 
        ELSE TTSTR(FKEYSPC2);        # "   $" OR "  $" #
        IF TABVTPROTM[0] THEN 
          BEGIN                      # IF PROTECT AVAILABLE FOR FSE # 
          VDTSAM(MSKPROTECT+MSKINVERSE);
          END 
        ELSE
          BEGIN                      # NO PROTECT # 
          VDTSAM(MSKINVERSE); 
          END 
        IF FKEYPAD GR 0 THEN TTST("      ",FKEYPAD);
        TTST(FKEYNAME[SCRNPT5*SCRNPT3],FKEYCHARS);
        IF FKEYPAD GR 0 THEN TTST("      ",FKEYPAD);
        IF SCRNPT2 NQ FKEYSHOW THEN 
          BEGIN                      # IF NOT FKEYSHOW #
          IF TABVTPROTM[0] THEN 
            BEGIN                    # IF PROTECT AVAILABLE FOR FSE # 
            VDTSAM(MSKPROTECT); 
            END 
          ELSE
            BEGIN                    # NO PROTECT # 
            VDTSAM(0);
            END 
          TTSTR(FKEYSPC1);           # " $" OR "$" #
          END 
        END 
      IF NOT TABLOCKMDE[0] THEN 
        BEGIN                        # IF CHARACTER MODE TERMINAL # 
        IF NOT(TABATTRCHR[0] AND TABLASTPOS[0] EQ CURSORMOVE"SCROLL"
          AND VTYCUR EQ VTYMAX) THEN VDTSAM(0); 
        END 
      ELSE
        BEGIN                        # IF BLOCK MODE TERMINAL # 
        IF SCRNPT1 EQ FKEYROW+1+SHIFTFKEY 
          OR SCRNPT1 EQ FKEYROW+2*(2+SHIFTFKEY)-1 THEN
          VDTCLL(0,SCRNPT1);
        END 
      ATTRIBMASK[0] = 0;             # CLEAR MASK # 
      GOTO PTDONE;
  
PTEMPTY:  
      VDTSAP(DUMB,0,SCRNPT1);        # SET UP AN ATTR BYTE #
      VDTSAM(0);
      VDTCLL(0,SCRNPT1);
      GOTO PTDONE;
  
PTCMD:  
      VDTSAP(DUMB,0,COMMANDROW);     # SET UP AN ATTR BYTE #
      VDTSAM(0);
      VDTCLL(0,COMMANDROW); 
      GOTO PTDONE;
  
PTRESPONSE: 
      VDTSAP(DUMB,0,RESPONSEROW);    # SET ATTRIBUTE POSITION # 
      IF TABLOCKMDE[0] THEN VDTSAM(MSKPROTECT); 
      VDTCLL(0,RESPONSEROW);
      ATTRIBMASK[0] = 0;
                                     # FALL THROUGH TO PTDONE # 
PTDONE: 
  
      END 
    END 
  
  IF ERRCURSOR GQ 0 THEN
    BEGIN 
    XCURSOR=ERRCURSOR;
    IF YCURSOR EQ COMMANDROW THEN 
      BEGIN                          # IF COMMAND ROW # 
      IF TABLOCKMDE[0] THEN 
        BEGIN                        # SET ATTRIBUTE #
        VDTSAP(DUMB,0,COMMANDROW);
        VDTSAM(0);
        END 
      VDTCLL(0,COMMANDROW); 
      FOR SCRNPT2 = 0 STEP 1 UNTIL LENGTH(CMDLIN) - 1  DO 
        BEGIN                        # WRITE COMMAND #
        GETCHAR(CMDLINE,SCRNPT2,SCRNPT3); 
        VDTCHR(XLTINTXP[SCRNPT3]);
        END 
      ROWPAINT[COMMANDROW]=TRUE;
      END 
    END 
  ELSE
    BEGIN                            # NO NEED TO PAINT # 
    IF TABLOCKMDE[0] THEN 
      BEGIN                          # INSURE ATTRIBUTE # 
      VDTSAP(DUMB,0,COMMANDROW);
      VDTSAM(0);
      END 
    END 
  
  IF ERRSTRING NQ " $" THEN 
    BEGIN 
    VDTSAP(DUMB,0,RESPONSEROW); 
    IF TABLOCKMDE[0] THEN VDTSAM(MSKPROTECT); 
    VDTCLL(0,RESPONSEROW);
    TTSTR(ERRSTRING); 
    ATTRIBMASK[0] = 0;
    ROWPAINT[RESPONSEROW]=TRUE; 
    END 
  
  POSZ(CURF(CURFILE));
  IF XCURSOR LS 0 THEN XCURSOR=0; 
  IF XCURSOR GR USRNUMCOL THEN
    BEGIN                            # IF CURSOR OFF EDGE OF SCREEN # 
    XCURSOR=0;
    IF ERRSTRING EQ " $" THEN 
      BEGIN                          # IF NO OTHER ERROR MESSAGE #
      ERRSTRING = "CURSOR RESET FROM BEYOND EDGE OF SCREEN$"; 
      CONTROL IFEQ SINGLE,1;         # IF NOT MULTI USER FSE #
        IF TABLOCKMDE[0] THEN 
          BEGIN 
          VDTSAP(DUMB,0,RESPONSEROW); 
          VDTSAM(MSKPROTECT); 
          END 
      CONTROL FI;                    # END OF NOT MULTI USER FSE #
      VDTCLL(0,RESPONSEROW);
      TTSTR(ERRSTRING); 
      ATTRIBMASK[0] = 0;
      ROWPAINT[RESPONSEROW]=TRUE; 
      END 
    END 
  VDTPOS(XCURSOR,YCURSOR);
  
  IOEND  # PAINTSCREEN #
PAGE                         # GLOBAL LOCATE/CHANGE PROMPT #
  
  
PROC GLOBALPROMPT;
  IOBEGIN(GLOBALPROMPT) 
# 
**        GLOBALPROMPT - ASK QUESTION FOR GLOBAL OPERATIONS.
* 
*         THIS ROUTINE PROVIDES SCREEN FORMATTING AND INTERACTIVE 
*         DIALOGUE FOR THE GENERAL CATEGORY OF GLOBAL SEARCH AND
*         GLOBAL CHANGES.  THESE FUNCTIONS REQUIRE INTERMITTENT 
*         CALLS TO A SCREEN DRIVER WHILE PROCESSING A FILE.  THE
*         ACTUAL PROCESSING CODE INTERFACES TO EITHER GLOBALLOCATE
*         OR GLOBALCHANGE.  THESE ROUTINES PERFORM PRELIMINARY
*         OPERATIONS AND THEN PASS THE CALL TO THIS ROUTINE.  THEN
*         THE INTERFACE ROUTINE ANALYZES THE USERS REPLY. 
* 
*         GLOBALPROMPT HAS THREE BASIC FUNCTIONS.  FIRST, IT DOES 
*         INITIAL SCREEN FORMATTING ON THE FIRST CALL OF THE GLOBAL 
*         OPERATION OR THE FIRST CALL AFTER A DIALOGUE.  SECOND, IT 
*         DISPLAYS EACH LINE OF TEXT AS THEY BECOME AVAILABLE.
*         THIRD, WHEN THE DISPLAY IS FULL OR THE OPERATION IS ABOUT 
*         TO FINISH, GLOBALPROMPT PROMPTS THE USER FOR INSTRUCTIONS.
* 
*         ENTRY  SCRNPT4 - ORDINAL OF PROMPT MESSAGE. 
*                SCREENMODE, PROMPTING - BOTH TRUE TO DO ANYTHING.
*                ROWSUSED - AS INITIALIZED OR LEFT BY PREVIOUS CALL.
*                LINCTR - INDICATES FINAL CALL OF GLOBAL OPERATION. 
*                CURRENT, CURSPLIT, CURFILE, TOPF() - WHERE WE ARE. 
*                COMMANDROW, TITLEROW[ALL], NUMROWS[ALL] - SETUP. 
* 
*         EXIT   SCRNPT5=1 IF PROMPT REALLY OCCURRED, ELSE 0. 
*                TTYLIN - POSSIBLY INPUT TEXT.
*                TMPLIN - OLD VERSION OF TTYLIN IF TTYLIN CHANGED.
*                ROWLNPTR[ALL] - INDICATE WHICH FILE LINE ON ROW. 
*                ROWUSED - UPDATED. 
*                ROWPAINT[THIS SPLIT] - TRUE. 
*                TITLE1LIN, TITLE2LIN - CLEARED.
* 
*         MACROS GETCHAR. 
* 
*         CALLS  VDTCLL, VDTPOS, TTLPAD, TTSTR, VDTCHR, PAINTNONE,
*                COPYLIN, ASKUSER, PAINTSPLIT.
* 
*         USES   P<FROM>, SCRNPT1, SCRNPT2, SCRNPT3, SCRNPT6. 
# 
  ARRAY GLBLMSGS [1:4] S(8);
    BEGIN 
    ITEM GLBLTITLE  C(0,0,40) = [ "LOCATED LINES$", 
      "LOCATED LINES$", "CHANGED LINES$", "CHANGED LINES$" ]; 
    ITEM GLBLPROMPT C(4,0,40) = [ 
      "ENTER LINE NUMBER OR PRESS NEXT$", 
      "ENTER LINE NUMBER OR PRESS NEXT$", 
      "ENTER UNDO OR PRESS NEXT FOR MORE$", 
      "ENTER UNDO OR PRESS NEXT TO END$" ]; 
    END 
  
  SCRNPT5=0;
  
  IF NOT (SCREENMODE AND PROMPTING) THEN IORET
  
  IF ROWSUSED EQ 0 THEN      # INIT DISPLAY      #
    BEGIN 
    VDTCLL(0,COMMANDROW); 
    VDTCLL(0,RESPONSEROW);
    TITLE1LINE[0]=NULLIN; 
    TITLE2LINE[0]=NULLIN; 
    FOR SCRNPT1=0 STEP 1 UNTIL VTYMAX DO ROWLNPTR[SCRNPT1]=0; 
    FOR SCRNPT1=TITLEROW[CURSPLIT] STEP 1 UNTIL 
      TITLEROW[CURSPLIT]+NUMROWS[CURSPLIT] DO VDTCLL(0,SCRNPT1);
    VDTPOS(0,TITLEROW[CURSPLIT]); 
    TTSTR("F$");
    TTLCSTR("ILE $"); 
    TTLFN(FILENAM[SPLITFILE[CURSPLIT]]);
    TTSTR("   D$"); 
    TTLCSTR("ISPLAYING $"); 
    P<FROM>=LOC(GLBLTITLE[SCRNPT4]);
    TTLCSTR(FROM);
    END 
  
  IF LINCTR LS LARGENUM THEN # NOT FINAL CALL    #
    BEGIN 
    ROWSUSED=ROWSUSED+1;
    # PRINT ONE TEXT LINE NEXT POSITION # 
    VDTPOS(0,TITLEROW[CURSPLIT]+ROWSUSED);
    ROWLNPTR[TITLEROW[CURSPLIT]+ROWSUSED]=CURRENT-TOPF(CURFILE);
    TTLPAD(CURRENT-TOPF(CURFILE),7," ");
    TTSTR(" $");
    SCRNPT6 = -1;                    # NUMBER OF BLANKS SO FAR, - 1 # 
    FOR SCRNPT1=0 STEP 1 UNTIL MIN(LENGTH(LIN)-1,VTXMAX-8) DO 
      BEGIN 
      GETCHAR(LINE,SCRNPT1,SCRNPT2);
      IF SCRNPT2 EQ CBLANK THEN 
        BEGIN                       # IF CHARACTER IS A BLANK # 
        SCRNPT6 = SCRNPT6 + 1;
        END 
      ELSE
        BEGIN                        # NOT A BLANK #
        IF SCRNPT6 GQ 0 THEN
          BEGIN                      # IF SOME BLANKS HAVE BEEN SEEN #
          IF SCRNPT6 GQ VTNUMBLNK[0] THEN 
            BEGIN                    # IF AT OR PAST THRESHOLD #
            VDTPOS(SCRNPT1+8,VTYCUR); 
            END 
          ELSE
            BEGIN                    # NOT WORTH VDTPOS # 
            SCRNPT3 = XLTINTXP[CBLANK]; 
            FOR SCRNPT6 = SCRNPT6 STEP -1 UNTIL 0 DO
              BEGIN                  # SEND BLANKS #
              VDTCHR(SCRNPT3);
              END 
            END 
          SCRNPT6 = -1;              # RESET BLANK COUNT #
          END 
        SCRNPT2 = XLTINTXP[SCRNPT2];
        VDTCHR(SCRNPT2);
        END 
      END 
    END 
  
  IF ROWSUSED LS NUMROWS[CURSPLIT] AND LINCTR LS LARGENUM 
    THEN IORET
  
  PAINTNONE;                         # SUPPRESS PAINTSCREEN OUTPUT #
  COPYLIN(TTYLIN,TMPLIN);      # PRESERVE OLD TTYLIN         #
  P<FROM>=LOC(GLBLPROMPT[SCRNPT4]); 
  ASKUSER(FROM,0);
  PROMPTING=TRUE;            # SINCE ASKUSER CLEARS        #
  PAINTSPLIT;                # SO SCREEN WILL BE RE-BUILT  #
  SCRNPT5=1;                 # INDICATE PROMPT ON THIS CYCLE         #
  ROWSUSED=0;                # INDICATE FRESH BATCH NEXT TIME        #
  
  IOEND                       # OF GLOBALPROMPT   # 
  
  
PROC GLOBALLOCATE;
  IOBEGIN(GLOBALLOCATE) 
# 
**        GLOBALLOCATE - GLOBAL LOCATE PROMPTING INTERFACE. 
* 
*         GLOBALLOCATE IS AN INTERFACE BETWEEN THE LOCATE 
*         COMMAND PROCESSING AND THE GLOBALPROMPT ROUTINE.
*         GLOBAL SEARCHES DROP INTO A SECONDARY DISPLAY AND PROMPT. 
*         GLOBALLOCATE USES GLOBALPROMPT FOR CONTROL OVER THE 
*         DISPLAY AND USER'S REPLY, AND PERFORMS ITS OWN
*         ANALYSIS OF REPLIES.  GLOBALLOCATE CAN DIRECT THE COMMAND 
*         DRIVER TO SHUTDOWN THE SEARCH ON USER REQUEST.
* 
*         ENTRY  LINCTR - INDICATES LAST CALL OF OPERATION. 
*                CURRENT, CURSPLIT, CURFILE, TOPF() - WHERE WE ARE. 
* 
*         EXIT   LINCTR=LARGENUM FOR USER-REQUESTED SHUTDOWN. 
*                CURRENT - POSSIBLY MOVED.
* 
*         MACROS GETCHAR. 
* 
*         CALLS  GLOBALPROMPT, WINDOLIN, POSZ.
* 
*         USES   TTYLIN, SCRNPT4, SCRNPT5.
# 
  ITEM TMP1, TMP2, TMP3;     # USE INSTANTLY     #
  
  SCRNPT4=1;                 # INDICATE MESSAGE SELECTION  #
  IF LINCTR EQ LARGENUM THEN SCRNPT4=2; 
  GLOBALPROMPT; 
  IF SCRNPT5 EQ 0 THEN IORET        # IF NO REPLY YET # 
  
  # EXIT IMMEDIATELY IF USER ESCAPING WITH FKEY # 
  IF ESCAPE THEN IORET
  
  TMP1=-1;                   # SEE IF NUMERIC REPLY        #
  FOR TMP2=0 STEP 1 UNTIL LENGTH(TTYLIN)-1 DO 
    BEGIN 
    GETCHAR(TTYLINE,TMP2,TMP3); 
    IF TMP3 GQ CDIGIT0 AND TMP3 LQ CDIGIT9 THEN 
      BEGIN 
      IF TMP1 LS 0 THEN TMP1=0; 
      TMP1=TMP1*10 + TMP3-CDIGIT0;
      END 
    END 
  
  IF TMP1 LS 0 AND YCURSOR GR 0 AND ROWLNPTR[YCURSOR-1] NQ 0
    THEN TMP1=ROWLNPTR[YCURSOR-1];     # IF CURSOR POINTED #
  
  IF TMP1 GQ 0 THEN          # STOP ON SIGNIFICANT REPLY   #
    BEGIN 
    LINCTR=LARGENUM;         # TO STOP DORANGE   #
    TMP1=TMP1+TOPF(CURFILE);
    WINDOLIN(TMP1,CURFILE); 
    POSZ(TMP1); 
    END 
  
  IOEND                       # OF GLOBALLOCATE   # 
  
  
PROC GLOBALCHANGE;
  IOBEGIN(GLOBALCHANGE) 
# 
**        GLOBALCHANGE - GLOBAL CHANGE PROMPTING INTERFACE. 
* 
*         ENTRY  LINCTR - INDICATES LAST CALL OF OPERATION. 
*                CURRENT, CURSPLIT, CURFILE, TOPF() - WHERE WE ARE. 
* 
*         EXIT   LINCTR=LARGENUM FOR USER-REQUESTED SHUTDOWN. 
*                CMDLIN - POSSIBLY UNDO COMMAND.
* 
*         MACROS GETCHAR. 
* 
*         CALLS  GLOBALPROMPT, EXCHWD, DSPLCOD, STARTCMD. 
* 
*         USES   TMPLIN, SCRNPT4, SCRNPT5.
* 
*         NOTE   TTYLIN USED WITH RESTORATION.
# 
  
  ITEM TMP1, TMP2, TMP3;     # USE INSTANTLY     #
  
  IF NOT (SCREENMODE AND PROMPTING) THEN IORET   # EFFICIENT         #
  
  SCRNPT4=3;                 # INDICATE MESSAGE SELECTION  #
  IF LINCTR EQ LARGENUM THEN SCRNPT4=4; 
  GLOBALPROMPT; 
  IF SCRNPT5 EQ 0 THEN IORET    # LEAVE IF NO REPLY YET # 
  
  # GET OUT IF USER ESCAPING WITH FKEY #
  IF ESCAPE THEN IORET
  
  EXCHWD(BUFWIDP1,TTYLIN,TMPLIN);      # TTYLIN AS WAS, TMPLIN=INPUT #
  TMP1=-1;                   # SEARCH FOR ALPHABETIC REPLY #
  FOR TMP2=0 STEP 1 UNTIL LENGTH(TMPLIN)-1 DO 
    BEGIN 
    GETCHAR(TMPLINE,TMP2,TMP3); 
    DSPLCOD(TMP3);
    IF TMP1 LS 0 AND TMP3 GQ CLETTERA AND TMP3 LQ CLETTERZ
      THEN TMP1=TMP3; 
    END 
  IF TMP1 EQ "U" THEN 
    BEGIN 
    LINCTR=LARGENUM;         # TO STOP DORANGE   #
    SETCHAR(CMDLINE,0,CLETTERU);       # CREATE UNDO COMMAND         #
    SETCHAR(CMDLINE,1,CENDLINE);
    STARTCMD; 
    END 
  
  IOEND                       # OF GLOBALCHANGE   # 
PAGE                         # GENERAL LINE TO SCREEN DISPLAYS       #
  
# 
**        DEDICATED DISPLAY DRIVERS.
* 
*         BGNDSPLAY, ENDDSPLAY, AND EOLDSPLAY PROVIDE A GENERAL 
*         MECHANISM FOR COMMAND PROCESSORS IN THE EDITOR TO 
*         OVERRIDE THE NORMAL DISPLAY AND DISPLAY SPECIALIZED 
*         INFORMATION.  AT THE CURRENT TIME, THESE ROUTINES ARE 
*         COMPILED ONLY IN THE SINGLE-USER VERSION OF THE EDITOR
*         DUE TO THEIR LIMITED SCOPE OF NEED. 
* 
*         THE CALLER USES BGNDSPLAY TO TAKE OVER THE SCREEN,
*         THEN USES ANY OF THE FSEFORM ROUTINES TO FORMAT EACH
*         LINE OF TEXT, CALLING EOLDSPLAY TO ADVANCE THE CURSOR 
*         BETWEEN LINES.  THE DISPLAY IS COMPLETED BY ENDDSPLAY.
*         NOTE THAT EOLDSPLAY INCLUDES LOGIC TO TURN PAGES. 
# 
  
CONTROL IFEQ SINGLE,1;
  
  PROC BGNDSPLAY; 
# TITLE BGNDSPLAY - INTIALIZE DEDICATED DISPLAY FORMAT. # 
  
    BEGIN  # BGNDSPLAY #
  
# 
**        BGNDSPLAY - INITIALIZE DEDICATED DISPLAY FORMAT.
* 
*         PROC BGNDSPLAY
* 
*         ENTRY  SCREENMODE - ON FOR NON-TRIVIAL OPERATION. 
* 
*         EXIT   SCRNPT1 - INITIALIZED AS PAGE COUNTER. 
*                SCREEN CLEARED, CURSOR POSITIONED. 
*                TITLE1LIN, TITLE2LIN - CLEARED.
* 
*         CALLS  PAINTNONE, VDTCLS, VDTPOS. 
# 
  
    IF SCREENMODE THEN
      BEGIN 
      IF SPLITFILE[2] NQ 0 THEN 
        BEGIN                        # IF IN SPLIT SCREEN MODE #
        IF CURSPLIT EQ 1 THEN 
          BEGIN                      # IF FIRST SPLIT IS CURRENT #
          CURSPLIT = 2;              # CLEAR FOR OTHER SPLIT #
          PAINTNONE;
          CURSPLIT = 1;              # RESET #
          END 
        ELSE
          BEGIN                      # CURRENT SPLIT IN THE SECOND #
          CURSPLIT = 1;              # CLEAR FOR OTHER SPLIT #
          PAINTNONE;
          CURSPLIT = 2;              # RESET #
          END 
        END 
      PAINTNONE;
      VDTCLS; 
      TITLE1LINE[0]=NULLIN; 
      TITLE2LINE[0]=NULLIN; 
      SCRNPT1=TITLEROW[1];
      VDTPOS(0,SCRNPT1);
      END 
  
    END  # BGNDSPLAY #
  
  
  PROC ENDDSPLAY; 
    BEGIN 
# 
**        ENDDSPLAY - TERMINATE SPECIAL DISPLAY SEQUENCE. 
* 
*         EXIT   ROWPAINT[ALL] - TRUE.
* 
*         CALLS  EOLDSPLAY, PAINTALL. 
* 
*         USES   SCRNPT1. 
# 
    SCRNPT1=VTYMAX; 
    EOLDSPLAY;
    PAINTALL; 
    END                       # OF ENDDSPLAY      # 
  
  
  PROC EOLDSPLAY; 
    BEGIN 
# 
**        EOLDSPLAY - LINE BY LINE CONTROL FOR SPECIAL DISPLAYS.
* 
*         ENTRY  SCREENMODE - TRUE FOR NON-TRIVIAL OPERATION. 
*                SCRNPT1 - AS INITIALIZED BY BGNDSPLAY OR INCREMENTED 
*                    IN LAST CALL TO EOLDSPLAY. 
* 
*         EXIT   SCRNPT1 - INCREMENTED OR RE-INITIALIZED. 
*                CURSOR MOVED TO NEXT LINE. 
* 
*         CALLS  ASKUSER, BGNDSPLAY, VDTPOS, TTBRK. 
* 
*         USES   SCRNPT2. 
# 
    IF SCREENMODE THEN
      BEGIN 
      SCRNPT1=SCRNPT1+1;
      SCRNPT2=USRNUMLIN;
      IF SCRNPT2 EQ COMMANDROW THEN SCRNPT2=SCRNPT2-1;
      IF SCRNPT1 GR SCRNPT2 THEN
        BEGIN 
        ASKUSER("PRESS NEXT TO CONTINUE$",0); 
        BGNDSPLAY;
        END 
      ELSE VDTPOS(0,SCRNPT1); 
      END 
    ELSE TTBRK; 
    END                       # OF EOLDSPLAY      # 
  
CONTROL FI; 
PAGE                         # SCREEN SETUP/MANIPULATION   #
  
  
PROC PAINTALL;
  BEGIN 
# 
**        PAINTALL - SET PAINT BITS ON ALL LINES. 
* 
*         EXIT   ROWPAINT[ALL] - TRUE.
* 
*         CALLS  PAINTREST. 
# 
  PAINTREST(0); 
  END                        # OF PAINTALL     #
  
  
PROC PAINTNONE; 
  BEGIN 
# 
**        PAINTNONE - CLEAR PAINT BITS FOR ONE SPLIT. 
* 
*         ENTRY  CURSPLIT - WHICH SPLIT TO SUPPRESS PAINT.
*                TITLEROW[1-2], NUMROWS[1-2] - SETUP. 
* 
*         EXIT   ROWPAINT[ALL IN SPLIT] - FALSE.
*                ROWORIG[ALL IN SPLIT] - NOMINAL. 
# 
  FOR SCRNPT1=TITLEROW[CURSPLIT] STEP 1 UNTIL 
    TITLEROW[CURSPLIT]+NUMROWS[CURSPLIT] DO 
    BEGIN                     # SUPPRESS PAINTSCREEN OUTPUT # 
    ROWPAINT[SCRNPT1]=FALSE;
    ROWORIG[SCRNPT1]=SCRNPT1; 
    END 
  END                         # OF PAINTNONE      # 
  
  
PROC PAINTREST(PARM); 
# TITLE PAINTREST - SET PAINT BITS FOR REST OF SCREEN. #
  
  BEGIN  # PAINTREST #
  
# 
**        PAINTREST - SET PAINT BITS FOR REST OF SCREEN.
* 
*         PROC PAINTREST(PARM)
* 
*         ENTRY  PARM - FIRST LINE TO SET BIT FOR.
*                VTYMAX - LAST LINE.
* 
*         EXIT   ROWPAINT[THOSE] - TRUE.
# 
  
  ITEM PARM      I;                  # FIRST LINE # 
  ITEM TMP1      I;                  # TEMPORARY STORAGE #
  
  FOR TMP1=PARM STEP 1 UNTIL VTYMAX DO
    BEGIN 
    ROWPAINT[TMP1]=TRUE;
    IF ROWTYPE[TMP1] EQ ROWST"TITLE" THEN 
      BEGIN 
      IF ROWSPLIT[TMP1] EQ 1 THEN TITLE1LINE[0]=NULLIN; 
      ELSE TITLE2LINE[0]=NULLIN;
      END 
    END 
  
  END  # PAINTREST #
  
  
PROC PAINTSPLIT;
# TITLE PAINTSPLIT - SET PAINT BITS ALL LINES ONE SPLIT. #
  
  BEGIN  # PAINTSPLIT # 
  
# 
**        PAINTSPLIT - SET PAINT BITS ALL LINES ONE SPLIT.
* 
*         PROC PAINTSPLIT 
* 
*         ENTRY  CURSPLIT - WHICH SPLIT TO PAINT. 
*                TITLEROW[1-2], NUMROWS[1-2] - SETUP. 
* 
*         EXIT   ROWPAINT[ALL IN SPLIT] - TRUE. 
* 
*         CALLS  PAINTONESPLT.
# 
  
  PAINTONESPLT(CURSPLIT); 
  
  END  # PAINTSPLIT # 
  
  
PROC PAINTONESPLT(SPLIT); 
# TITLE PAINTONESPLT - SET PAINT BITS ALL LINES ONE SPLIT. #
  
  BEGIN  # PAINTONESPLT # 
  
# 
**        PAINTONESPLT - SET PAINT BITS ALL LINES ONE SPLIT.
* 
*         PROC PAINTONESPLT(SPLIT)
* 
*         ENTRY  SPLIT - WHICH SPLIT TO PAINT.
*                TITLEROW[1-2], NUMROWS[1-2] - SETUP. 
* 
*         EXIT   ROWPAINT[ALL IN SPLIT] - TRUE. 
# 
  
  ITEM SPLIT;                        # WHICH SPLIT TO PAINT # 
  ITEM TMP1;                         # TEMPORARY STORAGE #
  
  FOR TMP1=TITLEROW[SPLIT] STEP 1 UNTIL 
    TITLEROW[SPLIT]+NUMROWS[SPLIT] DO ROWPAINT[TMP1]=TRUE;
  
  END  # PAINTONESPLT # 
  
  
PROC SETUPSCREEN(I,J,K);
  BEGIN 
# 
**        SETUPSCREEN - INITIALIZE ALL SCREEN FORMAT CONTROLS.
* 
*         ENTRY  I - FILE BRACKET NUMBER FOR SPLIT 1. 
*                J - FILE BRACKET NUMBER FOR SPLIT 2. 
*                K - NUMBER OF DATA LINES IN BOTTOM SPLIT.
*                TABVTHOMEU[0] - CONTROLS SELECTION OF COMMANDROW.
*                FKEYNUMROW - WHETHER TO INCLUDE FUNCTION KEY DISPLAY.
* 
*         EXIT   COMMANDROW, FKEYROW - SETUP. 
*                TITLEROW[1-2], NUMROWS[1-2] - SETUP. 
*                TOPS(1-2), BOTS(1-2) - SETUP.
*                ALL ROW CONTROLS SETUP.
* 
*         CALLS  SETTOPBOTS, SETROWTYPE.
* 
*         USES   SCRNPT1, SCRNPT2.
# 
  ITEM I,J,K; 
  ITEM NKEYS, NTITLES;
  
  
  PROC SETROWSPLIT; 
# TITLE SETROWSPLIT - INITIALIZE ROWSPLIT VECTOR. # 
  
    BEGIN  # SETROWSPLIT #
  
# 
**        SETROWSPLIT - INITIALIZE ROWSPLIT VECTOR. 
* 
*         PROC SETROWSPLIT
* 
*         ENTRY  CURSPLIT - WHICH SPLIT.
*                TITLEROW[1-2], NUMROWS[1-2] - SETUP. 
* 
*         EXIT   ROWTYPE[ALL IN SPLIT] - INITIALIZED. 
*                ROWSPLIT[ALL IN SPLIT] - INITIALIZED.
* 
*         CALLS  PAINTSPLIT.
* 
*         USES   SCRNPT1, SCRNPT5.
# 
  
    IF ROWTYPE[TITLEROW[CURSPLIT]] NQ ROWST"TITLE"
      OR ROWSPLIT[TITLEROW[CURSPLIT]] NQ CURSPLIT THEN
      BEGIN 
      PAINTSPLIT; 
      IF CURSPLIT EQ 1 THEN TITLE1LINE[0]=NULLIN; 
      ELSE TITLE2LINE[0]=NULLIN;
      END 
    ROWTYPE[TITLEROW[CURSPLIT]]=ROWST"TITLE"; 
    ROWSPLIT[TITLEROW[CURSPLIT]]=CURSPLIT;
    FOR SCRNPT1=1 STEP 1 UNTIL NUMROWS[CURSPLIT] DO 
      BEGIN 
      SCRNPT5=SCRNPT1+TITLEROW[CURSPLIT]; 
      IF ROWTYPE[SCRNPT5] NQ ROWST"TEXT"
        OR ROWSPLIT[SCRNPT5] NQ CURSPLIT THEN ROWPAINT[SCRNPT5]=TRUE; 
      ROWTYPE[SCRNPT5]=ROWST"TEXT"; 
      ROWSPLIT[SCRNPT5]=CURSPLIT; 
      END 
  
    END  # SETROWSPLIT #
  
  
  PROC SETROWTYPE;
    BEGIN 
# 
**        SETROWTYPE - CLASSIFY LINES BY TYPE OF DISPLAY. 
* 
*         ENTRY  COMMANDROW, RESPONSEROW, TITLEROW[1-2],
*                FKEYROW, SPLITFILE[1-2] - INITIALIZED. 
*                VTYMAX - NUMBER OF LINES ON SCREEN.
* 
*         EXIT   ROWTYPE[ALL] - INITIALIZED.
*                ROWSPLIT[ALL] - INITIALIZED. 
*                CURSPLIT - INITIALIZED.
* 
*         CALLS  SETROWSPLIT. 
* 
*         USES   SCRNPT1, SCRNPT2, SCRNPT3. 
# 
    ROWTYPE[COMMANDROW]=ROWST"COMMAND"; 
    ROWSPLIT[COMMANDROW]=1; 
    ROWTYPE[RESPONSEROW] = ROWST"RESPONSE"; 
  
    CURSPLIT=1; 
    SETROWSPLIT;
    IF SPLITFILE[2] NQ 0 THEN 
      BEGIN 
      CURSPLIT=2; 
      SETROWSPLIT;
      END 
  
    IF FKEYNUMROW EQ 0 THEN SCRNPT1=-1; 
    ELSE SCRNPT1=FKEYNUMROW*(2+SHIFTFKEY)-2;
    FOR SCRNPT2=0 STEP 1 UNTIL SCRNPT1 DO 
      BEGIN 
      IF ROWTYPE[FKEYROW+SCRNPT2] NQ ROWST"LABEL" THEN
        BEGIN 
        ROWPAINT[FKEYROW+SCRNPT2]=TRUE; 
        ROWTYPE[FKEYROW+SCRNPT2]=ROWST"LABEL";
        END 
      END 
    SCRNPT1=FKEYROW+SCRNPT1+1;
    SCRNPT3=VTYMAX; 
    IF COMMANDROW EQ VTYMAX THEN SCRNPT3=VTYMAX-1;
    FOR SCRNPT2=SCRNPT1 STEP 1 UNTIL SCRNPT3 DO 
      BEGIN 
      # BLANK OUT BOTTOM OF SCREEN IF USER REQUESTED SHORT SCREEN # 
      IF ROWTYPE[SCRNPT2] NQ ROWST"EMPTY" THEN ROWPAINT[SCRNPT2]=TRUE;
      ROWTYPE[SCRNPT2]=ROWST"EMPTY";
      END 
  
    END                              # OF SETROWTYPE #
  
  
  # ACTUAL SETUPSCREEN MAIN CODE STARTS HERE #
  
  IF NOT SCREENMODE THEN RETURN;
  
  IF TABVTHOMEU[0] THEN 
    BEGIN 
    COMMANDROW=0; 
    RESPONSEROW=1;
    TITLEROW[1]=2;
    END 
  ELSE
    BEGIN 
    COMMANDROW=VTYMAX;
    RESPONSEROW = VTYMAX-1; 
    TITLEROW[1]=0;
    END 
  
  SPLITFILE[1]=I; 
  SPLITFILE[2]=J; 
  
  SFKEYDEFS = 0;
  SCRNPT1 = 1;
  FOR SCRNPT2 = 1 STEP 1 UNTIL POSFKEYS DO
    BEGIN 
    IF (FKEYNAME[SCRNPT2] NQ " ") OR
       (FKEYNAME[-SCRNPT2] NQ " ") THEN 
      BEGIN                          # IF FUNCTION KEY DEFINED #
      FKEYNUMS[SCRNPT1] = SCRNPT2;
      SCRNPT1 = SCRNPT1 + 1;
      IF FKEYNAME[-SCRNPT2] NQ " " THEN SFKEYDEFS = 1;
      END 
    END 
  FOR SCRNPT1 = SCRNPT1 STEP 1 UNTIL POSFKEYS DO
    FKEYNUMS[SCRNPT1] = 0;
  SHIFTFKEY = SFKEYDEFS LAN SFKEYSHOW;
  NKEYS=MAX(0,FKEYNUMROW*(2+SHIFTFKEY)-1);
  FKEYROW = USRNUMLIN + TITLEROW[1] - (NKEYS + 1);
  
  NUMROWS[1]=0; 
  IF K LS 0 THEN NUMROWS[2]=(USRNUMLIN-2-NKEYS)/2;
  ELSE NUMROWS[2]=MIN(K,(USRNUMLIN-2-NKEYS)); 
  
  IF J EQ 0 THEN NTITLES=1; 
  ELSE NTITLES=2; 
  
  IF I NQ 0 THEN
    BEGIN 
    NUMROWS[1]=USRNUMLIN-NKEYS-NTITLES-NUMROWS[2]-1;
    SETTOPBOTS(1);
    END 
  IF J NQ 0 THEN
    BEGIN 
    TITLEROW[2]=USRNUMLIN-NKEYS-NUMROWS[2]-2+TITLEROW[1]; 
    SETTOPBOTS(2);
    END 
  ELSE TITLEROW[2]=TITLEROW[1]+NUMROWS[1];
  SETROWTYPE; 
  IF TABLOCKMDE[0] OR TABATTRCHR[0] THEN
    BEGIN                            # IF ATTRIBUTE TAKES A POSITION #
    IF TABLOCKMDE[0] THEN ATTCOUNT = 1; 
    FKEYSPC1 = "$"; 
    FKEYSPC2 = "  $"; 
    END 
  ELSE
    BEGIN                            # CHARACTER MODE TERMINAL #
    ATTCOUNT = 0;                    # NO ATTRIBUTE BYTE #
    FKEYSPC1 = " $";
    FKEYSPC2 = "   $";
    END 
  END                            #  OF SETUPSCREEN  # 
  
CONTROL IFEQ SINGLE,1;
  PROC CLEARSCREEN; 
# TITLE CLEARSCREEN - GET BACK TO LINE MODE. #
  
    BEGIN  # CLEARSCREEN #
  
# 
**        CLEARSCREEN - GET BACK TO LINE MODE.
* 
*         EXIT   SCREEN CLEARED.
*                VIRTERM SHUT DOWN VIA VDTSTM ROUTINE.
*                ALL PAINT BITS TRUE. 
* 
*         CALLS  PAINTALL, VDTCLS, VDTSTM.
* 
*         USES   SCRNPT1. 
# 
  
    IF SCREENMODE THEN
      BEGIN 
      VDTCLS; 
      PAINTALL; 
      VDTSTM(0,SCRNPT1);             # SET LINE MODE #
      ATTCOUNT = 0;                  # CLEAR ATTRIBUTE BYTE COUNT # 
      END 
  
    END  # CLEARSCREEN #
CONTROL FI; 
PAGE                      # EDITOR/WORKIO/SCREEN INTERFACE #
  
  
PROC SETTOPBOTS(SPLIT); 
# TITLE SETTOPBOTS - FORCE TOPS AND BOTS TO BRACKET CURRENT. #
  
  BEGIN  # SETTOPBOTS # 
  
# 
**        SETTOPBOTS - FORCE TOPS AND BOTS TO BRACKET CURRENT.
* 
*         SETTOPBOTS ASSURES THAT TOPS AND BOTS ARE WITHIN LEGAL
*         FILE BOUNDARIES AND THAT THEY BRACKET THE CURRENT LINE. 
*         IF THESE CONDITIONS ARE ALREADY TRUE, NOTHING IS CHANGED. 
*         ELSE WE BUILD NEW SPLIT STARTING AT CURRENT LINE. 
* 
*         PROC SETTOPBOTS(SPLIT)
* 
*         ENTRY  SPLIT - WHICH SPLIT. 
*                SPLITFILE[SPLIT] - SETUP.
*                CURF(SPLITFILE[SPLIT]) - CURRENT LINE. 
*                TOPS(SPLIT), BOTS(SPLIT) - POSSIBLY ALREADY VALID. 
* 
*         EXIT   TOPS(SPLIT), BOTS(SPLIT) - GUARANTEED VALID. 
*                ROWPAINT[ALL THIS SPLIT] - POSSIBLY TRUE.
* 
*         CALLS  SETTOPS, SETBOTS, PAINTONESPLT.
# 
  
  ITEM SPLIT     I;                  # WHICH SPLIT #
  ITEM L         I;                  # LINE # 
  
  SETTOPS(SPLIT); 
  SETBOTS(SPLIT); 
  L=CURF(SPLITFILE[SPLIT]); 
  L=MAX(L,TOPF(SPLITFILE[SPLIT])+1);
  L=MIN(L,BOTF(SPLITFILE[SPLIT])-1);
  IF L LQ TOPS(SPLIT) OR L GQ BOTS(SPLIT) THEN
    BEGIN 
    TOPS(SPLIT)=L-1;
    SETTOPS(SPLIT); 
    SETBOTS(SPLIT); 
    IF BOTS(SPLIT) GR TOPS(SPLIT)+1 THEN PAINTONESPLT(SPLIT); 
    END 
  
  END  # SETTOPBOTS # 
  
  
PROC SETTOPS(SPLIT);
  BEGIN 
# 
**        SETTOPS - ASSURE TOPS() IS IN FILE BOUNDS.
* 
*         ENTRY  SPLIT - WHICH SPLIT. 
*                SPLITFILE[SPLIT] - WHICH FILE. 
*                TOPF(FILE), BOTF(FILE) - FILE BOUNDARIES.
* 
*         EXIT   TOPS(SPLIT) - GUARANTEED IN BOUNDS.
# 
  ITEM SPLIT; 
  TOPS(SPLIT)=MIN(TOPS(SPLIT),BOTF(SPLITFILE[SPLIT])-2);
  TOPS(SPLIT)=MAX(TOPS(SPLIT),TOPF(SPLITFILE[SPLIT]));
  END                         # OF SETTOPS        # 
  
  
PROC SETBOTS(SPLIT);
  BEGIN 
# 
**        SETBOTS - SET BOTS() BY TOPS() AND FILE BOUNDS. 
* 
*         ENTRY  SPLIT - WHICH SPLIT. 
*                SPLITFILE[SPLIT] - WHICH FILE BRACKET. 
*                TOPS(SPLIT), BOTF(FILE) - SETUP. 
* 
*         EXIT   BOTS(SPLIT) - DEFINED. 
# 
  ITEM SPLIT; 
  BOTS(SPLIT)=MIN(TOPS(SPLIT)+NUMROWS[SPLIT]+1,BOTF(SPLITFILE[SPLIT])); 
  END                      # OF SETBOTS                 # 
  
  
PROC REPX;
  IOBEGIN(REPX) 
# 
**        REPX - INTERFACE FOR LINE REPLACEMENT.
* 
*         REPX IS CALLED BY ANY ROUTINE IN THE EDITOR WHICH IS
*         REPLACING A TEXT LINE IN THE WORKFILE.  NOTE THAT WE
*         DEFINE TEXT LINES AS LINES WITHIN FILE BRACKETS.  THIS
*         DOES NOT INCLUDE LINES IN THE AUDIT TRAIL OR IN THE 
*         FILE DIRECTORY. 
* 
*         REPX ASSURES THAT ANY SCREEN DISPLAY OF THE LINE IS 
*         FLAGGED FOR REPAINT WHEN NEEDED.  REPAINT IS NOT NEEDED 
*         FOR CHANGES MADE BY THE DOSCREEN ROUTINE TO MIMIC TERMINAL
*         HARDWARE CAPABILITIES.  THIS IS DENOTED BY THE HARDFN FLAG. 
* 
*         LOGIC FOR THIS ROUTINE MUST CHECK SCREEN BOUNDARIES SINCE 
*         CHANGES CAN BE MADE OFF-SCREEN.  ALSO MUST CHECK FOR OVER-
*         LAPPED SPLITS OF SAME FILE - EVEN IF CHANGE CAME AS A 
*         HARD FUNCTION, THE OVERLAPPED VERSON STILL NEEDS PAINTING.
* 
*         ENTRY  LIN - THE LINE IMAGE AS CHANGED. 
*                CURRENT, CURSPLIT, CURFILE - WHERE WE ARE. 
*                HARDFN - TRUE IF MIMIC-ING WHAT HARDWARE ALREADY DID.
*                TOPS(BOTH), BOTS(BOTH) - BRACKET THE LINES ON DISPLAY. 
*                SCREENMODE - TRUE FOR NON-TRIVIAL OPERATION. 
* 
*         EXIT   ROWPAINT[RIGHT ROWS] - SET TRUE IF NEEDED. 
*                WORKFILE ACCESS METHOD CALLED TO MANAGE UPDATE.
* 
*         CALLS  REPS (INTERNAL), REPZ. 
# 
  
   PROC REPS(SPLIT);
     BEGIN
# 
**        REPS - INTERNAL LOGIC FOR REPX. 
* 
*         NOTE   SEE HEADER FOR REPX. 
# 
     ITEM SPLIT;
     IF CURRENT GR TOPS(SPLIT) AND CURRENT LS BOTS(SPLIT) 
       AND (SPLIT NQ CURSPLIT OR NOT HARDFN)
       THEN ROWPAINT[LTOY(CURRENT,SPLIT)]=TRUE; 
     END                     # OF REPS            # 
  
  # ACTUAL REPX CODE STARTS HERE #
  REPZ; 
  IF SCREENMODE THEN
    BEGIN 
    REPS(1);
    REPS(2);
    END 
  IOEND                    # OF REPX            # 
  
  
PROC INSX;
  IOBEGIN(INSX) 
# 
**        INSX - INTERFACE FOR LINE INSERTION.
* 
*         INSX IS CALLED BY ANY ROUTINE IN THE EDITOR WHICH IS
*         INSERTING A TEXT LINE IN THE WORKFILE.  NOTE THAT WE
*         DEFINE TEXT LINES AS LINES WITHIN FILE BRACKETS.  THIS
*         DOES NOT INCLUDE LINES IN THE AUDIT TRAIL OR IN THE 
*         FILE DIRECTORY. 
* 
*         INSX ASSURES THAT ANY SCREEN DISPLAY OF THE LINE IS 
*         FLAGGED FOR REPAINT WHEN NEEDED.  REPAINT IS NOT NEEDED 
*         FOR CHANGES MADE BY THE DOSCREEN ROUTINE TO MIMIC TERMINAL
*         HARDWARE CAPABILITIES.  THIS IS DENOTED BY THE HARDFN FLAG. 
* 
*         LOGIC FOR THIS ROUTINE MUST CHECK SCREEN BOUNDARIES SINCE 
*         CHANGES CAN BE MADE OFF-SCREEN.  ALSO MUST CHECK FOR OVER-
*         LAPPED SPLITS OF SAME FILE - EVEN IF CHANGE CAME AS A 
*         HARD FUNCTION, THE OVERLAPPED VERSON STILL NEEDS PAINTING.
* 
*         ENTRY  LIN - THE LINE IMAGE TO BE INSERTED. 
*                CURRENT, CURSPLIT, CURFILE - WHERE WE ARE. 
*                HARDFN - TRUE IF MIMIC-ING WHAT HARDWARE ALREADY DID.
*                TOPS(BOTH), BOTS(BOTH) - BRACKET THE LINES ON DISPLAY. 
*                SCREENMODE - TRUE FOR NON-TRIVIAL OPERATION. 
*                TABVTPROTM[0] - TERMINAL CAPABILITY TO PROTECT FIELDS. 
* 
*         EXIT   ROWPAINT[RIGHT ROWS] - SET TRUE IF NEEDED. 
*                ROWPAINT[LOWER], ROWBITS[LOWER] - PROPOGATED AS NEEDED.
*                WORKFILE ACCESS METHOD CALLED TO MANAGE UPDATE.
* 
*         CALLS  INSS (INTERNAL), INSZ. 
# 
  
  PROC INSS(SPLIT); 
    BEGIN 
# 
**        INSS - INTERNAL LOGIC FOR INSX. 
* 
*         NOTE   SEE HEADER FOR INSX. 
# 
    ITEM SPLIT, I, THISROW, LASTROW;
    IF SPLITFILE[SPLIT] NQ 0 THEN 
      BEGIN 
      IF CURRENT GR TOPF(SPLITFILE[SPLIT]) AND
         CURRENT LS BOTF(SPLITFILE[SPLIT]) THEN 
        BEGIN 
        SETBOTS(SPLIT); 
        IF CURRENT GR TOPS(SPLIT) AND CURRENT LS BOTS(SPLIT) THEN 
          BEGIN 
          THISROW=LTOY(CURRENT,SPLIT);
          LASTROW=TITLEROW[SPLIT]+NUMROWS[SPLIT]; 
          FOR I=LASTROW STEP -1 UNTIL THISROW+1 DO
            BEGIN 
            ROWPAINT[I]=ROWPAINT[I-1];
            ROWBITS[I]=ROWBITS[I-1];
            END 
          IF HARDFN AND SPLIT EQ CURSPLIT THEN
            BEGIN 
            IF NOT TABVTPROTM[0] THEN PAINTREST(LASTROW+1); 
            END 
          ELSE
            BEGIN 
            FOR I=LASTROW STEP -1 UNTIL THISROW+1 
              DO ROWORIG[I]=ROWORIG[I-1]; 
            ROWORIG[THISROW]=0; 
            END 
          END 
        END 
      END 
    END                    # OF INSS              # 
  
  # ACTUAL INSX CODE STARTS HERE #
  INSZ; 
  IF SCREENMODE THEN
    BEGIN 
    INSS(1);
    INSS(2);
    END 
  IOEND                   # OF INSX              #
  
  
PROC DELX;
  IOBEGIN(DELX) 
# 
**        DELX - INTERFACE FOR LINE DELETION. 
* 
*         DELX IS CALLED BY ANY ROUTINE IN THE EDITOR WHICH IS
*         DELETEING A TEXT LINE IN THE WORKFILE.  NOTE THAT WE
*         DEFINE TEXT LINES AS LINES WITHIN FILE BRACKETS.  THIS
*         DOES NOT INCLUDE LINES IN THE AUDIT TRAIL OR IN THE 
*         FILE DIRECTORY. 
* 
*         DELX ASSURES THAT ANY SCREEN DISPLAY OF THE LINE IS 
*         FLAGGED FOR REPAINT WHEN NEEDED.  REPAINT IS NOT NEEDED 
*         FOR CHANGES MADE BY THE DOSCREEN ROUTINE TO MIMIC TERMINAL
*         HARDWARE CAPABILITIES.  THIS IS DENOTED BY THE HARDFN FLAG. 
* 
*         LOGIC FOR THIS ROUTINE MUST CHECK SCREEN BOUNDARIES SINCE 
*         CHANGES CAN BE MADE OFF-SCREEN.  ALSO MUST CHECK FOR OVER-
*         LAPPED SPLITS OF SAME FILE - EVEN IF CHANGE CAME AS A 
*         HARD FUNCTION, THE OVERLAPPED VERSON STILL NEEDS PAINTING.
* 
*         ENTRY  LIN - THE LINE IMAGE TO BE DELETED.
*                CURRENT, CURSPLIT, CURFILE - WHERE WE ARE. 
*                HARDFN - TRUE IF MIMIC-ING WHAT HARDWARE ALREADY DID.
*                TABVTPROTM[0] - TERMINAL CAPABILITY TO PROTECT FIELDS. 
*                TOPS(BOTH), BOTS(BOTH) - BRACKET THE LINES ON DISPLAY. 
*                SCREENMODE - TRUE FOR NON-TRIVIAL OPERATION. 
* 
*         EXIT   ROWPAINT[RIGHT ROWS] - SET TRUE IF NEEDED. 
*                ROWPAINT[LOWER], ROWBITS[LOWER] - POSSIBLY PROPOGATED. 
*                LIN - UNAFFECTED BY DELX CODE.  MAY BE AFFECTED BY 
*                    PASS-ON CALL TO DELZ.
*                WORKFILE ACCESS METHOD CALLED TO MANAGE UPDATE.
* 
*         CALLS  DELS (INTERNAL), DELZ. 
# 
  ITEM SPLIT;                        # TEMPORARY SPLIT REFERENCE #
  
  PROC DELS(SPLIT); 
    BEGIN 
# 
**        DELS - INTERNAL LOGIC FOR DELX. 
* 
*         NOTE   SEE HEADER FOR DELX. 
# 
    ITEM SPLIT,I,THISROW,LASTROW; 
    IF SPLITFILE[SPLIT] NQ 0 THEN 
      BEGIN                          # IF A FILE IN THIS SPLIT #
        IF TEMP GR 0 THEN 
          BEGIN                      # IF DELETED LINE WAS ON SCREEN #
          THISROW=CURRENT-DELETCTL; 
          THISROW=LTOY(THISROW,SPLIT);
          LASTROW=TITLEROW[SPLIT]+NUMROWS[SPLIT]; 
          FOR I=THISROW+2 STEP 1 UNTIL LASTROW DO 
            BEGIN                    # REPAINT LINES AFTER DELETION # 
            ROWPAINT[I-1]=ROWPAINT[I];
            ROWBITS[I-1]=ROWBITS[I];
            END 
          ROWPAINT[LASTROW]=TRUE; 
          IF HARDFN AND SPLIT EQ CURSPLIT THEN
            BEGIN 
            IF NOT TABVTPROTM[0] THEN PAINTREST(LASTROW); 
            END 
          ELSE
            BEGIN 
            ROWORIG[THISROW]=0; 
            FOR I=THISROW+2 STEP 1 UNTIL LASTROW
              DO ROWORIG[I-1]=ROWORIG[I]; 
            END 
          END 
      POPTEMP;
      END 
    END                    # OF DELS             #
  
  # ACTUAL DELX CODE STARTS HERE #
  
  IF NUMMARKS GR 0 THEN 
    BEGIN                            # IF MARK IS ACTIVE #
    IF CURRENT EQ REGLINE[MARKREG] THEN 
      BEGIN                          # IF FIRST MARKED LINE DELETED # 
      IF REGLINE[MARKREG+1] GR CURRENT THEN 
        BEGIN                        # IF MORE THAN ONE MARKED LINE # 
        REGLINE[MARKREG] = CURRENT + 1; 
        MRKCHAR[0] = - 1; 
        END 
      ELSE
        BEGIN                        # ONLY ONE MARKED LINE # 
        KILLMARKS = TRUE; 
        END 
      END 
    ELSE
      BEGIN                          # NOT FIRST MARKED LINE DELETED #
      IF CURRENT EQ REGLINE[MARKREG+1] THEN 
        BEGIN                        # IF LAST MARKED LINE DELETED #
        IF REGLINE[MARKREG] LS CURRENT THEN 
          BEGIN                      # IF MORE THAN ONE MARKED LINE # 
          REGLINE[MARKREG+1] = CURRENT - 1; 
          MRKCHAR[1] = - 1; 
          END 
        ELSE
          BEGIN                      # ONLY ONE MARKED LINE # 
          KILLMARKS = TRUE; 
          END 
        END 
      END 
    END 
  IF SCREENMODE THEN
    BEGIN 
    FOR SPLIT=2 STEP -1 UNTIL 1 DO
      BEGIN 
      IF SPLITFILE[SPLIT] NQ 0 THEN 
        BEGIN                        # IF A FILE IN THIS SPLIT #
        PUSHTEMP; 
        TEMP = 0; 
        IF CURRENT GQ TOPF(SPLITFILE[SPLIT]) AND
           CURRENT LQ BOTF(SPLITFILE[SPLIT]) THEN 
          BEGIN                      # IF DELETING LINE IN THIS FILE #
          IF CURRENT GR TOPS(SPLIT) AND CURRENT LQ BOTS(SPLIT) THEN 
            TEMP = 1; 
          END 
        END 
      END 
    DELZ; 
    DELS(1);
    DELS(2);
    END 
  ELSE DELZ;
  IOEND                   # OF DELX             # 
  
  
END TERM
