@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             EDT031
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                           ISSUE 11~
~V9 -1
~P
~V9 1
~YEDT031
~S~M~OEDT IMPLEMENTATION DESCRIPTION
~S~M~OSection 3 Version 1
~S~OSection 3.1 Screen Editor
~S~O1. General Description
~BThis module provides screen editing and text manipulation facilities.
~S~O2. Interfaces
~
Other modules used:~
   LIB07 (File and Current File Handling)~
~
Library Procedure:~
   SEDIT (INPUT FILE,OUTPUT FILE,TERMINAL TYPE)~
~S~O3. Implementation
~S~O3.1 Outline of Operation
~BThe screen editor comprises three parts: editor, display
processor and text handler.  The editor is responsible for the
processing of the edit commands.  The display processor always
starts working when there are no more edit commands.  It refreshes
all or parts of the screen.  The text handler is responsible for
the transfer of blocks of text from one place to another.  This is also
used for recovery of text after deletions.
~BThe editing operations are performed on a data structure which
consists of three parts:  A gap, data before the gap and data after
the gap.  The latter two sections are called the gap and the data parts.
~BCursor movements involve copying characters from one side of the gap
into the other side.  Insertions and deletions, on the other hand,
involve appropriate operations on either sides.
~BThe display processor is woken up when the editor has no more
commands to process.  It then starts updating the screen.  Arrival
of a new command halts this process temporarily.
~BThe text handler has its own buffer in which the latest deleted or
saved texts are kept (KILL BUFFER).  This can be used for the
transfer of data from one place to another.
~S~O3.2 Data Structures
~T# 20
~
~
SCREEN.LIST~IAn array, indexed by line number, holding all the
information relating to the control of the screen and the editor.
Each entry is a record with the following fields:~
   :LINE.VEC~IAn array, containing the text which is used
for screen updates.~
   :CH.CNT~INo of characters in a line.~
   :CTD~IA flag, indicating that the line is a long one.~
   :DISPLAY.STATE~IIndicates the display status of a line.~
   :DISPLAY.COL~IIndicates the position for the start of a redisplay.~
GAP.CH.PTR~IThe address of a vector of bytes, used to hold the
data before the gap.~
DATA.CH.PTR~IThe address of a vector of bytes, used to hold the data
following the gap.~
KILL.BUF.PTR~IThe address of a vector of bytes, used to save
deleted and other saved texts.~
DISPLAY~IIndicates the state of the refresh for the display processor.~
O.LINE~IThis is the latest cursor line position, known by the display
processor.~
O.COL~IThis is the latest cursor column position, known by the
display processor.~
LINE.AFFECTED~IThis variable indicates a single line which requires
redisplay.~
CLEAR.SCREEN.FLAG~IThis flag, when set, indicates that a total clearing
of the screen is required.~
BOUT~IBatch output stream number.~
I.SEG.NO~IThis is the segment into which the input file is opened.~
NEW.SEG~IThis gives the segment into which the input segment
is copied.~
BUF.SEG.NO~IThis segment is used as an intermediate buffer, if
necessary.~
KILL.SEG.NO~IThis gives the segment in which recently deleted
lines and other saved texts are kept.~
I.SEG.BLKS~IGives the number of input blocks.~
C.LINE~IGives the current line position for the editor.~
C.COL~IGives the current column position for the editor.~
FINISHED~IA flag, indicating the end of the edit.~
STRT.OF.WINDOW~IGives the start of the window block number.~
STRT.OF.GAP~IGives the start of the gap block number.~
STRT.OF.DATA~IGives the start of the data block number.~
END.OF.WINDOW~IGives the end of the window block number.~
M.STRT.OF.GAP~IIndicates the marked gap block.~
M.STRT.OF.DATA~IIndicates the marked data block.~
W.STRT.PTR~IGives the position of the start of the window.~
W.END.PTR~IGives the position of the end of the window.~
GAP.PTR~IA pointer into the top of the gap area.~
DATA.PTR~IA pointer into the data area.~
REP.CNT~IGives the repeat counter.~
STX.POS~IGives the start of the text position.~
EXT.POS~IGives the end of text position.~
END.OF.BLKS~IGives the maximum block number.~
M.GAP.PTR~IGives the marked gap pointer.~
M.DATA.PTR~IGives the marked data pointer.~
KILL.PTR~IA pointer into the kill segment.~
KILL.SEG.SIZE~IGives the number of blocks in the kill segment.~
SIZE.OF.REGION~IGives the size of the marked region in bytes.~
MARKED.COL~IHolds the column position of the mark.~
I.SEG.STATUS~IHolds the input segment status.~
TERMINAL.TYPE~IHolds the terminal type.~
GAP.PTR.STRT~IGives the minimum value for the GAP.PTR.~
GAP.PTR.END~IGives the maximum value for the GAP.PTR.~
DATA.PTR.END~IGives the maximum value for the DATA.PTR.~
S.STR.OF.GAP~IGives the saved STRT.OF.GAP.~
S.STRT.OF.DATA~IGives the saved STRT.OF.DATA.~
S.GAP.PTR~IGives the saved GAP.PTR.~
S.DATA.PTR~IGives the saved DATA.PTR.~
I.FILE.NAME~IHolds the input file name.~
O.FILE.NAME~IHolds the output file name.~
I.USER.NAME~IHolds the input file's directory.~
O.USER.NAME~IHolds the output file's directory.~
OUTPUT.LIMIT~IGives the maximum output, using the batch
output, at any one time before breaking, if screen control
sequences are to be output.~
~S~O3.3 Special Notes
~BNone.
~Y
~V9 -1
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H                EDT031
~V9 -1
~F
@TITLE EDT03(1,11)
@COL 1S-2N-3R-4R-5N-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
SEDIT
@BOX 3.0
GLOBAL VARIABLES
@BOX 4.0
PROCEDURES IN MODULE
   1 SEDIT
   2 EXTERNAL INTERRUPT TRAP
   3 GET GAP CHAR
   4 GET GAP BLOCK
   5 UPDATE
   7 CLEAR SCREEN
   8 PUT GAP CHAR
   9 ERASE TO EOL
   10 GET DATA BLOCK
   11 POSITION CURSOR
   12 COPY CHARS UP
   13 COPY CHARS DOW
   14 GET DATA CHAR
   15 SET TERMINAL TYPE
   16 PUT DATA CHAR
   17 SET DATA POINTERS
   18 SET GAP POINTERS
   19 SAVE POINTERS
   20 MONITOR MESSAGE
   21 SET MARK
   22 CHECK MARK POS
   23 COPY TO KILL BUF
   24 DISPLAY PROCESSOR
   25 REFRESH LINE
   26 UPDATE AFTER INSERT
   27 FAULT TRAP
@BOX 6.0
END
@BOX 1.1
#EDT03/1
MODULE (sedIT);
@BOX 3.1
::DATA DECLARATIONS
#EDT03/2
@BOX 4.1
::PROCEDURE SPECIFICATIONS
#EDT03/3
@BOX 6.1
*END
@END
@TITLE EDT03/1(1,11)
@COL 1S-2N-3N-4R
@FLOW 1-2-3-4
@BOX 1.0
EXTERNAL ENVIRONMENT
@BOX 1.1
::EXTERNAL ENVIRONMENT
@BOX 4.1
IMPORT LITERAL SYS14.X.SEG.SIZE, SYS14.PAGE.SHIFT, SYS14.PAGE.SIZE;
IMPORT LITERAL ADDR SYS14.SEG.SIZE;
LSPEC TPROC (INTEGER, INTEGER);
LSPEC END.OUTPUT (INTEGER, INTEGER);
LSPEC SELECT.OUTPUT (INTEGER);
LSPEC OUT.HDR (ADDR [LOGICAL8]);
LSPEC DEFINE.OUTPUT (INTEGER, ADDR [LOGICAL8], INTEGER32, INTEGER32) / INTEGER;
LSPEC I.SOURCE (ADDR [INTEGER]);
LSPEC I.ENQ () / INTEGER;
LSPEC NEW.LINES (INTEGER);
LSPEC PROMPT (ADDR [LOGICAL8]);
LSPEC BREAK.OUTPUT (INTEGER);
LSPEC OUT.NAME (LOGICAL64);
LSPEC OUT.I (INTEGER32, INTEGER);
LSPEC IN.I () / ADDR;
LSPEC NEXT.CH () / INTEGER;
LSPEC IN.CH () / INTEGER;
LSPEC OUT.CH (INTEGER);
LSPEC SPACES (INTEGER);
LSPEC READ.TRAP (INTEGER) / ADDR TPROC;
LSPEC OUT.FN (ADDR [LOGICAL8]);
LSPEC CAPTION (ADDR [LOGICAL8]);
LSPEC ENTER.TRAP (INTEGER, INTEGER);
LSPEC SET.TRAP (INTEGER, ADDR TPROC);
LSPEC PROCESS.NAME (ADDR [LOGICAL8]) / ADDR [LOGICAL8];
LSPEC LIB07.MAKE.CURRENT.FILE (INTEGER);
LSPEC LIB07.CURRENT.FILE.AVAILABLE () / INTEGER;
LSPEC LIB07.GET.CURRENT.FILE () / INTEGER;
LSPEC LIB07.RELEASE.BUFFER.SEG (INTEGER);
LSPEC RETURN.FROM.TRAP ();
LSPEC CHANGE.CHANNEL (INTEGER, INTEGER, LOGICAL);
LSPEC READ.CH (INTEGER) / LOGICAL16;
LSPEC WAIT (LOGICAL, INTEGER);
LSPEC READ.CH.STATUS (INTEGER);
LSPEC READ.FILE.STATUS (ADDR [LOGICAL8], LOGICAL64);
LSPEC CHANGE.SIZE (INTEGER, ADDR);
LSPEC READ.SEGMENT.STATUS (INTEGER);
LSPEC RELEASE.SEGMENT (INTEGER);
LSPEC MAP (INTEGER, INTEGER, INTEGER);
LSPEC CREATE.X.SEGMENT (INTEGER);
LSPEC CREATE.SEGMENT (INTEGER, ADDR);
LSPEC OPEN.FILE (ADDR [LOGICAL8], LOGICAL64, INTEGER, LOGICAL);
LSPEC FILE (ADDR [LOGICAL8], LOGICAL64, INTEGER);
LSPEC COPY.BLOCK (INTEGER, INTEGER, INTEGER, INTEGER);
ADDR PW0, PW1, PW2, PW3, PW4, PW5, PW6;
LOGICAL64 PWW1, PWW2;
@END
@TITLE EDT03/2(1,11)
@COL 1S
@BOX 1.0
DATA DECLARATIONS
@BOX 1.1
::DATA DECLARATIONS
*GLOBAL 9;
LITERAL / INTEGER MAX.LINES = 20, ETX = 3, MAX.COLS = 80, DBL.CMD.PREFIX = %7,
   CR = %D, NO.OF.TERMINAL.TYPES = 3, MAX.GAP.BLKS = 16;
LITERAL / LOGICAL16 P.MODE = %2095;
LITERAL / INTEGER NO.ACTION = 0, POSITIONING = 1, SINGLE.LINE.REFRESH = 2,
   MULTI.LINE.REFRESH = 3;
LITERAL / ADDR [LOGICAL8] PRMT = ;
TYPE SCREEN.TYPE IS
   INTEGER8 CH.CNT, CTD, DISPLAY.STATE
   INTEGER DISPLAY.COL
   LOGICAL8 [MAX.COLS] LINE.VEC;
SCREEN.TYPE [MAX.LINES] SCREEN.LIST;
ADDR [LOGICAL8] KILL.BUF.PTR, GAP.CH.PTR, DATA.CH.PTR;
INTEGER DISPLAY, O.LINE, O.COL, CLEAR.SCREEN.FLAG, LINE.AFFECTED,
   DEV.NO, PERI.SPN;
INTEGER BOUT, I.SEG.NO, NEW.SEG, BUF.SEG.NO, KILL.SEG.NO, I.SEG.BLKS;
ADDR T.PROC [8] OLD.TRAP.PROC.ADDR;
INTEGER8 FINISHED, ERROR, C.LINE, C.COL;
LOGICAL16 OLD.P.MODE;
ADDR STRT.OF.WINDOW, STRT.OF.GAP, END.OF.WINDOW, STRT.OF.DATA,
   M.STRT.OF.GAP, M.STRT.OF.DATA, W.STRT.PTR, GAP.PTR, DATA.PTR, REP.CNT,
   OLD.MAPPED.IO.SEG, OLD.MAPPED.KILL.SEG;
ADDR ETX.POS, STX.POS, W.END.PTR, END.OF.BLKS, M.GAP.PTR,
   M.DATA.PTR, KILL.PTR, MAPPED.IO.SEG.NO, MAPPED.KILL.SEG.NO,
   KILL.SEG.SIZE, I.SEG.STATUS, TERMINAL.TYPE, MARKED.COL;
ADDR GAP.PTR.END, GAP.PTR.STRT, DATA.PTR.END, S.GAP.PTR, S.DATA.PTR,
   S.STRT.OF.GAP, S.STRT.OF.DATA, PAGESIZE.AD;
INTEGER32 SIZE.OF.REGION;
LOGICAL64 I.USER.NAME, O.USER.NAME;
ADDR [LOGICAL8] I.FILE.NAME, O.FILE.NAME;
INTEGER I.DOC.TYPE, O.DOC.TYPE;
LOGICAL8 [80] NAME.BUFFER;
INTEGER [4] DEST;
@END
@TITLE EDT03/3(1,11)
@COL 1S
@BOX 1.0
PROCEDURES
@BOX 1.1
*CODE 1;
::PROCEDURE DECLARATIONS
LSPEC SEDIT (ADDR [LOGICAL8], ADDR [LOGICAL8], INTEGER);
PSPEC EXTERNAL.INTERRUPT.TRAP (INTEGER, INTEGER);
PSPEC GET.GAP.CHAR () / INTEGER;
PSPEC GET.GAP.BLOCK (INTEGER) / INTEGER;
PSPEC UPDATE (INTEGER, ADDR, INTEGER8, INTEGER8, INTEGER8);
PSPEC CLEAR.SCREEN ();
PSPEC PUT.GAP.CHAR (INTEGER) /INTEGER;
PSPEC ERASE.TO.EOL ();
PSPEC GET.DATA.BLOCK (INTEGER) / INTEGER;
PSPEC POSITION.CURSOR (INTEGER8, INTEGER8);
PSPEC COPY.CHARS.UP (INTEGER32);
PSPEC COPY.CHARS.DOWN (INTEGER32);
PSPEC GET.DATA.CHAR () /INTEGER;
PSPEC SET.TERMINAL.TYPE (INTEGER);
PSPEC PUT.DATA.CHAR (INTEGER) / INTEGER;
PSPEC SET.DATA.POINTERS (INTEGER, ADDR) / INTEGER;
PSPEC SET.GAP.POINTERS (INTEGER, ADDR) / INTEGER;
PSPEC SAVE.POINTERS ();
PSPEC MONITOR.MESSAGE (INTEGER);
PSPEC SET.MARK ();
PSPEC CHECK.MARK.POS (ADDR INTEGER, ADDR INTEGER) / INTEGER32;
PSPEC COPY.TO.KILL.BUF (ADDR INTEGER, ADDR INTEGER) / INTEGER;
PSPEC DISPLAY.PROCESSOR ();
PSPEC REFRESH.LINE (INTEGER);
PSPEC UPDATE.AFTER.INSERT (INTEGER32, INTEGER, INTEGER, INTEGER, ADDR);
PSPEC FAULT.TRAP (INTEGER, INTEGER);
   #EDT03.1
   #EDT03.2
   #EDT03.3
   #EDT03.4
   #EDT03.5
   #EDT03.7
   #EDT03.8
   #EDT03.9
   #EDT03.10
   #EDT03.11
   #EDT03.12
   #EDT03.13
   #EDT03.14
   #EDT03.15
   #EDT03.16
   #EDT03.17
   #EDT03.18
   #EDT03.19
   #EDT03.20
   #EDT03.21
   #EDT03.22
   #EDT03.23
   #EDT03.24
   #EDT03.25
   #EDT03.26
   #EDT03.27
@END
@TITLE EDT03.1(1,11)
@COL 12R
@COL 1S-6R-3T-4T-5R-7R-8R-9R-10R-11F
@COL 15R-13R
@ROW 4-15
@ROW 12-5-13
@FLOW 1-6-3OTHERS-4EDIT-5-7-8-9-10-11
@FLOW 3CFILE-15-13-7
@FLOW 4NEWFILE-12-7
@BOX 1.0
SEDIT (INPUT FILE, OUTPUT FILE, TERMINAL TYPE)
@BOX 3.0
INPUT IS CURRENT FILE
@BOX 4.0
NEW FILE OR EDIT ?
@BOX 5.0
PROCESS FILE AND ENTER TRAP 5,7
IF EXCLUSIVE ACCESS
@BOX 6.0
INITIALISE TRAP PROCEDURES
@BOX 7.0
SET UP BUFFER SEGMENT
   #EDT03.1.1
@BOX 8.0
INIT SCREEN CONTROL VARS
SET TERMINAL IN CHAR MODE[EDT03.15]
UPDATE THE SCREEN
[EDT03.5]
@BOX 9.0
PROCESS SCREEN EDIT COMMANDS
   #EDT03.1.2
@BOX 10.0
MONITOR SUCCESSFUL COMPLETION
OR SIGNAL ERROR
   #EDT03.1.3
@BOX 11.0
END
@BOX 12.0
SET NUMBER OF BLOCKS TO NONE
@BOX 13.0
GET THE CURRENT FILE
@BOX 15.0
SET SEGMENT SIZE AND STATUS
@BOX 1.1
PROC SEDIT (I.FILE, O.FILE, T.TYPE);
INTEGER I, J;
LOGICAL8 LAST.CH;
DATAVEC CFILE (LOGICAL8)
        "<CFILE> "
END
DATAVEC NEWFILE (LOGICAL8)
        "<NEW>   "
END;
@BOX 3.1
PROCESS.NAME (I.FILE) => I.FILE.NAME;
PWW1 => I.USER.NAME;
IF PW1 => I.DOC.TYPE = 0
@BOX 4.1
READ.FILE.STATUS (I.FILE.NAME, I.USER.NAME);
IF PW0 < 0
@BOX 5.1
IF PW1 & 8 = 0 THEN
   OPEN.FILE (I.FILE.NAME, I.USER.NAME, -1, %3E);
   PW1 => I.SEG.NO;
   IF PW3 => I.SEG.STATUS & %20 = %20 THEN
      PW2 => I.SEG.BLKS;
   ELSE
      PW2 + SYS14.PAGE.SIZE - 1
      ->> SYS14.PAGE.SHIFT => I.SEG.BLKS;
   FI
ELSE
   ENTER.TRAP (5, 7);
FI
@BOX 6.1
0 => ERROR => FINISHED;
DEFINE.OUTPUT (-1, %"REP0*", 0, 5000) => BOUT;
SELECT.OUTPUT (BOUT);
DATAVEC HDR.VEC (LOGICAL8)
   0 [2]
END
OUT.HDR (^HDR.VEC);
SELECT.OUTPUT (0);
-1 => I.SEG.NO => NEW.SEG => BUF.SEG.NO => KILL.SEG.NO;
FOR I < 8 DO
   READ.TRAP (I) => OLD.TRAP.PROC.ADDR [I];
   SET.TRAP (I, ^FAULT.TRAP);
OD
SET.TRAP (3, ^EXTERNAL.INTERRUPT.TRAP);
@BOX 7.1
::SET UP THE BUFFER SEGMENTS
   #EDT03.1.1
@BOX 8.1
0 => SIZE.OF.REGION;
-1 => MARKED.COL => C.LINE;
FOR MAX.LINES DO
   0 => CH.CNT OF SCREEN.LIST [1 +> C.LINE]
   => CTD OF SCREEN.LIST [C.LINE]
   => DISPLAY.STATE OF SCREEN.LIST [C.LINE];
   MAX.COLS => DISPLAY.COL OF SCREEN.LIST [C.LINE];
OD
0 => C.LINE => C.COL => O.LINE => O.COL
   => LINE.AFFECTED => CLEAR.SCREEN.FLAG
   => DISPLAY;
SET.TERMINAL.TYPE (T.TYPE);
PROCESS.NAME (O.FILE) => O.FILE.NAME;
PWW1 => O.USER.NAME;
PW1 => O.DOC.TYPE;
CLEAR.SCREEN ();
PROMPT (PRMT);
UPDATE (STRT.OF.WINDOW, W.STRT.PTR, C.LINE, C.COL, MAX.LINES);
MULTI.LINE.REFRESH => DISPLAY;
@BOX 9.1
1 => REP.CNT;
::PROCESS SCREEN EDIT COMMANDS
   #EDT03.1.2
@BOX 10.1
::MONITOR COMPLETION OR ERROR
   #EDT03.1.3
@BOX 11.1
END
@BOX 12.1
^NEW.FILE => I.FILE.NAME;
0 => I.SEG.BLKS;
@BOX 13.1
READ.SEGMENT.STATUS (I.SEG.NO);
IF PW2 => I.SEG.STATUS & %20 = %20 THEN
   PW1 => I.SEG.BLKS;
ELSE
   PW1 + SYS14.PAGE.SIZE - 1
      ->> SYS14.PAGE.SHIFT => I.SEG.BLKS;
FI
@BOX 15.1
^CFILE => I.FILE.NAME;
LIB07.GET.CURRENT.FILE () => I.SEG.NO;
@END
@TITLE EDT03.1.1(1,11)
@COL 1S-3R-12T-2R-4T-6R-16N-7R-8F
@COL 13R-14R-9R-15N
@ROW 2-13
@ROW 6-9
@ROW 16-15
@FLOW 1-3-12OK-2-4NO-6-16-7-8
@FLOW 12FAILED-13-14-15-16
@FLOW 4YES-9-15
@BOX 1.0
SET UP BUFFER SEGMENT
@BOX 2.0
CREATE AND INITIALIZE BUFFER
[EDT03.1.1.1]
@BOX 3.0
CREATE SPACE FOR FILE TO BE COPIED
@BOX 4.0
INPUT NEW FILE ?
@BOX 6.0
SET UP POINTERS
@BOX 7.0
SET START OF WINDOW
@BOX 8.0
END
@BOX 9.0
SET UP AN EMPTY FILE
@BOX 12.0
ENOUGH SPACE NOT AVAILABLE?
@BOX 13.0
RELEASE ANY SEGMENT IF NECESSARY
@BOX 14.0
ENTER TRAP (9, 30)
BASIC APPLICATION TRAP
@BOX 1.1
::SET UP BUFFER SEGMENT
BEGIN
INTEGER I, TEMP.SIZE;
INTEGER32 I32, NEW.SIZE;
@BOX 2.1
::INITIALIZE BUFFER
   #EDT03.1.1.1
@BOX 3.1
IF I.SEG.BLKS + MAX.GAP.BLKS * SYS14.PAGE.SIZE
   => NEW.SIZE =< SYS14.SEG.SIZE THEN
   CREATE.SEGMENT (-1, NEW.SIZE);
   PW2 + SYS14.PAGE.SIZE - 1 ->>
      SYS14.PAGE.SHIFT => PW2;
ELSE
   IF I.SEG.BLKS + MAX.GAP.BLKS => NEW.SIZE >
      SYS14.X.SEG.SIZE THEN
      SYS14.X.SEG.SIZE => NEW.SIZE;
   FI
   CREATE.X.SEGMENT (NEW.SIZE);
FI
PW2 - I.SEG.BLKS => TEMP.SIZE;
PW1 => NEW.SEG;
@BOX 4.1
IF I.SEG.BLKS = 0
@BOX 6.1
3 => GAP.PTR;
0 => I32;
4 =>I;
FOR 4 DO
   I32 <<- 8 ! DATA.CH.PTR^ [1 -> I] => I32;
OD
I32 + 3 / SYS14.PAGE.SIZE => END.OF.BLKS;
I32 + 3 - (SYS14.PAGE.SIZE * END.OF.BLKS) => ETX.POS;
GAP.PTR => DATA.PTR;
TEMP.SIZE +> END.OF.BLKS;
FOR I < GAP.PTR + 1 DO
   DATA.CH.PTR^ [I] => GAP.CH.PTR^ [I];
OD
@BOX 7.1
GAP.PTR => STX.POS => W.STRT.PTR => GAP.PTR.STRT;
SYS14.PAGE.SIZE-1=>PAGESIZE.AD;
(IF STRT.OF.DATA = END.OF.BLKS THEN ETX.POS ELSE
   PAGESIZE.AD) => DATA.PTR.END;
@BOX 8.1
END
@BOX 9.1
STRT.OF.DATA => END.OF.BLKS;
FOR I < 4 DO
   0 => GAP.CH.PTR^ [I];
OD
3 => GAP.PTR;
SYS14.PAGE.SIZE - 1  => DATA.PTR => ETX.POS;
@BOX 12.1
IF PW0 /= 0 OR TEMP.SIZE < 2
@BOX 13.1
IF PW0 = 0 THEN
   RELEASE.SEGMENT (NEW.SEG);
FI
LIB07.RELEASE.BUFFER.SEG (I.SEG.NO);
@BOX 14.1
ENTER.TRAP (9, 30);
@END
@TITLE EDT03.1.1.1(1,9)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
INITIALISE BUFFER
@BOX 2.0
CREATE GAP AT THE BEGINNING OF THE INPUT SEGMENT
@BOX 3.0
SET POINTERS
@BOX 4.0
ACCESS BLOCKS
@BOX 5.0
CREATE KILL BUFFER
@BOX 6.0
END
@BOX 1.1
::INITIALISE BUFFER
INTEGER32 TEMP32;
BEGIN
INTEGER J;
@BOX 2.1
-1 => I;
TEMP.SIZE - 1 => J;
FOR I.SEG.BLKS DO
   COPY.BLOCK (I.SEG.NO, 1 +> I, NEW.SEG, 1 +> J);
OD
LIB07.RELEASE.BUFFER.SEG (I.SEG.NO);
NEW.SEG => I.SEG.NO;
-1 => NEW.SEG;
@BOX 3.1
IF I.SEG.BLKS > 0 THEN
   TEMP.SIZE => STRT.OF.DATA;
ELSE
   TEMP.SIZE - 1 => STRT.OF.DATA;
FI
0 => STRT.OF.GAP => STRT.OF.WINDOW;
@BOX 4.1
READ.SEGMENT.STATUS (I.SEG.NO);
PW1 -1 => END.OF.BLKS;
IF PW2 & %40 => I.SEG.STATUS /= 0 THEN
   CREATE.SEGMENT (-1, 2 * SYS14.PAGE.SIZE);
   MAP (PW1 => BUF.SEG.NO, -1, 0);
   PW1 => OLD.MAPPED.IO.SEG;
   PW6 => MAPPED.IO.SEG.NO;
   MAKE (LOGICAL8, SYS14.PAGE.SIZE, PW6 * SYS14.SEG.SIZE) => GAP.CH.PTR;
   MAKE (LOGICAL8, SYS14.PAGE.SIZE, PW6 * SYS14.SEG.SIZE + SYS14.PAGE.SIZE)
      => DATA.CH.PTR;
   IF I.SEG.BLKS > 0 THEN
      COPY.BLOCK (I.SEG.NO, STRT.OF.DATA, MAPPED.IO.SEG.NO, 1);
   FI
ELSE
   MAKE (LOGICAL8, SYS14.PAGE.SIZE, I.SEG.NO * SYS14.SEG.SIZE) => GAP.CH.PTR;
   SYS14.PAGE.SIZE * STRT.OF.DATA => TEMP32;
   MAKE (LOGICAL8, SYS14.PAGE.SIZE, I.SEG.NO * SYS14.SEG.SIZE +
      TEMP32) => DATA.CH.PTR;
   -1 => OLD.MAPPED.IO.SEG;
FI
@BOX 5.1
CREATE.SEGMENT (-1, SYS14.SEG.SIZE);
PW1 => KILL.SEG.NO;
PW2 => KILL.SEG.SIZE;
MAP (PW1, -1, 0);
PW1 => OLD.MAPPED.KILL.SEG;
PW6 => MAPPED.KILL.SEG.NO;
MAKE (LOGICAL8, KILL.SEG.SIZE, PW6 * SYS14.SEG.SIZE) => KILL.BUF.PTR;
@BOX 6.1
END
@END
@TITLE EDT03.1.2(1,11)
@COL 1S-3T-9R-5R-6T-7F
@COL 8R
@ROW 5-8
@FLOW 1-3CONTROL-9-5-6NO-7
@FLOW 3OTHERS-8-6
@FLOW 6YES-3
@BOX 1.0
PROCESS SCREEN EDIT COMMANDS
@BOX 3.0
READ NEXT CHARACTER
@BOX 5.0
SELECT APPROPRIATE COMMAND
1   C-W (BEGINNING OF LINE) [EDT03.1.2.2]
2   C-E (END OF LINE) [EDT03.1.2.3]
3   C-P (CURSOR RIGHT) [EDT03.1.2.4]
4   C-O (CURSOR LEFT) [EDT03.1.2.5]
5   C-Y (CURSOR DOWN) [EDT03.1.2.6]
6   C-U (CURSOR UP) [EDT03.1.2.7]
7   C-D (DELETE NEXT CHARACTER) [EDT03.1.2.8]
8   <DEL> (DELETE PREVIOUS CHARACTER) [EDT03.1.2.9]
9   C-X (KILL LINE) [EDT03.1.2.10]
10  C-Z (SCROLL DOWN) [EDT03.1.2.11]
11  C-A (SCROLL UP) [EDT03.1.2.12]
12  C-B (PAGE UP/BOF) [EDT03.1.2.13]
13  C-V (PAGE DOWN/EOF) [EDT03.1.2.14]
14  C-R (NUMERIC ARGUMENT) [EDT03.1.2.15]
15  C-G C-W (QUIT) [EDT03.1.2.16]
16  C-G C-E (EXIT AND WRITE) [EDT03.1.2.17]
17  C-G C-R (DISPLAY REPEAT COUNTER) [EDT03.1.2.18]
18  C-G C-B (PLACE MARK) [EDT03.1.2.19]
19  C-G C-V (INTERCHANGE MARK AND CURSOR) [EDT03.1.2.20]
20  C-G C-Z (SAVE REGION) [EDT03.1.2.21]
21  C-G C-X (KILL REGION) [EDT03.1.2.22]
22  C-G C-A (UNKILL) [EDT03.1.2.23]
23  ERROR
@BOX 6.0
CONTINUE ?
@BOX 7.0
END
@BOX 8.0
INSERT THE CHARACTER
   #EDT03.1.2.1
@BOX 9.0
FIND COMMAND NUMBER
#EDT03.1.2.24
@BOX 1.1
::PROCESS SCREEN EDIT COMMANDS
BEGIN
INTEGER CMD;
LOGICAL16 CH, OLD.CHAR;
0 => CH;
%100 => OLD.CHAR;
@BOX 3.1
IF CH & %100 = 0 THEN
   IF OLD.CHAR & %100 /= 0 THEN
      DISPLAY.PROCESSOR ();
   FI
   READ.CH (DEV.NO);
   PW1 => OLD.CHAR;
FI
IF OLD.CHAR & %FF => CH > %1F  < %7F OR
   CH >= %8 =< %D
@BOX 5.1
ALTERNATIVE CMD FROM
   #EDT03.1.2.2
   #EDT03.1.2.3
   #EDT03.1.2.4
   #EDT03.1.2.5
   #EDT03.1.2.6
   #EDT03.1.2.7
   #EDT03.1.2.8
   #EDT03.1.2.9
   #EDT03.1.2.10
   #EDT03.1.2.11
   #EDT03.1.2.12
   #EDT03.1.2.13
   #EDT03.1.2.14
   #EDT03.1.2.15
   #EDT03.1.2.16
   #EDT03.1.2.17
   #EDT03.1.2.18
   #EDT03.1.2.19
   #EDT03.1.2.20
   #EDT03.1.2.21
   #EDT03.1.2.22
   #EDT03.1.2.23
   0;
END
@BOX 6.1
IF FINISHED = 0
@BOX 7.1
END
@BOX 8.1
::INSERT CHARACTER
   #EDT03.1.2.1
@BOX 9.1
::FIND COMMAND NUMBER
#EDT03.1.2.24
@END
@TITLE EDT03.1.2.1(1,11)
@COL 12R-15R
@COL 1S-3T-9R-4R-13T-5T-14R-6R-7R-8F
@ROW 12-4
@ROW 15-5
@FLOW 1-3OK-9-4-13NO-5OTHERS-14-6-7-8
@FLOW 3FULL-12-5
@FLOW 5INSERT-3
@FLOW 13YES-15-6
@BOX 1.0
INSERT CHARACTER
@BOX 3.0
STORE CHARACTER?
@BOX 4.0
UPDATE LINE AND COLUMN
@BOX 5.0
CHECK IF NEXT IS AN INSERTION TOO ?
@BOX 6.0
REFRESH SCREEN AND
ADVANCE CURSOR[EDT03.26]
@BOX 7.0
RESET REPEAT COUNT
@BOX 8.0
END
@BOX 9.0
ECHO CHARACTER
@BOX 12.0
SIGNAL BUFFER FULL
@BOX 13.0
END OF TEXT AREA?
@BOX 14.0
NOTE CHARACTER ALREADY READ
@BOX 15.0
NOTE REDISPLAY REQUIRED
@BOX 1.1
::INSERT CHARACTER
BEGIN
INTEGER DUMP.PTR, DUMP.BLOCK, T.LINE, T.COL, COUNT,
   INS.CNT, BUF.FULL;
STRT.OF.GAP => DUMP.BLOCK;
GAP.PTR => DUMP.PTR;
C.LINE => T.LINE;
C.COL => T.COL;
0 => INS.CNT => BUF.FULL;
@BOX 3.1
IF STRT.OF.DATA - STRT.OF.GAP =< 2 AND
   GAP.PTR >= DATA.PTR THEN
   -1 => BUF.FULL;
FI
IF BUF.FULL /= 0 OR
   PUT.GAP.CHAR (CH) => BUF.FULL /= 0
@BOX 4.1
1 +> INS.CNT;
IF [CH >= %A =< %D] OR
   T.COL = MAX.COLS -1 THEN
   1 +> T.LINE;
   0 => T.COL;
ELSE
   1 +> T.COL;
FI
@BOX 5.1
READ.CH (DEV.NO);
PW1 => OLD.CHAR & %FF => CH;
IF CH > %1F < %7F OR CH >= 8 =< %D
@BOX 6.1
UPDATE.AFTER.INSERT (INS.CNT, T.LINE, T.COL, DUMP.BLOCK, DUMP.PTR);
@BOX 7.1
1 => REP.CNT;
-1 => MARKED.COL;
@BOX 8.1
END
@BOX 9.1
OUT.CH (CH);
BREAK.OUTPUT (0);
@BOX 12.1
MONITOR.MESSAGE (4);
@BOX 13.1
IF T.LINE >= MAX.LINES
@BOX 14.1
%100 !> CH;
@BOX 15.1
%100 !> OLD.CHAR;
@END
@TITLE EDT03.1.2.2(1,11)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
BEGINNING OF LINE
@BOX 2.0
COPY DATA DOWN
[EDT03.13]
@BOX 3.0
POSITION THE CURSOR
@BOX 4.0
END
@BOX 1.1
::BEGINNING OF LINE
BEGIN
@BOX 2.1
COPY.CHARS.DOWN (C.COL);
0 => C.COL;
@BOX 3.1
IF DISPLAY = NO.ACTION THEN
   POSITIONING => DISPLAY;
FI
1 => REP.CNT;
@BOX 4.1
END
@END
@TITLE EDT03.1.2.3(1,11)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
END OF LINE
@BOX 2.0
COPY DATA UP
[EDT03.12]
@BOX 3.0
AJDUST COL POSITION
@BOX 4.0
POSITION CURSOR
@BOX 5.0
END
@BOX 1.1
::END OF LINE
BEGIN
INTEGER8 CNT;
@BOX 2.1
COPY.CHARS.UP ( CH.CNT OF SCREEN.LIST [C.LINE] - 1 => CNT - C.COL);
@BOX 3.1
CNT => C.COL;
@BOX 4.1
IF DISPLAY = NO.ACTION THEN
   POSITIONING => DISPLAY;
FI
1 => REP.CNT;
@BOX 5.1
END
@END
@TITLE EDT03.1.2.4(1,11)
@COL 1S-2T-3T-6T-7R-8R-4R-5F
@COL 9N-10N
@ROW 6-9
@ROW 8-10
@FLOW 1-2NO-3NO-6NO-7-8-2
@FLOW 2YES-9-10-4-5
@FLOW 3YES-8
@FLOW 6YES-9
@BOX 1.0
CURSOR RIGHT
@BOX 2.0
END OF MOVE?
@BOX 3.0
NEW POSITION BEFORE END OF LINE?
@BOX 4.0
POSITION CURSOR AND
RESET REPEAT COUNTER
@BOX 5.0
END
@BOX 6.0
END OF LAST LINE?
@BOX 7.0
MOVE TO NEXT LINE
@BOX 8.0
COPY ONE CHARACTER OVER
[EDT03.12]
@BOX 1.1
::CURSOR RIGHT
BEGIN
INTEGER T.LINE, T.COL;
C.LINE => T.LINE;
C.COL => T.COL;
@BOX 2.1
IF 1 -> REP.CNT <0 OR
   [STRT.OF.DATA = END.OF.WINDOW AND
   DATA.PTR = W.END.PTR]
@BOX 3.1
IF 1 + C.COL < CH.CNT OF SCREEN.LIST [C.LINE]
@BOX 4.1
IF DISPLAY = NO.ACTION THEN
   POSITIONING => DISPLAY;
FI
1 => REP.CNT;
@BOX 5.1
END
@BOX 6.1
IF C.LINE = MAX.LINES - 1
@BOX 7.1
1 +> C.LINE;
-1 => C.COL;
@BOX 8.1
1 +> C.COL;
COPY.CHARS.UP (1);
@END
@TITLE EDT03.1.2.5(1,11)
@COL 1S-2T-3R-4R-5F
@FLOW 1-2NO-3-2
@FLOW 2YES-4-5
@BOX 1.0
CURSOR LEFT
@BOX 2.0
END OF MOVE?
@BOX 3.0
MOVE TO NEW POSITION
[EDT03.13]
@BOX 4.0
POSITION CURSOR AND
RESET REPEAT COUNTER
@BOX 5.0
END
@BOX 1.1
::CURSOR LEFT
BEGIN
INTEGER T.LINE, T.COL;
C.LINE => T.LINE;
C.COL => T.COL;
@BOX 2.1
IF 1 -> REP.CNT < 0 OR
   [C.LINE = 0 AND C.COL = 0]
@BOX 3.1
IF 1 -> C.COL < 0 THEN
   CH.CNT OF SCREEN.LIST [1 -> C.LINE] - 1 => C.COL;
FI
COPY.CHARS.DOWN (1);
@BOX 4.1
IF DISPLAY = NO.ACTION THEN
   POSITIONING => DISPLAY;
FI
1 => REP.CNT;
@BOX 5.1
END
@END
@TITLE EDT03.1.2.6(1,11)
@COL 1S-2T-4R-5R-6R
@COL 7R-8R-9F
@ROW 4-7
@FLOW 1-2NO-4-5-6-2
@FLOW 2YES-7-8-9
@BOX 1.0
CURSOR DOWN
@BOX 2.0
END OF MOVE?
@BOX 4.0
COMPUTE NEW POSITION
@BOX 5.0
COMPUTE NEW CURSOR POSITION
@BOX 6.0
DECREMENT REPEAT COUNTER
@BOX 7.0
COPY DATA UP [EDT03.12] AND
RESET REPEAT COUNTER
@BOX 8.0
SET POSITIONING IF REQUIRED
@BOX 9.0
END
@BOX 1.1
::CURSOR DOWN
BEGIN
INTEGER COL, CNT;
C.COL => COL;
0 => CNT;
@BOX 2.1
IF REP.CNT = 0 OR
   C.LINE = MAX.LINES - 1 OR
   CH.CNT OF SCREEN.LIST [C.LINE + 1] = 0
@BOX 4.1
CH.CNT OF SCREEN.LIST [C.LINE] - C.COL +> CNT;
@BOX 5.1
0 => C.COL;
SELECT SCREEN.LIST [1 +>C.LINE];
IF CH.CNT =< COL THEN
   CH.CNT - 1 => C.COL +> CNT;
ELSE
   COL => C.COL +> CNT;
FI
@BOX 6.1
1 -> REP.CNT;
@BOX 7.1
COPY.CHARS.UP (CNT);
1 => REP.CNT;
@BOX 8.1
IF DISPLAY = NO.ACTION THEN
   POSITIONING => DISPLAY;
FI
@BOX 9.1
END
@END
@TITLE EDT03.1.2.7(1,11)
@COL 1S-2T-3R-4R-5R
@COL 6R-7R-12R-8F
@ROW 3-6
@FLOW 1-2NO-3-4-5-2
@FLOW 2YES-6-7-12-8
@BOX 1.0
CURSOR UP
@BOX 2.0
REPEAT COUNTER IS ZERO ?
@BOX 3.0
SET COPY BACK COUNT UP TO BEGINNING
OF THE CURRENT LINE
@BOX 4.0
SET COPY BACK COUNT UP TO THE APPROPRIATE
POSITION OF THE PREVIOUS LINE
@BOX 5.0
DECREMENT REPEAT COUNTER
@BOX 6.0
COPY DATA DOWN
[EDT03.13]
@BOX 7.0
SET POSITIONING IF REQUIRED
@BOX 8.0
END
@BOX 12.0
RESET REPEAT COUNTER
@BOX 1.1
::CURSOR UP
BEGIN
INTEGER COL, CNT;
C.COL => COL;
0 => CNT;
@BOX 2.1
IF REP.CNT = 0 OR C.LINE = 0
@BOX 3.1
C.COL +> CNT;
@BOX 4.1
1 -> C.LINE;
SELECT SCREEN.LIST [C.LINE];
IF CH.CNT => C.COL =< COL THEN
   1 +> CNT;
   1 -> C.COL;
ELSE
   C.COL - COL +> CNT;
   COL => C.COL;
FI
@BOX 5.1
1 -> REP.CNT;
@BOX 6.1
COPY.CHARS.DOWN (CNT);
@BOX 7.1
IF DISPLAY = NO.ACTION THEN
   POSITIONING => DISPLAY;
FI
@BOX 8.1
END
@BOX 9.1
IF C.LINE /= 0
@BOX 10.1
COPY.DATA.DOWN (CNT);
@BOX 11.1
IF C.LINE = MAX.LINES - 1 THEN
   IF CENTRE.LINE + REP.CNT - 1 - SCROLL.CNT
      => SCROLL.CNT > 0 THEN
      IF SCROLL.CNT > CENTRE.LINE - 1 THEN
         MAX.LINES - 1 => REP.CNT;
      ELSE
         CENTRE.LINE + SCROLL.CNT => REP.CNT;
      FI
   ELSE
      CENTRE.LINE => REP.CNT;
   FI
FI
0 => CNT;
@BOX 12.1
1 => REP.CNT;
@BOX 13.1
IF STX.REACHED /= 0
@BOX 14.1
C.COL => DUMP.COL;
SCROLL.DOWN (CENTRE.LINE + REP.CNT -1) => SCROLL.CNT;
@BOX 15.1
IF SCROLL.CNT = 0
@BOX 16.1
IF C.LINE /= MAX.LINES - 1 AND
   C.COL - DUMP.COL => CNT > 0 AND
      CTD OF SCREEN.LIST [C.LINE] = 1
@BOX 17.1
COPY.DATA.DOWN (CNT);
DUMP.COL => C.COL;
0 => CNT;
@END
@TITLE EDT03.1.2.8(1,11)
@COL 1S-2T-3T-5T-6R-7R-9R-10F
@COL 12R
@ROW 6-12
@FLOW 1-2NO-3OTHERS-5OTHERS-6-7-9-10
@FLOW 2YES-9
@FLOW 3EOT-9
@FLOW 5CR/LF/FF/CTD-12-7
@BOX 1.0
DELETE NEXT CHARACTER
@BOX 2.0
AT THE END OF THE SCREEN?
@BOX 3.0
DELETE NEXT CHARACTER, IF ANY?
@BOX 5.0
EOL MARKER DELETED?
@BOX 6.0
SET NUMBER OF LINES
TO BE REFRESHED
@BOX 7.0
REFRESH SCREEN
[EDT03.5]
@BOX 9.0
RESET REPEAT COUNTER
@BOX 10.0
END
@BOX 12.0
SET NUMBER OF LINES
TO BE REFRESHED
@BOX 1.1
::DELETE NEXT CHARACTER
BEGIN
INTEGER8 COUNT, T.LINE;
LOGICAL8 CH;
@BOX 2.1
SELECT SCREEN.LIST [C.LINE];
IF STRT.OF.DATA = END.OF.BLKS
   AND DATA.PTR = ETX.POS
@BOX 3.1
IF GET.DATA.CHAR () => CH < 0
@BOX 5.1
IF [CH >= %A =< %D] OR CTD = 1
@BOX 6.1
1 => COUNT;
@BOX 7.1
UPDATE (STRT.OF.DATA, DATA.PTR, C.LINE, C.COL, COUNT);
@BOX 9.1
1 => REP.CNT;
-1 => MARKED.COL;
@BOX 10.1
END
@BOX 12.1
IF CTD = 0 THEN
   MAX.LINES - C.LINE => COUNT;
ELSE
   -1 => COUNT;
FI
@END
@TITLE EDT03.1.2.9(1,11)
@COL 1S-2T-3R-4T-12N-5T-6R-14N-7R-13R-9F
@COL 10R-11R-15N
@ROW 12-10
@ROW 6-11
@ROW 14-15
@FLOW 1-2NO-3-4NO-12-5NO-6-14-7-13-9
@FLOW 2YES-13
@FLOW 4YES-10-15-14
@FLOW 5YES-11-15
@BOX 1.0
DELETE PREVIOUS CHARACTER
@BOX 2.0
AT BEGINNING OF THE SCREEN ?
@BOX 3.0
REMOVE PREVIOUS CHARACTER
@BOX 4.0
CURSOR CURRENTLY AT THE
BEGINNING OF A LINE ?
@BOX 5.0
CURRENT LINE IS A LONG LINE ?
@BOX 6.0
SET NUMBER OF LINES TO
BE REFRESHED
@BOX 7.0
REFRESH SCREEN
[EDT03.5]
@BOX 9.0
END
@BOX 10.0
SET CURSOR TO THE END
OF THE PREVIOUS LINE
@BOX 11.0
SET LINES TO BE REFRESHED
@BOX 13.0
RESET REPEAT COUNTER
@BOX 1.1
::DELETE PREVIOUS CHARACTER
BEGIN
INTEGER8 COUNT, T.LINE;
IF REP.CNT /= 1 AND REP.CNT > C.COL THEN
   C.COL => REP.CNT;
FI
@BOX 2.1
IF C.COL = 0 AND C.LINE = 0
@BOX 3.1
GET.GAP.CHAR ();
@BOX 4.1
IF 1 -> C.COL = -1
@BOX 5.1
IF CTD OF SCREEN.LIST [C.LINE] = 1
@BOX 6.1
1 => COUNT;
@BOX 7.1
UPDATE (STRT.OF.DATA, DATA.PTR, C.LINE, C.COL, COUNT);
@BOX 9.1
END
@BOX 10.1
1 -> C.LINE;
SELECT SCREEN.LIST [C.LINE];
CH.CNT - 1 => C.COL;
MAX.LINES - C.LINE => COUNT;
@BOX 11.1
-1 => COUNT;
@BOX 13.1
1 => REP.CNT;
-1 => MARKED.COL;
@END
@TITLE EDT03.1.2.10(1,11)
@COL 1S-3T-2T-4R-5R-8R-9R-10F
@COL 11R
@ROW 4-11
@FLOW 1-3NON ZERO-2NO-4-5-8-9-10
@FLOW 3ZERO-11-8-9-10
@FLOW 2YES-9
@BOX 1.0
DKILL LINE
@BOX 2.0
END OF FILE?
@BOX 3.0
CHECK REPEAT COUNTER
@BOX 4.0
COMPUTE NUMBER OF CHARACTERS TO
BE DELETED FROM CURRENT LINE
@BOX 5.0
KILL CHARACTERS
@BOX 8.0
REFRESH SCREEN OR CURRENT LINE
[EDT03.5]
@BOX 9.0
RESET REPEAT COUNTER
@BOX 10.0
END
@BOX 11.0
KILL UP TO CURSOR POSITION
@BOX 1.1
::KILL LINE
BEGIN
INTEGER8 T.LINE, SCREEN.REFRESH, DEL.CNT;
@BOX 2.1
IF STRT.OF.DATA = END.OF.BLKS AND
   DATA.PTR = ETX.POS
@BOX 3.1
SELECT SCREEN.LIST [C.LINE];
IF REP.CNT = 0
@BOX 4.1
IF CH.CNT = 1 OR C.COL = CH.CNT - 1
   THEN
   ::KILL EOL MARKER
   1 => DEL.CNT;
   (IF CTD /= 0 THEN 1 ELSE 2) => SCREEN.REFRESH;
ELSE
   ::KILL UP TO EOL MARKER
   CH.CNT - 1 - C.COL + CTD => DEL.CNT;
   CTD => SCREEN.REFRESH;
FI
@BOX 5.1
-1 => KILL.PTR;
FOR DEL.CNT DO
   GET.DATA.CHAR () =>
      KILL.BUF.PTR^ [1 +> KILL.PTR];
OD
@BOX 8.1
DEL.CNT => SIZE.OF.REGION;
IF SCREEN.REFRESH = 0 THEN
   1 => SCREEN.REFRESH;
ELSE
   IF SCREEN.REFRESH = 2 THEN
      MAX.LINES - C.LINE => SCREEN.REFRESH;
   ELSE
      -1 * DEL.CNT => SCREEN.REFRESH;
   FI
FI
UPDATE (STRT.OF.DATA, DATA.PTR, C.LINE, C.COL, SCREEN.REFRESH);
@BOX 9.1
1 => REP.CNT;
-1 => MARKED.COL;
@BOX 10.1
END
@BOX 11.1
C.COL => DEL.CNT => KILL.PTR;
ETX => KILL.BUF.PTR^ [KILL.PTR];
FOR DEL.CNT DO
   GET.GAP.CHAR () =>
      KILL.BUF.PTR^ [1 -> KILL.PTR];
OD
0 => C.COL;
CTD => SCREEN.REFRESH;
@END
@TITLE EDT03.1.2.11(1,11)
@COL 1S-2R-3T-7R-8T-9T-10T-11R-4R-5R-6F
@COL 12R-13R-14N
@ROW 7-12
@ROW 14-11
@FLOW 1-2-3NO-7-8NO-9NO-10NO-8
@FLOW 10YES-9
@FLOW 9YES-11-4-5-6
@FLOW 8YES-13-14-4
@FLOW 3YES-12-14
@BOX 1.0
SCROLL DOWN
@BOX 2.0
SET DEFAULT COUNTER IF NECESSARY
@BOX 3.0
CURRENT CURSOR POSITION
STAYS WITHIN SCREEN?
@BOX 4.0
REFRESH.SCREEN AND POSITION CURSOR
[EDT03.5]
@BOX 5.0
RESET REPEAT COUNTER
@BOX 6.0
END
@BOX 7.0
MOVE TO THE BEGINNING OF
THE NEXT LINE
[EDT03.12]
@BOX 8.0
LAST LINE COPIED?
@BOC 9.0
GET NEXT CHARACTER, IF ANY?
@BOX 10.0
STORE CHARACTER AND CHECK
FOR END OF LINE?
@BOX 11.0
SET START OF WINDOW POSITION
@BOX 12.0
COMPUT NEW WINDOW POSITION
@BOX 13.0
SET START OF WINDOW POSITION
@BOX 1.1
::SCROLL DOWN
BEGIN
INTEGER LINES, CNT, T.LINE, CH, TEMP;
0 => CNT;
@BOX 2.1
IF REP.CNT = 1 THEN
   MAX.LINES - 2 => REP.CNT;
FI
IF REP.CNT = 0 THEN
   1 => CLEAR.SCREEN.FLAG;
FI
@BOX 3.1
IF REP.CNT - C.LINE => LINES =< 0
@BOX 4.1
UPDATE (STRT.OF.WINDOW, W.STRT.PTR, 0, 0, MAX.LINES);
@BOX 5.1
1 => REP.CNT;
@BOX 6.1
END
@BOX 7.1
COPY.CHARS.UP (CH.CNT OF SCREEN.LIST [C.LINE]
   - C.COL);
@BOX 8.1
0 => CNT;
IF 1 -> LINES =< 0
@BOX 9.1
IF GET.DATA.CHAR () => CH < 0
@BOX 10.1
PUT.GAP.CHAR (CH);
IF 1 +> CNT /= MAX.COLS AND
   [CH < %A OR CH > %D]
@BOX 11.1
STRT.OF.GAP => STRT.OF.WINDOW;
IF GAP.PTR - CNT => W.STRT.PTR < 0 THEN
   SYS14.PAGE.SIZE +> W.STRT.PTR;
   1 -> STRT.OF.WINDOW;
FI
@BOX 12.1
-1 => T.LINE;
FOR REP.CNT DO
   CH.CNT OF SCREEN.LIST
      [1 +> T.LINE] +> CNT;
OD
W.STRT.PTR +> CNT ->> SYS14.PAGE.SHIFT => TEMP
   +> STRT.OF.WINDOW;
TEMP <<- SYS14.PAGE.SHIFT -: CNT => W.STRT.PTR;
@BOX 13.1
STRT.OF.GAP => STRT.OF.WINDOW;
GAP.PTR => W.STRT.PTR;
@END
@TITLE EDT03.1.2.12(1,11)
@COL 1S-2R-6T-7T-8R-9R-4R-5F
@COL 10R
@ROW 8-10
@FLOW 1-2-6NO-7NO-8-9-4-5
@FLOW 6YES-9
@FLOW 7YES-10-9
@BOX 1.0
SCROLL UP
@BOX 2.0
SET DEFAULT COUNTER IF NECESSARY
@BOX 4.0
RESET REPEAT COUNTER
@BOX 5.0
END
@BOX 6.0
REPEAT COUNT ZERO?
@BOX 7.0
CURRENT CURSOR POSITION
STAYS WITHIN SCREEN
@BOX 8.0
MOVE TO APPROPRIATE POSITION
#EDT03.1.2.12.1
@BOX 9.0
REFRESH SCREEN
[EDT03.5]
@BOX 10.0
COMPUTE START OF WINDOW
#EDT03.1.2.12.2
@BOX 1.1
::SCROLL UP
BEGIN
INTEGER CNT, T.LINE, CH;
0 => CNT;
@BOX 2.1
IF REP.CNT = 1 THEN
   MAX.LINES - 2 => REP.CNT;
FI
IF REP.CNT = 0 THEN
   1 => CLEAR.SCREEN.FLAG;
FI
@BOX 4.1
1 => REP.CNT;
@BOX 5.1
END
@BOX 6.1
IF REP.CNT = 0
@BOX 7.1
IF REP.CNT - MAX.LINES + C.LINE + 1 < 0
@BOX 8.1
::MOVE TO APPROPRIATE POSITION
#EDT03.1.2.12.1
@BOX 9.1
UPDATE (STRT.OF.WINDOW, W.STRT.PTR, 0, 0, MAX.LINES);
@BOX 10.1
::COMPUTE START OF WINDOW
#EDT03.1.2.12.2
@END
@TITLE EDT03.1.2.12.1(1,11)
@COL 1S-2R-3R-4T-5T-6T-7R-10F
@COL 8R-9R
@ROW 8-5
@FLOW 1-2-3-4NO-5NO-6NO-7-4
@FLOW 4YES-8-9-10
@FLOW 5YES-9
@FLOW 6YES-5
@BOX 1.0
MOVE TO APPROPRIATE POSITION
@BPX 2.0
MOVE TO THE BEGINNING OF THE SCREEN
@BOX 3.0
REMEMBER FIRST SCREEN LINE
CHARACTER COUNT
@BOX 4.0
END OF MOVE?
@BOX 5.0
GET NEXT CHARACTER, IF ANY?
@BOX 6.0
COPY IT DOWN AND CHECK
FOR END OF LINE?
@BOX 7.0
RESET CHARACTER COUNT
@BOX 8.0
GO BACK TO THE BEGINNING
OF THE LAST LINE[EDT03.12]
@BOX 9.0
SET WINDOW
@BOX 10.0
END
@BOX 1.1
::MOVE TO APPROPRIATE POSITION
BEGIN
@BOX 2.1
C.COL => CNT;
FOR C.LINE DO
CH.CNT OF SCREEN.LIST [1 -> C.LINE]
   +> CNT;
OD
COPY.CHARS.DOWN (CNT);
@BOX 3.1
CH.CNT OF SCREEN.LIST [0] => CNT;
@BOX 4.1
IF 1 -> REP.CNT < 0
@BOX 5.1
IF GET.GAP.CHAR () => CH < 0
@BOX 6.1
PUT.DATA.CHAR (CH);
IF 1 +> CNT /= MAX.COLS AND
   [CH < %A OR CH > %D]
@BOX 7.1
0 => CNT;
@BOX 8.1
COPY.CHARS.UP (1);
@BOX 9.1
STRT.OF.GAP => STRT.OF.WINDOW;
GAP.PTR => W.STRT.PTR;
@BOX 10.1
END
@END
@TITLE EDT03.1.2.12.2(1,11)
@COL 1S-2R-3T-4T-5T-6R-7R-8F
@COL 9R
@ROW 4-9
@FLOW 1-2-3NO-4NO-5NO-6-3
@FLOW 3YES-9-7-8
@FLOW 4YES-7
@FLOW 5YES-4
@BOX 1.0
COMPUTE WINDOW POSITION
@BOX 2.0
SAVE POINTERS
@BOX 3.0
END OF WINDOW MOVE?
@BOX 4.0
GET CHARACTER
IF ANY?
@BOX 5.0
NOT END OF LINE?
@BOX 6.0
RESET CHARACTER COUNT
@BOX 7.0
SET WINDOW
@BOX 8.0
END
@BOX 9.0
ADVANCE WINDOW ONE CHARACTER
[EDT03.8]
@BOX 1.1
::COMPUTE WINDOW POSITION
BEGIN
@BOX 2.1
SAVE.POINTERS ();
CH.CNT OF SCREEN.LIST [C.LINE] => CNT;
SET.GAP.POINTERS(STRT.OF.WINDOW, W.STRT.PTR);
@BOX 3.1
IF 1 -> REP.CNT < 0
@BOX 4.1
IF GET.GAP.CHAR () => CH < 0
@BOX 5.1
IF 1 +> CNT /= MAX.COLS AND
   [CH < %A OR CH > %D]
@BOX 6.1
0 => CNT;
@BOX 7.1
STRT.OF.GAP => STRT.OF.WINDOW;
GAP.PTR => W.STRT.PTR;
SET.GAP.POINTERS (S.STRT.OF.GAP, S.GAP.PTR);
@BOX 8.1
END
@BOX 9.1
PUT.GAP.CHAR (CH);
@END
@TITLE EDT03.1.2.13(1,10)
@COL 1S-2T-3R-8R-7F
@COL 4R
@ROW 3-4
@FLOW 1-2NO-3-8-7
@FLOW 2YES-4-8
@BOX 1.0
BACK PAGE/BEGINNING OF FILE
@BOX 3.0
BACKWARD BY PAGE?
@BOX 3.0
COPY CHARACTERS DOWN
@BOX 4.0
GO BACK REQUIRED NO OF PAGES
@BOX 7.0
END
@BOX 8.0
SET WINDOW POSITION, REFRESH
SCREEN AND RESET REPEAT COUNTER
@BOX 1.1
::BACK PAGE/BEGINNING OF FILE
BEGIN
INTEGER CH;
@BOX 2.1
IF REP.CNT /= 0
@BOX 3.1
COPY.CHARS.DOWN (END.OF.BLKS + 1 * SYS14.PAGE.SIZE);
@BOX 4.1
WHILE REP.CNT >= 0 AND
   GET.GAP.CHAR () => CH >= 0 DO
   PUT.DATA.CHAR (CH);
   IF CH = "$P" AND 1 -> REP.CNT < 0 THEN
      COPY.CHARS.UP (1);
   FI
OD
@BOX 7.1
END
@BOX 8.1
STRT.OF.GAP => STRT.OF.WINDOW;
GAP.PTR => W.STRT.PTR;
0 => C.LINE => C.COL;
UPDATE (STRT.OF.DATA, DATA.PTR, C.LINE, C.COL, MAX.LINES);
1 => REP.CNT;
@END
@TITLE EDT03.1.2.14(1,11)
@COL 1S-3T-2R-4R-5F
@COL 6R
@FLOW 1-3NO-2-4-5
@FLOW 3YES-6-4
@ROW 2-6
@BOX 1.0
FORWARD PAGE/END OF FILE
@BOX 2.0
COPY TO THE END OF THE FILE
[EDT03.12]
@BOX 3.0
FORWARD BY PAGE?
@BOX 4.0
REFRESH THE SCREEN CONTENTS
[EDT03.5]
@BOX 5.0
END
@BOX 6.0
GO FORWARD BY REQUIRED NO OF PAGES
@BOX 1.1
::FORWARD PAGE/END.OF.FILE
BEGIN
INTEGER CH;
@BOX 2.1
COPY.CHARS.UP (END.OF.BLKS + 1 * SYS14.PAGE.SIZE);
@BOX 3.1
IF REP.CNT /= 0
@BOX 4.1
STRT.OF.GAP => STRT.OF.WINDOW;
GAP.PTR => W.STRT.PTR;
0 => C.LINE => C.COL;
UPDATE (STRT.OF.DATA, DATA.PTR, C.LINE, C.COL, MAX.LINES);
1 => REP.CNT;
@BOX 5.1
END
@BOX 6.1
WHILE REP.CNT > 0 AND
   GET.DATA.CHAR () => CH >= 0 DO
   PUT.GAP.CHAR (CH);
   IF CH = "$P" THEN
      1 -> REP.CNT;
   FI
OD
@END
@TITLE EDT03.1.2.15(1,10)
@COL 1S-2R-4T-5R
@COL 6R-3F
@ROW 5-6
@FLOW 1-2-4NO-5-4
@FLOW 4YES-6-3
@BOX 1.0
NUMERIC ARGUMENT
@BOX 2.0
RESET REPEAT COUNTER
@BOX 3.0
END
@BOX 4.0
READ CHARACTER
@BOX 5.1
COMPUTE REPEAT COUNTER
@BOX 6.1
REQUEST TO RESET CURSOR
@BOX 1.1
::NUMERIC ARGUMENT
BEGIN
@BOX 2.1
POSITION.CURSOR (MAX.LINES + 1, 1);
CAPTION (%"Repeat Counter = ");
BREAK.OUTPUT (0);
0 => REP.CNT;
@BOX 3.1
END
@BOX 4.1
READ.CH (DEV.NO);
IF PW1 => OLD.CHAR & %FF => CH < "0" OR CH > "9"
@BOX 5.1
OUT.CH (CH);
BREAK.OUTPUT (0);
REP.CNT * 10 + (CH - "0") => REP.CNT;
@BOX 6.1
%100 !> CH;
MONITOR.MESSAGE (7);
IF DISPLAY = NO.ACTION THEN
   POSITIONING => DISPLAY;
FI
@END
@TITLE EDT03.1.2.16(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
QUIT
@BOX 2.0
SET FINISHED FLAG
@BOX 3.0
END
@BOX 1.1
::QUIT
BEGIN
@BOX 2.1
POSITION.CURSOR (MAX.LINES + 1, 1);
CAPTION (%"<<<Abort>>>- REALLY? ");
BREAK.OUTPUT (0);
READ.CH (DEV.NO);
IF PW1 => OLD.CHAR => CH & %FF = "Y" THEN
   1 => FINISHED;
ELSE
   MONITOR.MESSAGE (7);
FI
@BOX 3.1
END
@END
@TITLE EDT03.1.2.17(1,9)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
EXIT AND WRITE
@BOX 2.0
SET FINISHED FLAG
@BOX 3.0
END
@BOX 1.1
::EXIT AND WRITE
BEGIN
@BO 2.1
2 => FINISHED;
@BOX 3.1
END
@END
@TITLE EDT03.1.2.18(1,9)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
DISPLAY REPEAT COUNTER
@BOX 2.0
SET MESSAGE NUMBER AND DISPLAY
THE MESSAGE
@BOX 3.0
END
@BOX 1.1
::DISPLAY REPEAT COUNTER
BEGIN
@BOX 2.1
MONITOR.MESSAGE (0);
READ.CH (DEV.NO);
PW1 => OLD.CHAR => CH;
%100 !> CH;
MONITOR.MESSAGE (7);
@BOX 3.1
END
@END
@TITLE EDT03.1.2.19(1,9)
@COL 1S-3R-4R-5F
@FLOW 1-3-4-5
@BOX 1.0
PLACE MARK
@BOX 3.0
SET MARK
[EDT03.1.1.24]
@BOX 4.0
RESET REPEAT COUNTER
@BOX 5.0
END
@BOX 1.1
::PLACE MARK
BEGIN
@BOX 3.1
SET.MARK ();
@BOX 4.1
1 => REP.CNT;
@BOX 5.1
END
@END
@TITLE EDT03.1.2.20(1,11)
@COL 10R
@COL 1S-2T-4T-5R-6R-7R-8T-9R-11R-12F
@COL 13R
@ROW 4-13
@ROW 10-9
@FLOW 1-2NO-4OTHERS-5-6-7-8OUTSIDE-9-11-12
@FLOW 2YES-13-11
@FLOW 4AT GAP-11
@FLOW 8INSIDE-10-11
@BOX 1.0
INTERCHANGE MARK AND CURSOR
@BOX 2.0
MARK NOT SET ?
@BOX 4.0
CHECK POSITION OF THE MARK ?
[EDT03.22]
@BOX 5.0
SET NEW MARK
@BOX 6.0
NOTE SIZE OF THE REGION
@BOX 7.0
MOVE TO THE PREVIOUS MARK
@BOX 8.0
IS MARK INSIDE THE SCREEN ?
@BOX 9.0
SET UP CORRECT SCREEN CONTENTS
[EDT03.5]
@BOX 10.0
SET POSITIONING IF REQUIRED
@BOX 11.0
RESET REPEAT COUNTER
@BOX 12.0
END
@BOX 13.0
MONITOR THE ERROR
[EDT03.20]
@BOX 1.1
::INTERCHANGE MARK AND CURSOR
BEGIN
INTEGER T.LINE, T.COL, M.COL;
INTEGER32 CNT;
@BOX 2.1
IF MARKED.COL => M.COL < 0
@BOX 4.1
CHECK.MARK.POS (^T.LINE, ^T.COL) => CNT;
IF T.LINE = C.LINE AND
   T.COL = C.COL
@BOX 5.1
SET.MARK ();
@BOX 6.1
CNT => SIZE.OF.REGION;
MONITOR.MESSAGE (3);
@BOX 7.1
IF T.LINE < C.LINE OR
   [T.LINE = C.LINE AND T.COL < C.COL] THEN
   COPY.CHARS.DOWN (CNT);
ELSE
   COPY.CHARS.UP (CNT);
FI
@BOX 8.1
IF T.LINE >= 0 < MAX.LINES
@BOX 9.1
0 => C.LINE;
STRT.OF.GAP => STRT.OF.WINDOW;
IF M.COL => C.COL -: GAP.PTR => W.STRT.PTR < 0 THEN
   SYS14.PAGE.SIZE +> W.STRT.PTR;
   1 -> STRT.OF.WINDOW;
FI
UPDATE (STRT.OF.WINDOW, W.STRT.PTR, C.LINE, C.COL, MAX.LINES);
@BOX 10.1
T.LINE => C.LINE;
T.COL => C.COL;
IF DISPLAY =  NO.ACTION THEN
   POSITIONING => DISPLAY;
FI
@BOX 11.1
1 => REP.CNT;
@BOX 12.1
END
@BOX 13.1
MONITOR.MESSAGE (2);
@END
@TITLE EDT03.1.2.21(1,11)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
SAVE REGION
@BOX 2.0
COPY THE REGION TO THE KILL BUFFER
[EDT03.23]
@BOX 3.0
RESET REPEAT COUNTER
@BOX 4.0
END
@BOX 1.1
::SAVE REGION
BEGIN
INTEGER DMY;
@BOX 2.1
COPY.TO.KILL.BUF (^DMY, ^DMY);
@BOX 3.1
1 => REP.CNT;
@BOX 4.1
END
@END
@TITLE EDT03.1.2.22(1,11)
@COL 1S-2T-3R-4T-5R-6R-7R-8R-9F
@COL 10R
@ROW 5-10
@FLOW 1-2OK-3-4OUTSIDE-5-6-7-8-9
@FLOW 2FAILED-8
@FLOW 4INSIDE-10-6
@BOX 1.0
KILL REGION
@BOX 2.0
COPY THE REGION TO THE KILL BUFFER
[EDT03.23]
@BOX 3.0
KILL THE REGION
@BOX 4.0
MARK IS INSIDE THE SCREEN ?
@BOX 5.0
SET NUMBER OF LINES TO
BE REFRESHED AND START
OF THE WINDOW IF NECESSARY
@BOX 6.0
REFRESH THE SCREEN
[EDT03.5]
@BOX 7.0
SET THE MARK TO UNDEFINED
@BOX 8.0
RESET THE REPEAT COUNTER
@BOX 9.0
END
@BOX 10.0
SET NUMBER OF LINES TO
BE REFRESHED AND CURSOR
IF NECESSARY
@BOX 1.1
::KILL REGION
BEGIN
INTEGER BLK, PTR, POS, REFRESH.CNT, M.LINE, M.COL;
@BOX 2.1
IF COPY.TO.KILL.BUF (^M.LINE, ^M.COL) < 0
@BOX 3.1
IF M.LINE < C.LINE OR
   [M.LINE = C.LINE AND M.COL < C.COL] THEN
   0 => POS;
   SET.GAP.POINTERS (M.STRT.OF.GAP, M.GAP.PTR);
ELSE
   1 => POS;
   SET.DATA.POINTERS (M.STRT.OF.DATA, M.DATA.PTR);
FI
@BOX 4.1
IF M.LINE >= 0 < MAX.LINES
@BOX 5.1
IF POS = 0 THEN
   M.STRT.OF.GAP => STRT.OF.WINDOW => BLK;
   M.GAP.PTR => W.STRT.PTR => PTR;
   0 => C.LINE => C.COL;
   MAX.LINES => REFRESH.CNT;
ELSE
   STRT.OF.GAP => BLK;
   GAP.PTR => PTR;
   MAX.LINES - C.LINE => REFRESH.CNT;
FI
C.LINE => M.LINE;
C.COL => M.COL;
@BOX 6.1
UPDATE (BLK, PTR, M.LINE, M.COL, REFRESH.CNT);
@BOX 7.1
-1 => MARKED.COL;
@BOX 8.1
1 => REP.CNT;
@BOX 9.1
END
@BOX 10.1
IF M.LINE = C.LINE AND
   CTD OF SCREEN.LIST [C.LINE] = 0 THEN
   1 => REFRESH.CNT;
ELSE
   MAX.LINES => REFRESH.CNT;
FI
IF POS = 0 THEN
   M.LINE => C.LINE;
   M.COL => C.COL;
ELSE
   C.LINE => M.LINE;
   C.COL => M.COL;
FI
STRT.OF.GAP => BLK;
GAP.PTR => PTR;
@END
@TITLE EDT03.1.2.23(1,11)

@COL 1S-2R-3T-4T-5R-6R-13R-14R-15F

@FLOW 1-2-3NO-4NO-5-3
@FLOW 3YES-6-13-14-15
@FLOW 4YES-6
@BOX 1.0
UNKILL
@BOX 2.0
SET UP POINTERS
@BOX 3.0
END OF KILL BUFFER?
@BOX 4.0
PUT NEXT CHARACTER FROM KILL BUFFER
INTO STORE AND CHECK IF FULL?
@BOX 5.0
ADJUST TEMP CURSOR
@BOX 6.0
COMPUTE NEW SCREEN CONTENTS AND REFRESH
[EDT03.26]
@BOX 13.0
DISPLAY APPROPRIATE MESSAGE
AND SET MARK TO UNDEFINED
[EDT03.20]
@BOX 14.0
RESET REPEAT COUNTER
@BOX 15.0
END
@BOX 19.0
SET NUMBER OF LINES TO
BE REFRESHED
@BOX 20.0
UPDATE SCREEN CONTENTS
AND DISPLAY
@BOX 33.0
GAP NOT FULL ?
@BOX 34.0
GAP CANNOT BE CREATED ?
@BOX 35.0
UPDATE POINTERS
@BOX 1.1
::UNKILL REGION
BEGIN
INTEGER MESS.NO, CH, DUMP.PTR, DUMP.BLOCK, T.LINE, T.COL,
    BUF.FULL;
INTEGER32 INS.CNT;
@BOX 2.1
STRT.OF.GAP => DUMP.BLOCK;
GAP.PTR => DUMP.PTR;
C.LINE => T.LINE;
C.COL => T.COL;
0 => INS.CNT => BUF.FULL;
-1 => KILL.PTR;
@BOX 3.1
IF 1 +> KILL.PTR = SIZE.OF.REGION
@BOX 4.1
IF STRT.OF.DATA - STRT.OF.GAP =< 2 AND
   GAP.PTR >= DATA.PTR THEN
   -1 => BUF.FULL;
FI
IF BUF.FULL /= 0
  OR PUT.GAP.CHAR (KILL.BUF.PTR^ [KILL.PTR] => CH)
   => BUF.FULL /= 0
@BOX 5.1
1 +> INS.CNT;
IF CH >= %A =< %D OR
   T.COL = MAX.COLS - 1 THEN
   1 +> T.LINE;
   0 => T.COL;
ELSE
   1 +> T.COL;
FI
@BOX 6.1
UPDATE.AFTER.INSERT (INS.CNT, T.LINE, T.COL, DUMP.BLOCK, DUMP.PTR);
@BOX 13.1
(IF BUF.FULL < 0 THEN 4 ELSE 3)  => MESS.NO;
MONITOR.MESSAGE (MESS.NO);
-1 => MARKED.COL;
@BOX 14.1
1 => REP.CNT;
@BOX 15.1
END
@BOX 16.1
0 => C.COL;
1 +> C.LINE;
1 -> KILL.PTR;
@BOX 19.1
IF FILE.OVER.FLOW < 0 THEN
   4 => MESS.NO;
FI
IF C.LINE = DUMP.LINE AND KILL.SIZE
   + INIT.CNT =< MAX.COLS THEN
   1 => INIT.CNT;
ELSE
   MAX.LINES - DUMP.LINE => INIT.CNT;
FI
@BOX 20.1
IF C.LINE = 0 AND C.COL = 0 THEN
   REFRESH.SCREEN (STRT.OF.DATA, DATA.PTR,
      C.LINE, C.COL, INIT.CNT );
ELSE
   REFRESH.SCREEN (DUMP.STRT, DUMP.PTR,
      DUMP.LINE, DUMP.COL, INIT.CNT );
FI
POSITION.CURSOR (C.LINE, C.COL);
BREAK.OUTPUT (0);
@BOX 33.1
IF STRT.OF.GAP /= STRT.OF.DATA OR
   GAP.PTR < DATA.PTR
@BOX 34.1
IF CREATE.GAP () => FILE.OVER.FLOW < 0
@BOX 35.1
DUMP.STRT + MASK.BUF.LIST & MASK.BUF.LIST => DUMP.STRT;
@END
@TITLE EDT03.1.2.24(1,10)

@COL 1S-4T-2R-3F
@COL 5R
@ROW 2-5
@FLOW 1-4SNGL CMD-2-3
@FLOW 4DBL CMD-5-3
@BOX 1.0
FIND COMMAND
@BOX 2.0
FIND THE COMMAND NUMBER
@BOX 3.0
END
@BOX 4.0
CHARACTER IS A DOUBLE COMMAND PREFIX ?
@BOX 5.0
FIND THE COMMAND
@BOX 1.1
::FIND.CMD
BEGIN
INTEGER TEMP;
LITERAL / INTEGER NO.OF.CMDS = 14, NO.OF.DBL.CMDS = 8;
LITERAL / INTEGER MAX.CMD.NO = NO.OF.CMDS + NO.OF.DBL.CMDS;
DATAVEC CMD.VEC (LOGICAL8)
   %17 %17 %5  %5 "C" %10 "D" %F  "B" %19
   "A" %15 "P" %4 %14 %14 "M" %18 "T" %1A
   "S" %1  "V" %2 "U" %16 %12 %12
END
DATAVEC DBL.CMD.VEC (LOGICAL8)
   %17 %17 %5  %5  %12 %12 "V" %2
   "U" %16 "T" %1A "M" %18 "S" %1
END
PSPEC READ.CMD (INTEGER) / INTEGER;
PROC READ.CMD (INIT.CH);
IF INIT.CH = %1B THEN
   READ.CH (DEV.NO);
FI
READ.CH (DEV.NO);
PW1 => READ.CMD;
END
-1 => CMD;
@BOX 2.1
IF CH = %1B OR CH = %9B THEN
   READ.CMD (CH) => OLD.CHAR & %FF => CH;
FI
NO.OF.CMDS * 2 => TEMP;
WHILE 1 +> CMD < TEMP AND
   CMD.VEC [CMD] /= CH
DO OD
2 /> CMD;
IF CMD = NO.OF.CMDS THEN
   MAX.CMD.NO => CMD;
FI
@BOX 3.1
END
@BOX 4.1
IF CH = DBL.CMD.PREFIX
@BOX 5.1
READ.CH (DEV.NO);
PW1 => OLD.CHAR & %FF => CH;
NO.OF.DBL.CMDS * 2 => TEMP;
IF CH = %1B OR CH = %9B THEN
   READ.CMD (CH) => OLD.CHAR & %FF => CH;
FI
WHILE 1 +> CMD < TEMP AND
   DBL.CMD.VEC [CMD] /= CH
DO OD
2 /> CMD;
IF CMD = NO.OF.DBL.CMDS THEN
   MAX.CMD.NO => CMD;
ELSE
   CMD + NO.OF.CMDS => CMD;
FI
@END
@TITLE EDT03.1.3(1,11)
@COL 1S-2T-3T-4R-5R-12R-13F
@COL 14R-17N-15R
@ROW 3-14
@ROW 5-15
@FLOW 1-2NO-3NO-4-5-12-13
@FLOW 2YES-14-17-15-12
@FLOW 3YES-17
@BOX 1.0
MONITOR COMPLETION
@BOX 2.0
ERROR ?
@BOX 3.0
QUIT ?
@BOX 4.0
SET PREAMBLES
@BOX 5.0
CREATE RESULTANT FILE
@BOX 12.0
RELEASE OTHER SEGMENTS
@BOX 13.0
END
@BOX 14.0
DISPLAY FAULT MESSAGE
[EDT03.20]
@BOX 15.0
RELEASE INPUT SEGMENT
@BOX 18.0
FINAL RESULT IS TO BE A SEGMENT?
@BOX 1.1
::MONITOR COMPLETION
BEGIN
INTEGER I;
INTEGER32 CNT;
@BOX 2.1
IF ERROR /= 0
@BOX 3.1
IF FINISHED /= 2
@BOX 4.1
COPY.CHARS.UP (END.OF.BLKS + 1 * SYS14.PAGE.SIZE);
STRT.OF.GAP + 1 * SYS14.PAGE.SIZE -
   (STX.POS + 1) - (SYS14.PAGE.SIZE - GAP.PTR - 1) => CNT;
FOR 4 DO
   PUT.GAP.CHAR (%FF);
OD
SAVE.POINTERS ();
SET.GAP.POINTERS (0, -1);
FOR I < 4 DO
   CNT & %FF => GAP.CH.PTR^ [I];
   CNT ->> 8 => CNT;
OD
IF I.SEG.STATUS /= 0 THEN
   COPY.BLOCK (MAPPED.IO.SEG.NO, 0, I.SEG.NO, 0);
FI
READ.SEGMENT.STATUS (I.SEG.NO);
IF PW2 & %20 = 0 THEN
   CHANGE.SIZE (I.SEG.NO, S.STRT.OF.GAP  + 1 * SYS14.PAGE.SIZE);
ELSE
   CHANGE.SIZE (I.SEG.NO, S.STRT.OF.GAP + 1);
FI
@BOX 5.1
IF O.DOC.TYPE = 0 THEN
   LIB07.MAKE.CURRENT.FILE (I.SEG.NO);
ELSE
   FILE (O.FILE.NAME, O.USER.NAME, I.SEG.NO);
   RELEASE.SEGMENT (I.SEG.NO);
FI
POSITION.CURSOR (MAX.LINES + 2, 0);
CAPTION (%"End of Edit$L");
OUT.FN (O.FILE);
CAPTION (%"   OK$L");
@BOX 12.1
RELEASE.SEGMENT (BUF.SEG.NO);
RELEASE.SEGMENT (KILL.SEG.NO);
BREAK.OUTPUT (0);
CHANGE.CHANNEL (PERI.SPN, 1, OLD.P.MODE);
END.OUTPUT (BOUT, 0);
MAP (OLD.MAPPED.IO.SEG, MAPPED.IO.SEG.NO, 0);
MAP (OLD.MAPPED.KILL.SEG, MAPPED.KILL.SEG.NO, 0);
SET.TRAP (3, OLD.TRAP.PROC.ADDR);
@BOX 13.1
END
@BOX 14.1
MONITOR.MESSAGE (5);
@BOX 15.1
POSITION.CURSOR (MAX.LINES + 2, 1);
CAPTION (%"Edit Aborted$L");
RELEASE.SEGMENT (I.SEG.NO);
@BOX 18.1
IF INP.SEG > 0
@END


@TITLE EDT03.2(1,9)

@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
EXTERNAL INTERRUPT TRAP
@BOX 2.0
PROCESS INTERRUPT AND
RELEASE SEGMENTS
@BOX 3.0
END
@BOX 1.1
PROC EXTERNAL.INTERRUPT.TRAP (TRAP.NO, REASON);
@BOX 2.1
MONITOR.MESSAGE (8);
WAIT (0, 2);
CHANGE.CHANNEL (PERI.SPN, 0, P.MODE);
RETURN.FROM.TRAP ();
::TEMP SWITCH BRK OFF
::SELECT.OUTPUT (0);
::BREAK.OUTPUT (0);
::OUT.CH (%1B);
::CAPTION (%"]R");
::OUT.CH (%1B);
::OUT.CH ('\);
::BREAK.OUTPUT (0);
::LIB07.RELEASE.BUFFER.SEG (I.SEG.NO);
::RELEASE.SEGMENT (BUF.SEG.NO);
::RELEASE.SEGMENT (KILL.SEG.NO);
::RELEASE.SEGMENT (NEW.SEG);
::0 => PW0;
::SET.TRAP (TRAP.NO, OLD.TRAP.PROC.ADDR [3]);
::ENTER.TRAP (TRAP.NO, REASON);
@BOX 3.1
END
@END
@TITLE EDT03.3(1,11)
@COL 1S-2T-8N-9N-3R-4F
@COL 5T-6R-7R
@ROW 8-5
@ROW 9-6
@ROW 3-7
@FLOW 1-2NO-8-9-3-4
@FLOW 2YES-5NO-6-3
@FLOW 5YES-7-4
@BOX 1.0
GET GAP CHARACTER () CHAR
@BOX 2.0
END OF BLOCK?
@BOX 3.0
RETURN CHARACTER
@BOX 4.0
END
@BOX 5.0
END OF FILE?
[EDT03.4]
@BOX 6.0
ADJUST POINTERS
@BOX 7.0
RETURN EOF STATUS
@BOX 1.1
PROC GET.GAP.CHAR;
@BOX 2.1
IF GAP.PTR =< GAP.PTR.STRT
@BOX 3.1
GAP.CH.PTR^ [GAP.PTR] => GET.GAP.CHAR;
1 -> GAP.PTR;
@BOX 4.1
END
@BOX 5.1
IF GET.GAP.BLOCK (STRT.OF.GAP - 1) /= 0
@BOX 6.1
IF STRT.OF.GAP /= 0 THEN
   -1 => GAP.PTR.STRT;
ELSE
   STX.POS => GAP.PTR.STRT;
FI
SYS14.PAGE.SIZE - 1 => GAP.PTR;
@BOX 7.1
-1 => GET.GAP.CHAR;
@END
@TITLE EDT03.4(1,9)
@COL 7R
@COL 1S-2T-3T-4R-5R-6F
@COL 8R
@ROW 7-4-8
@FLOW 1-2NO-3NO-4-5-6
@FLOW 2YES-8-6
@FLOW 3YES-7-5
@BOX 1.0
GET GAP BLOCK (BLOCK) STATUS
@BOX 2.0
BLOCK NO OUT OF RANGE?
@BOX 3.0
SEGMENT DIRECTLY ACCESSIBLE?
@BOX 4.0
COPY BLOCK
@BOX 5.0
SET START OF GAP POINTER
@BOX 6.0
END
@BOX 7.0
ACCESS REQUIRED BLOCK
@BOX 8.0
RETURN FAULT STATUS
@BOX 1.1
PROC GET.GAP.BLOCK (BLOCK);
INTEGER32 TEMP;
@BOX 2.1
IF BLOCK + 1 >= STRT.OF.DATA OR
   BLOCK < 0
@BOX 3.1
IF I.SEG.STATUS = 0
@BOX 4.1
IF GAP.PTR /= 0 THEN
   COPY.BLOCK (MAPPED.IO.SEG.NO, 0, I.SEG.NO, STRT.OF.GAP);
FI
IF BLOCK < STRT.OF.GAP THEN
   COPY.BLOCK (I.SEG.NO, BLOCK, MAPPED.IO.SEG.NO, 0);
FI
@BOX 5.1
BLOCK => STRT.OF.GAP;
0 => GET.GAP.BLOCK;
@BOX 6.1
END
@BOX 7.1
BLOCK * SYS14.PAGE.SIZE => TEMP;
MAKE (LOGICAL8, SYS14.PAGE.SIZE, SYS14.SEG.SIZE *
   I.SEG.NO + TEMP) => GAP.CH.PTR;
@BOX 8.1
-1 => GET.GAP.BLOCK;
@END
@TITLE EDT03.5(1,11)
@COL 1S-9R-23R-22R-2T-3R-4T-5T-6T-10R-7R-8R-16N
@COL 17N-11R-20N
@COL 18N-13R-14R-15F
@ROW 4-18
@ROW 5-17
@ROW 7-11
@ROW 16-20
@FLOW 1-9-23-22-2NO-3-4OTHER-5OTHER-6FULL-10-11-20-16-2
@FLOW 2YES-14-15
@FLOW 4EOS-18-13-14
@FLOW 5YES-17-11
@FLOW 6NOT FULL-7-8-4
@BOX 1.0
UPDATE (SOURCE BLOCK, SOURCE POINTER, DEST LINE, DEST COL, COUNT)
@BOX 2.0
END OF REFRESHING?
@BOX 3.0
POSITION CURSOR
@BOX 4.0
GET NEXT CHARACTER?
@BOX 5.0
'LF', 'CR', OR 'FF'?
@BOX 6.0
LINE NOT FULL?
@BOX 7.0
OUTPUT THE CHARACTER
@BOX 8.0
PREPARE NEXT CHARACTER
@BOX 9.0
IF COUNT IS NEGATIVE (-CHARS DELETED)
FIND NUMBER OF LINES TO BE UPDATED
@BOX 10.0
PROCESS LONG LINE CONDITION
@BOX 11.0
PREPARE FOR NEXT LINE
@BOX 13.0
PROCESS 'EOS' CONDITION
@BOX 14.0
EMPTY OUTPUT STREAM
SET END OF WINDOW IF THERE
@BOX 15.0
END
@BOX 22.0
SET POINTERS
@BOX 23.0
SET DISPLAY TYPE REQUIRED
@BOX 1.1
PROC UPDATE (S.BLK, S.PTR, D.LINE, D.COL, COUNT);
INTEGER CH, EOS.FLAG, BEF.GAP, T.LINE;
0 => EOS.FLAG => BEF.GAP;
@BOX 2.1
SELECT SCREEN.LIST [D.LINE];
0 => CTD;
IF D.LINE = MAX.LINES OR COUNT = 0
@BOX 3.1
1 => DISPLAY.STATE;
IF D.COL < DISPLAY.COL THEN
   D.COL => DISPLAY.COL;
FI
@BOX 4.1
::GET NEXT WINDOW CHAR
#EDT03.5.1
IF EOS.FLAG /= 0
@BOX 5.1
IF CH >= %A =< %D
@BOX 6.1
IF D.COL < MAX.COLS -1
@BOX 7.1
CH => LINE.VEC [D.COL];
@BOX 8.1
1 +> D.COL;
@BOX 9.1
IF COUNT < 0 THEN
   -1 *> COUNT;
   0 => T.LINE;
   WHILE 1 +> T.LINE + D.LINE < MAX.LINES AND
      CTD OF SCREEN.LIST [T.LINE + D.LINE] /= 0
   DO OD
   IF T.LINE + D.LINE < MAX.LINES AND
      CH.CNT OF SCREEN.LIST [T.LINE + D.LINE]
      > COUNT THEN
      1 + T.LINE => COUNT;
   ELSE
      MAX.LINES - D.LINE => COUNT;
   FI
FI
@BOX 10.1
1 => CTD;
@BOX 11.1
CH => LINE.VEC [D.COL];
1 + D.COL => CH.CNT;
1 +> D.LINE;
0 => D.COL;
1 -> COUNT;
@BOX 13.1
"e" => LINE.VEC [D.COL];
D.COL + 1 => CH.CNT;
WHILE 1 +> D.LINE < MAX.LINES DO
   0 => CH.CNT OF SCREEN.LIST [D.LINE]
     => CTD OF SCREEN.LIST [D.LINE]
     => DISPLAY.COL OF SCREEN.LIST [D.LINE];
   1 => DISPLAY.STATE OF SCREEN.LIST [D.LINE];
OD
@BOX 14.1
IF EOS.FLAG /= 0 OR
   D.LINE = MAX.LINES THEN
   STRT.OF.DATA => END.OF.WINDOW;
   DATA.PTR => W.END.PTR;
FI
SET.DATA.POINTERS (S.STRT.OF.DATA, S.DATA.PTR);
@BOX 15.1
END
@BOX 22.1
SAVE.POINTERS ();
IF S.BLK < STRT.OF.GAP OR
   [S.BLK = STRT.OF.GAP AND S.PTR =< GAP.PTR]
   THEN
   SET.GAP.POINTERS (S.BLK, S.PTR);
ELSE
   -1 => BEF.GAP;
   D.LINE => C.LINE;
   D.COL => C.COL;
FI
@BOX 23.1
IF COUNT = 1 AND [DISPLAY < SINGLE.LINE.REFRESH OR
   [DISPLAY = SINGLE.LINE.REFRESH AND D.LINE
   = LINE.AFFECTED]] THEN
   SINGLE.LINE.REFRESH => DISPLAY;
   D.LINE => LINE.AFFECTED;
ELSE
   MULTI.LINE.REFRESH => DISPLAY;
FI
@END
@TITLE EDT03.5.1(1,9)
@COL 1S-2T-11N-12N-3T-4R-5F
@COL 8T-9R-10R
@ROW 11-8
@ROW 12-9
@ROW 4-10
@FLOW 1-2AFT GAP-11-12-3NO-4-5
@FLOW 2BEF GAP-8NO-9-12
@FLOW 8YES-10-5
@FLOW 3YES-5
@BOX 1.0
GET NEXT WINDOW CHARACTER
@BOX 2.0
CHECK POSITION?
@BOX 3.0
END OF FILE?
@BOX 4.0
GET NEXT CHARACTER
@BOX 5.0
END
@BOX 8.0
START OF GAP NOT REACHED?
@BOX 9.0
SET CURSOR AT THIS POINT
@BOX 10.0
GET NEXT CHARACTER
@BOX 1.1
::GET NEXT WINDOW CHARACTER
BEGIN
@BOX 2.1
IF BEF.GAP = 0
@BOX 3.1
IF DATA.PTR >= DATA.PTR.END AND
   SET.DATA.POINTERS (STRT.OF.DATA + 1 , -1)
   => EOS.FLAG /= 0
@BOX 4.1
DATA.CH.PTR^ [1 +> DATA.PTR] => CH;
@BOX 5.1
END
@BOX 8.1
IF GAP.PTR < GAP.PTR.END OR
   SET.GAP.POINTERS (STRT.OF.GAP + 1, -1)
   => BEF.GAP = 0
@BOX 9.1
D.LINE => C.LINE;
D.COL => C.COL;
@BOX 10.1
GAP.CH.PTR^ [1 +> GAP.PTR] => CH;
@END
@TITLE EDT03.7(1,11)

@COL 1S-2R-5R-3F

@FLOW 1-2-5-3
@BOX 1.0
CLEAR SCREEN
@BOX 2.0
CLEAR SCREEN AND SET LOWER LINES
@BOX 3.0
END
@BOX 5.0
SEND OUTPUT
@BOX 1.1
PROC CLEAR.SCREEN;
INTEGER CH, I;
@BOX 2.1
SELECT.OUTPUT (BOUT);
ALTERNATIVE TERMINAL.TYPE FROM
   ::ANSI
   BEGIN
      OUT.CH (%1B);
      CAPTION (%"[2J");
   END
   ::NEWBURY
   OUT.CH (%1F);
   ::INTERTUBE
   OUT.CH (%1C);
END
@BOX 3.1
END
@BOX 5.1
POSITION.CURSOR (MAX.LINES, 0);
FOR MAX.COLS DO
   OUT.CH ("-");
OD
POSITION.CURSOR (MAX.LINES + 1, 48);
CAPTION (%"INPUT  FILE> ");
IF I.USER.NAME /= 0 THEN
   OUT.NAME (I.USER.NAME);
   OUT.CH(":");
FI
IF I.DOC.TYPE /= 0 THEN
   CAPTION (I.FILE.NAME);
ELSE
   CAPTION (%"<CFILE> ");
FI
POSITION.CURSOR (MAX.LINES + 2, 48);
CAPTION (%"OUTPUT FILE> ");
IF O.USER.NAME /= 0 THEN
   OUT.NAME (O.USER.NAME);
   OUT.CH (":");
FI
IF O.DOC.TYPE /= 0 THEN
  CAPTION (O.FILE.NAME);
ELSE
   CAPTION (%"<CFILE> ");
FI
BREAK.OUTPUT (BOUT);
SELECT.OUTPUT (0);
@END
@TITLE EDT03.8(1,9)
@COL 1S-2T-8N-9N-3R-4F
@COL 5T-6R-7R
@ROW 8-5
@ROW 9-6
@ROW 3-7
@FLOW 1-2NO-8-9-3-4
@FLOW 2YES-5NO-6-3
@FLOW 5YES-7-4
@BOX 1.0
PUT GAP CHARACTER (CHAR) STATUS
@BOX 2.0
END OF BLOCK?
@BOX 3.0
STORE CHARACTER
@BOX 4.0
END
@BOX 5.0
NO MORE SPACE?
@BOX 6.0
SET POINTERS
@BOX 7.0
RETURN FAULT STATUS
@BOX 1.1
PROC PUT.GAP.CHAR (CH);
@BOX 2.1
IF GAP.PTR >= SYS14.PAGE.SIZE - 1
@BOX 3.1
CH => GAP.CH.PTR^ [1 +> GAP.PTR];
0 => PUT.GAP.CHAR;
@BOX 4.1
END
@BOX 5.1
IF GET.GAP.BLOCK (STRT.OF.GAP + 1) /= 0
@BOX 6.1
-1 => GAP.PTR => GAP.PTR.STRT;
@BOX 7.1
-1 => PUT.GAP.CHAR;
@END
@TITLE EDT03.9(1,10)

@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ERASE TO EOL
@BOX 2.0
ERASE TO EOL
@BOX 3.0
END
@BOX 1.1
PROC ERASE.TO.EOL;
@BOX 2.1
ALTERNATIVE TERMINAL.TYPE FROM
   ::ANSI
   BEGIN
      OUT.CH (%1B);
      CAPTION (%"[K");
   END
   ::NEWBURY
   OUT.CH (%19);
   ::INTERTUBE
   BEGIN
      OUT.CH (%1B);
      OUT.CH (%5B);
   END
END
@BOX 3.1
END
@END
@TITLE EDT03.10(1,9)
@COL 7R
@COL 1S-2T-3T-4R-5R-6F
@COL 8R
@ROW 4-7-8
@FLOW 1-2NO-3NO-4-5-6
@FLOW 2YES-8-6
@FLOW 3YES-7-5
@BOX 1.0
GET DATA BLOCK (BLOCK) STATUS
@BOX 2.0
END OF FILE?
@BOX 3.0
SEGMENT DIRECTLY ACCESSIBLE?
@BOX 4.0
COPY BLOCK
@BOX 5.0
SET START OF DATA POINTER
@BOX 6.0
END
@BOX 7.0
ACCESS NEXT BLOCK
@BOX 8.0
RETURN FAULT STATUS
@BOX 1.1
PROC GET.DATA.BLOCK (BLOCK);
INTEGER32 TEMP;
@BOX 2.1
IF BLOCK > END.OF.BLKS OR
   BLOCK =< STRT.OF.GAP
@BOX 3.1
IF I.SEG.STATUS = 0
@BOX 4.1
IF DATA.PTR < SYS14.PAGE.SIZE - 1 THEN
   COPY.BLOCK (MAPPED.IO.SEG.NO, 1, I.SEG.NO, STRT.OF.DATA);
FI
IF BLOCK > STRT.OF.DATA THEN
   COPY.BLOCK (I.SEG.NO, BLOCK, MAPPED.IO.SEG.NO, 1);
FI
@BOX 5.1
BLOCK => STRT.OF.DATA;
0 => GET.DATA.BLOCK;
@BOX 6.1
END
@BOX 7.1
BLOCK * SYS14.PAGE.SIZE => TEMP;
MAKE (LOGICAL8, SYS14.PAGE.SIZE, I.SEG.NO *
   SYS14.SEG.SIZE + TEMP)
   => DATA.CH.PTR;
@BOX 8.1
-1 => GET.DATA.BLOCK;
@END
@TITLE EDT03.11(1,10)

@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
POSITION CURSOR (LINE, COLUMN)
@BOX 2.0
POSITION THE CURSOR
@BOX 3.0
END
@BOX 1.1
PROC POSITION.CURSOR (LINE, COL);
INTEGER Q;
@BOX 2.1
ALTERNATIVE TERMINAL.TYPE FROM
   ::ANSI
   BEGIN
      OUT.CH (%1B);
      OUT.CH ('[);
      OUT.I (1 + LINE, 0);
      OUT.CH (";");
      OUT.I (1 + COL, 0);
      OUT.CH ('H);
   END
   ::NEWBURY
   BEGIN
      OUT.CH (%16);
      OUT.CH (COL + %20);
      OUT.CH (LINE + %20);
   END
   ::INTERTUBE
   BEGIN
      OUT.CH (%1B);
      OUT.CH ("Y");
      OUT.CH (LINE + %20);
      OUT.CH (COL + %20);
   END
END
@BOX 3.1
END
@END
@TITLE EDT03.12(1,11)
@COL 1S-2T-3T-14N-15N-4T-16N-17N-5R-13F
@COL 11N-6T-7R-8T-9R-12N
@ROW 2-11
@ROW 14-6
@ROW 15-7
@ROW 17-8
@ROW 17-9
@ROW 13-12
@FLOW 1-2NO-3NO-14-15-4NO-16-17-5-2
@FLOW 2YES-11-12-13
@FLOW 3YES-6NO-7-4
@FLOW 6YES-12
@FLOW 4YES-8NO-9-5
@FLOW 8YES-12
@BOX 1.0
COPY CHARACTERS UP (COUNT)
@BOX 2.0
END OF COPY?
@BOX 3.0
END OF DATA BLOCK?
@BOX 4.0
END OF GAP BLOCK?
@BOX 5.0
COPY CHARACTER
@BOX 6.0
END OF FILE?
[EDT03.10]
@BOX 7.0
SET POINTERS
@BOX 8.0
BUFFER FULL?
[EDT03.4]
@BOX 9.0
SET POINTERS
@BOX 13.0
END
@BOX 1.1
PROC COPY.CHARS.UP (COUNT);
@BOX 2.1
IF 1 -> COUNT < 0
@BOX 3.1
IF DATA.PTR >= DATA.PTR.END
@BOX 4.1
IF GAP.PTR >= SYS14.PAGE.SIZE -1
@BOX 5.1
DATA.CH.PTR^ [1 +> DATA.PTR] =>
   GAP.CH.PTR^ [1 +> GAP.PTR];
@BOX 6.1
IF GET.DATA.BLOCK (STRT.OF.DATA + 1) /= 0
@BOX 7.1
-1 => DATA.PTR;
SYS14.PAGE.SIZE-1=>PAGESIZE.AD;
(IF STRT.OF.DATA = END.OF.BLKS THEN
   ETX.POS ELSE PAGESIZE.AD)
   => DATA.PTR.END;
@BOX 8.1
IF GET.GAP.BLOCK (STRT.OF.GAP + 1) /= 0
@BOX 9.1
-1 => GAP.PTR => GAP.PTR.STRT;
@BOX 13.1
END
@END
@TITLE EDT03.13(1,11)
@COL 1S-2T-3T-13N-14N-4T-15N-16N-5R-6F
@COL 11N-7T-8R-9T-10R-12N
@ROW 2-11
@ROW 13-7
@ROW 14-8
@ROW 15-9
@ROW 16-10
@ROW 6-12
@FLOW 1-2NO-3NO-13-14-4NO-15-16-5-2
@FLOW 2YES-11-12-6
@FLOW 3YES-7NO-8-4
@FLOW 7YES-12
@FLOW 4YES-9NO-10-5
@FLOW 9YES-12
@BOX 1.0
COPY CHARACTERS DOWN (COUNT)
@BOX 2.0
END OF COPY?
@BOX 3.0
NEED PREVIOUS BLOCK?
@BOX 4.0
NEED ANOTHER BLOCK FOR DATA?
@BOX 5.0
COPY CHARACTER
@BOX 6.0
END
@BOX 7.0
PASSED BEGINNING OF FILE?
[EDT03.4]
@BOX 8.0
SET GAP POINTERS
@BOX 9.0
BUFFER FULL?
[EDT03.10]
@BOX 10.0
SET DATA POINTERS
@BOX 1.1
PROC COPY.CHARS.DOWN (COUNT);
@BOX 2.1
IF 1 -> COUNT < 0
@BOX 3.1
IF GAP.PTR =< GAP.PTR.STRT
@BOX 4.1
IF DATA.PTR < 0
@BOX 5.1
GAP.CH.PTR^ [GAP.PTR] => DATA.CH.PTR^ [DATA.PTR];
1 -> DATA.PTR;
1 -> GAP.PTR;
@BOX 6.1
END
@BOX 7.1
IF GET.GAP.BLOCK (STRT.OF.GAP - 1) /= 0
@BOX 8.1
IF STRT.OF.GAP /= 0 THEN
   -1 => GAP.PTR.STRT;
ELSE
   STX.POS => GAP.PTR.STRT;
FI
SYS14.PAGE.SIZE - 1 => GAP.PTR;
@BOX 9.1
IF GET.DATA.BLOCK (STRT.OF.DATA - 1) /= 0
@BOX 10.1
SYS14.PAGE.SIZE - 1 => DATA.PTR
   => DATA.PTR.END;
@END
@TITLE EDT03.14(1,11)
@COL 1S-2T-8N-9N-3R-4F
@COL 5T-6R-7R
@ROW 8-5
@ROW 9-6
@ROW 3-7
@FLOW 1-2NO-8-9-3-4
@FLOW 2YES-5NO-6-3
@FLOW 5YES-7-4
@BOX 1.0
GET DATA CHARACTER () CHAR
@BOX 2.0
END OF BLOCK?
@BOX 3.0
GET CHARACTER
@BOX 4.0
END
@BOX 5.0
END OF FILE?
[EDT03.10]
@BOX 6.0
SET POINTERS
@BOX 7.0
RETURN FAULT STATUS
@BOX 1.1
PROC GET.DATA.CHAR;
@BOX 2.1
IF DATA.PTR >= DATA.PTR.END
@BOX 3.1
DATA.CH.PTR^ [1 +> DATA.PTR] => GET.DATA.CHAR;
@BOX 4.1
END
@BOX 5.1
IF GET.DATA.BLOCK (STRT.OF.DATA + 1) /= 0
@BOX 6.1
-1 => DATA.PTR;
SYS14.PAGE.SIZE-1=>PAGESIZE.AD;
(IF STRT.OF.DATA = END.OF.BLKS THEN ETX.POS
   ELSE PAGESIZE.AD) => DATA.PTR.END;
@BOX 7.1
-1 => GET.DATA.CHAR;
@END
@TITLE EDT03.15(1,9)

@COL 1S-5R-4F

@FLOW 1-5-4
@BOX 1.0
SET TERMINAL TYPE (TYPE)
@BOX 4.0
END
@BOX 5.0
SET TO SPECIAL MODE
@BOX 1.1
PROC SET.TERMINAL.TYPE (T.TYPE);
INTEGER [4] SOURCE;
@BOX 4.1
END
@BOX 5.1
IF T.TYPE => TERMINAL.TYPE >= NO.OF.TERMINAL.TYPES THEN
   0 => TERMINAL.TYPE;
FI
I.SOURCE (^SOURCE);
CHANGE.CHANNEL (SOURCE [0] => PERI.SPN, 0, P.MODE);
PW1 => DEV.NO;
PW2 => OLD.P.MODE;
@BOX 6.1
IF T.TYPE => TERMINAL.TYPE > 0 =< NO.OF.TERMINAL.TYPES
@END
@TITLE EDT03.16(1,11)
@COL 1S-2T-8N-9N-3R-4F
@COL 5T-6R-7R
@ROW 8-5
@ROW 9-6
@ROW 3-7
@FLOW 1-2NO-8-9-3-4
@FLOW 2YES-5NO-6-3
@FLOW 5YES-7-4
@BOX 1.0
PUT DATA CHARACTER (CHAR) STATUS
@BOX 2.0
NO MORE DATA IN THIS BLOCK?
@BOX 3.0
PUT CHARACTER INTO BUFFER
@BOX 4.0
END
@BOX 5.0
NO MORE BLOCKS?
[EDT03.10]
@BOX 6.0
SET DATA POINTERS
@BOX 7.0
RETURN FAULT STATUS
@BOX 1.1
PROC PUT.DATA.CHAR (CH);
@BOX 2.1
IF DATA.PTR < 0
@BOX 3.1
CH => DATA.CH.PTR^ [DATA.PTR];
1 -> DATA.PTR;
0 => PUT.DATA.CHAR;
@BOX 4.1
END
@BOX 5.1
IF GET.DATA.BLOCK (STRT.OF.DATA - 1) /= 0
@BOX 6.1
SYS14.PAGE.SIZE - 1 => DATA.PTR => DATA.PTR.END;
@BOX 7.1
-1 => PUT.DATA.CHAR;
@END
@TITLE EDT03.17(1,11)
@COL 8R
@COL 1S-2T-3T-4T-5R-6R-7F
@COL 9R
@ROW 8-5
@ROW 6-9
@FLOW 1-2NO-3NO-4NO-5-6-7
@FLOW 2YES-9-7
@FLOW 3YES-8-6
@FLOW 4YES-6
@BOX 1.0
SET DATA POINTERS (BLOCK, PTR) STATUS
@BOX 2.0
BLOCK OUT OF RANGE?
@BOX 3.0
SEGMENT DIRECTLY ACCESSIBLE?
@BOX 4.0
NO CHANGE IN DATA BLOCK NUMBER?
@BOX 5.0
COPY APPROPRIATE BLOCK
@BOX 6.0
SET POINTERS
@BOX 7.0
END
@BOX 8.0
ACCESS REQUIRED BLOCK
@BOX 9.0
RETURN FAULT STATUS
@BOX 1.1
PROC SET.DATA.POINTERS (BLOCK, PTR);
INTEGER32 TEMP;
@BOX 2.1
IF BLOCK > END.OF.BLKS
@BOX 3.1
IF I.SEG.STATUS = 0
@BOX 4.1
IF BLOCK = STRT.OF.DATA
@BOX 5.1
IF STRT.OF.DATA = S.STRT.OF.DATA AND
   S.DATA.PTR < SYS14.PAGE.SIZE - 1 THEN
   COPY.BLOCK (MAPPED.IO.SEG.NO, 1, I.SEG.NO, STRT.OF.DATA);
FI
IF BLOCK /= S.STRT.OF.DATA OR
   S.DATA.PTR < SYS14.PAGE.SIZE - 1 THEN
   COPY.BLOCK (I.SEG.NO, BLOCK, MAPPED.IO.SEG.NO, 1);
FI
@BOX 6.1
SYS14.PAGE.SIZE-1=>PAGESIZE.AD;
BLOCK => STRT.OF.DATA;
(IF STRT.OF.DATA = END.OF.BLKS THEN ETX.POS ELSE
   PAGESIZE.AD) => DATA.PTR.END;
PTR => DATA.PTR;
0 => SET.DATA.POINTERS;
@BOX 7.1
END
@BOX 8.1
BLOCK * SYS14.PAGE.SIZE => TEMP;
MAKE (LOGICAL8, SYS14.PAGE.SIZE, I.SEG.NO *
   SYS14.SEG.SIZE + TEMP)
   => DATA.CH.PTR;
@BOX 9.1
-1 => SET.DATA.POINTERS;
@END
@TITLE EDT03.18(1,11)
@COL 8R
@COL 1S-2T-3T-4T-5R-6R-7F
@COL 9R
@ROW 8-5
@ROW 6-9
@FLOW 1-2NO-3NO-4NO-5-6-7
@FLOW 2YES-9-7
@FLOW 3YES-8-6
@FLOW 4YES-6
@BOX 1.0
SET GAP POINTERS (BLOCK, PTR) STATUS
@BOX 2.0
BLOCK OUT OF RANGE?
@BOX 3.0
SEGMENT DIRECTLY ACCESSIBLE?
@BOX 4.0
START OF GAP BLOCK NOT TO BE MOVED?
@BOX 5.0
COPY APPROPRIATE BLOCK
@BOX 6.0
SET GAP POINTERS
@BOX 7.0
END
@BOX 8.0
ACESS REQUIRED BLOCK
@BOX 9.0
RETURN FAULT STATUS
@BOX 1.1
PROC SET.GAP.POINTERS (BLOCK, PTR);
INTEGER32 TEMP;
@BOX 2.1
IF BLOCK > S.STRT.OF.GAP
@BOX 3.1
IF I.SEG.STATUS = 0
@BOX 4.1
IF BLOCK = STRT.OF.GAP
@BOX 5.1
IF BLOCK < STRT.OF.GAP THEN
   COPY.BLOCK (MAPPED.IO.SEG.NO, 0, I.SEG.NO, STRT.OF.GAP);
FI
COPY.BLOCK (I.SEG.NO, BLOCK, MAPPED.IO.SEG.NO, 0);
@BOX 6.1
SYS14.PAGE.SIZE-1=>PAGESIZE.AD;
BLOCK => STRT.OF.GAP;
(IF STRT.OF.GAP /= S.STRT.OF.GAP THEN
   PAGESIZE.AD ELSE S.GAP.PTR) => GAP.PTR.END;
IF BLOCK /= 0 THEN
   -1 => GAP.PTR.STRT;
ELSE
   STX.POS => GAP.PTR.STRT;
FI
PTR => GAP.PTR;
0 => SET.GAP.POINTERS;
@BOX 7.1
END
@BOX 8.1
BLOCK * SYS14.PAGE.SIZE => TEMP;
MAKE (LOGICAL8, SYS14.PAGE.SIZE, I.SEG.NO *
   SYS14.SEG.SIZE + TEMP)
   => GAP.CH.PTR;
@BOX 9.1
-1 => SET.GAP.POINTERS;
@END
@TITLE EDT03.19(1,9)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SAVE POINTERS
@BOX 2.0
SAVE DATA AND GAP POINTERS
@BOX 3.0
END
@BOX 1.1
PROC SAVE.POINTERS;
@BOX 2.1
DATA.PTR => S.DATA.PTR;
GAP.PTR => S.GAP.PTR;
STRT.OF.DATA => S.STRT.OF.DATA;
STRT.OF.GAP => S.STRT.OF.GAP;
@BOX 3.1
END
@END
@TITLE EDT03.20(1,9)
@COL 1S-2R-4R-5F
@FLOW 1-2-4-5
@BOX 1.0
MONITOR MESSAGE (MESSAGE NUMBER)
@BOX 2.0
DISPLAY MESSAGE CORRESPONDING
TO THE MESSAGE NUMBER
   0   DISPLAY REPEAT COUNTER
   1   UNABLE TO PERFORM OPERATION
   2   MARK IS NOT SET
   3   DISPLAY SIZE OF REGION
   4   BUFFER FULL
   5   FAULT
   6   REGION TOO WIDE
   7   CLEAR MESSAGE AREA
   8   NO BREAK
@BOX 4.0
REPOSITION CURSOR CORRECTLY
@BOX 5.0
END
@BOX 1.1
PROC MONITOR.MESSAGE (MESSAGE.NO);
@BOX 2.1
POSITION.CURSOR (MAX.LINES + 1, 1);
ALTERNATIVE MESSAGE.NO FROM
   BEGIN
      CAPTION (%"Repeat Counter is ");
      OUT.I (REP.CNT, 0);
   END
   CAPTION (%"UNABLE TO CREATE OUTPUT SEGMENT");
   CAPTION (%"Mark not set    ");
   BEGIN
      CAPTION (%"Size is ");
      OUT.I (SIZE.OF.REGION, 7);
   END
   CAPTION (%"Buffer full     ");
   CAPTION (%"FAULT           ");
   CAPTION (%"Region too wide ");
   SPACES (35);
   CAPTION (%"No break  option");
END
@BOX 4.1
POSITION.CURSOR (C.LINE, C.COL);
BREAK.OUTPUT (0);
@BOX 5.1
END
@END
@TITLE EDT03.21(1,9)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SET MARK
@BOX 2.0
REMEMBER CURRENT POSITION
@BOX 3.0
END
@BOX 1.1
PROC SET.MARK;
@BOX 2.1
STRT.OF.GAP => M.STRT.OF.GAP;
STRT.OF.DATA => M.STRT.OF.DATA;
GAP.PTR => M.GAP.PTR;
DATA.PTR => M.DATA.PTR;
C.COL => MARKED.COL;
@BOX 3.1
END
@END
@TITLE EDT03.22(1,9)
@COL 7R-8R
@COL 1S-2T-10T-4R-5R-3R-6F
@COL 9R
@ROW 7-4
@ROW 8-5-9
@FLOW 1-2NO-10DOWN-4-5-3-6
@FLOW 2YES-9-3
@FLOW 10UP-7-8-3
@BOX 1.0
CHECK MARK POSITION (LINE, COL) COUNT
@BOX 2.0
GAP IS NOT MOVED ?
@BOX 3.0
RETURN LINE AND COL
@BOX 4.0
CALCULATE NUMBER OF
CHARACTERS COPIED UP
@BOX 5.0
FIND OUT WHETHER MARK
IS STILL ON THE SCREEN
@BOX 6.0
END
@BOX 7.0
CALCULATE NUMBER OF
CHARACTERS COPIED DOWN
@BOX 8.0
FIND OUT WHETHER MARK
IS STILL ON THE SCREEN
@BOX 9.0
RETURN APPROPRIATE RESULT
@BOX 10.0
CHECK DIRECTION ?
@BOX 1.1
PROC CHECK.MARK.POS (LINE.ADDR, COL.ADDR);
INTEGER T.LINE, T.COL, TEMP;
INTEGER32 DISP;
C.LINE => T.LINE;
C.COL => T.COL;
@BOX 2.1
IF STRT.OF.GAP = M.STRT.OF.GAP AND
   GAP.PTR = M.GAP.PTR
@BOX 3.1
T.LINE => LINE.ADDR^;
T.COL => COL.ADDR^;
@BOX 4.1
STRT.OF.GAP - M.STRT.OF.GAP *
   SYS14.PAGE.SIZE + GAP.PTR - M.GAP.PTR
   => CHECK.MARK.POS;
@BOX 5.1
IF M.STRT.OF.GAP > STRT.OF.WINDOW OR
   [M.STRT.OF.GAP = STRT.OF.WINDOW AND
   M.GAP.PTR > W.STRT.PTR] THEN
   CHECK.MARK.POS => DISP;
   WHILE T.LINE >= 0 AND DISP > T.COL DO
      T.COL -> DISP;
      IF 1 -> T.LINE >= 0 THEN
         CH.CNT OF SCREEN.LIST [T.LINE] =>
            T.COL;
      FI
   OD
   DISP -> T.COL;
ELSE
   -1 => T.LINE;
FI
@BOX 6.1
END
@BOX 7.1
M.STRT.OF.DATA - STRT.OF.DATA *
   SYS14.PAGE.SIZE + M.DATA.PTR -
   DATA.PTR => CHECK.MARK.POS;
@BOX 8.1
IF M.STRT.OF.DATA < END.OF.WINDOW OR
   [M.STRT.OF.DATA = END.OFWINDOW AND
   M.DATA.PTR =< W.END.PTR] THEN
   CHECK.MARK.POS => DISP;
   WHILE CH.CNT OF SCREEN.LIST [T.LINE] -
      T.COL => TEMP =< DISP DO
      TEMP -> DISP;
      1 +> T.LINE;
      0 => T.COL;
   OD
   DISP +> T.COL;
ELSE
   MAX.LINES => T.LINE;
FI
@BOX 9.1
0 => CHECK.MARK.POS;
@BOX 10.1
IF M.STRT.OF.DATA > STRT.OF.DATA OR
   [M.STRT.OF.DATA = STRT.OF.DATA AND
   M.DATA.PTR > DATA.PTR]
@END
@TITLE EDT03.23(1,11)
@COL 11R
@COL 1S-2T-15N-4T-5T-6R-7T-16R-8R-9R-10F
@COL 12R-14R
@ROW 15-12
@ROW 6-14
@ROW 11-16
@FLOW 1-2OK-15-4OTHERS-5NO-6-7NO-16-8-9-10
@FLOW 2NOT SET-12-14-8
@FLOW 4AT GAP-14
@FLOW 5YES-14
@FLOW 7YES-11-8
@BOX 1.0
COPY TO KILL BUFFER (LINE, COL) STATUS
@BOX 2.0
CHECK MARK ?
@BOX 4.0
CHECK POSITION
OF MARK ?
@BOX 5.0
REGION TOO WIDE?
@BOX 6.0
SAVE POINTERS
@BOX 7.0
MARK BEFORE GAP?
@BOX 8.0
MONITOR MESSAGE
[EDT03.20]
@BOX 9.0
RETURN MARK POSITION
@BOX 10.0
END
@BOX 11.0
COPY REGION TO KILL BUFFER
AND SET POINTERS[EDT03.18]
@BOX 12.0
SET MESSAGE NUMBER
@BOX 14.0
RETURN FAULT STATUS
@BOX 16.0
COPY REGION TO KILL BUFFER
AND SET POINTERS[EDT03.17]
@BOX 1.1
PROC COPY.TO.KILL.BUF (LINE.ADDR, COL.ADDR);
INTEGER MESS.NO, T.LINE, T.COL;
INTEGER32 CNT;
@BOX 2.1
IF MARKED.COL < 0
@BOX 4.1
3 => MESS.NO;
CHECK.MARK.POS (^T.LINE, ^T.COL) => CNT;
IF T.LINE = C.LINE AND
   T.COL = C.COL
@BOX 5.1
6 => MESS.NO;
IF CNT >= KILL.SEG.SIZE
@BOX 6.1
0 => COPY.TO.KILL.BUF;
3 => MESS.NO;
SAVE.POINTERS ();
CNT => SIZE.OF.REGION;
@BOX 7.1
IF T.LINE < C.LINE OR
   [T.LINE = C.LINE AND T.COL< C.COL]
@BOX 8.1
MONITOR.MESSAGE (MESS.NO);
@BOX 9.1
T.LINE => LINE.ADDR^;
T.COL => COL.ADDR^;
@BOX 10.1
END
@BOX 11.1
CNT => KILL.PTR;
ETX => KILL.BUF.PTR^ [KILL.PTR];
FOR CNT DO
   GET.GAP.CHAR () =>
      KILL.BUF.PTR^ [1 -> KILL.PTR];
OD
SET.GAP.POINTERS (S.STRT.OF.GAP, S.GAP.PTR);
@BOX 12.1
C.LINE => T.LINE;
C.COL => T.COL;
2 => MESS.NO;
@BOX 14.1
-1 => COPY.TO.KILL.BUF;
@BOX 16.1
-1 => KILL.PTR;
FOR CNT DO
   GET.DATA.CHAR () =>
      KILL.BUF.PTR^ [1 +> KILL.PTR];
OD
ETX => KILL.BUF.PTR^ [1 +> KILL.PTR];
SET.DATA.POINTERS (S.STRT.OF.DATA, S.DATA.PTR);
@END
@TITLE EDT03.24(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
DISPLAY PROCESSOR ()
@BOX 2.0
SERVICE DISPLAY FROM
   NO ACTION
   POSITION CURSOR
   REFRESH SINGLE LINE
   REFRESH MUTIPLE LINE
@BOX 3.0
END
@BOX 1.1
PROC DISPLAY.PROCESSOR;
@BOX 2.1
ALTERNATIVE DISPLAY FROM
   ::NO ACTION
   0;
   ::POSITION CURSOR
   #EDT03.24.1
   ::REFRESH SINGLE LINE
   #EDT03.24.2
   ::REFRESH MULTIPLE LINES
   #EDT03.24.3
END
@BOX 3.1
END
@END
@TITLE EDT03.24.1(1,10)
@COL 1S-2T-3R-4R-5F
@COL 6R
@ROW 3-6
@FLOW 1-2NO-3-4-5
@FLOW 2YES-6-4
@BOX 1.0
POSITION CURSOR
@BOX 2.0
NOT A SINGLE POSITION MOVE?
@BOX 3.0
MOVE CURSOR TO POSITION
@BOX 4.0
UPDATE CURSOR POSITION
@BOX 5.0
END
@BOX 6.0
POSITION CURSOR
@BOX 1.1
::POSITION CURSOR
BEGIN
INTEGER DIR, Q;
@BOX 2.1
IF O.LINE /= C.LINE OR O.COL - C.COL
   => DIR /= 1 /= -1
@BOX 3.1
IF DIR < 0 THEN
   ALTERNATIVE TERMINAL.TYPE FROM
      ::ANSI
      BEGIN
         OUT.CH (%1B);
         CAPTION (%"[C");
      END
      ::NEWBURY
      OUT.CH (%18);
      ::INTERTUBE
      OUT.CH (%6);
   END
ELSE
   ALTERNATIVE TERMINAL.TYPE FROM
      ::ANSI
      BEGIN
         OUT.CH (%1B);
         CAPTION (%"[D");
      END
      ::NEWBURY
      OUT.CH (%8);
      ::INTERTUBE
      OUT.CH (%15);
   END
FI
@BOX 4.1
BREAK.OUTPUT (-1);
C.LINE => O.LINE;
C.COL => O.COL;
NO.ACTION => DISPLAY;
@BOX 5.1
END
@BOX 6.1
ALTERNATIVE TERMINAL.TYPE FROM
   ::ANSI
   BEGIN
      OUT.CH (%1B);
      OUT.CH ('[);
      OUT.I (1 + C.LINE, 0);
      OUT.CH (";");
      OUT.I (1 + C.COL, 0);
      OUT.CH ('H);
   END
   ::NEWBURY
   BEGIN
      OUT.CH (%16);
      OUT.CH (C.COL + %20);
      OUT.CH (C.LINE + %20);
   END
   ::INTERTUBE
   BEGIN
      OUT.CH (%1B);
      OUT.CH ("Y");
      OUT.CH (C.LINE + %20);
      OUT.CH (C.COL + %20);
   END
END
@END
@TITLE EDT03.24.2(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
REFRESH SINGLE PROGRAM
@BOX 2.0
REFRESH THE LINE
@BOX 3.0
END
@BOX 1.1
::REFRESH SINGLE LINE
BEGIN
@BOX 2.1
SELECT.OUTPUT (BOUT);
REFRESH.LINE (LINE.AFFECTED);
POSITION.CURSOR (C.LINE => O.LINE, C.COL => O.COL);
NO.ACTION => DISPLAY;
BREAK.OUTPUT (-1);
SELECT.OUTPUT (0);
@BOX 3.1
END
@END
@TITLE EDT03.24.3(1,11)
@COL 1S-2R-3R-4R-5R-6T-7N-8R-9F
@COL 10R
@ROW 7-10
@FLOW 1-2-3-4-5-6NO-7-5
@FLOW 6YES-10-8-9
@FLOW 7YES-5
@BOX 1.0
REFRESH MUTIPLE LINES
@BOX 2.0
CLEAR THE SCREEN IF REQUIRED
@BOX 3.0
SELECT BATCH OUTPUT STREAM
@BOX 4.0
FIND FIRST LINE TO BE DISPLAYED
@BOX 5.0
REFRESH LINE
@BOX 6.0
MORE LINE TO REFRESH?
@BOX 8.0
BREAK BATCH OUTPUT STREAM
@BOX 9.0
END
@BOX 10.0
POSITION CURSOR
[EDT03.11]
@BOX 1.1
::REFRESH MUTIPLE LINES
BEGIN
INTEGER LINE.NO;
@BOX 2.1
IF CLEAR.SCREEN.FLAG /= 0 THEN
   CLEAR.SCREEN ();
   0 => CLEAR.SCREEN.FLAG;
FI
@BOX 3.1
SELECT.OUTPUT (BOUT);
@BOX 4.1
-1 => LINE.NO;
WHILE 1 +> LINE.NO < MAX.LINES AND
   DISPLAY.STATE OF SCREEN.LIST [LINE.NO] = 0
   DO OD
@BOX 5.1
REFRESH.LINE (LINE.NO);
@BOX 6.1
WHILE 1 +> LINE.NO < MAX.LINES AND
   DISPLAY.STATE OF SCREEN.LIST [LINE.NO] = 0
   DO OD
IF LINE.NO = MAX.LINES
@BOX 8.1
BREAK.OUTPUT (BOUT);
SELECT.OUTPUT (0);
@BOX 9.1
END
@BOX 10.1
POSITION.CURSOR (C.LINE => O.LINE, C.COL => O.COL);
NO.ACTION => DISPLAY;
@END
@TITLE EDT03.25(1,11)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
REFRESH LINE (LINE NO)
@BOX 2.0
POSITION CURSOR TO THE START
OF THE LINE [EDT03.11]
@BOX 3.0
OUTPUT CHARACTERS WITHIN A LINE
@BOX 4.0
RESET STATE
@BOX 5.0
END
@BOX 1.1
PROC REFRESH.LINE (LINE.NO);
INTEGER COL, CH;
@BOX 2.1
SELECT SCREEN.LIST [LINE.NO];
POSITION.CURSOR (LINE.NO, DISPLAY.COL => COL);
ERASE.TO.EOL ();
@BOX 3.1
WHILE COL < CH.CNT DO
   IF LINE.VEC [COL] => CH < %20 THEN
      IF CH = "$P" THEN
         "p" => CH;
      ELSE
         IF CH /= "$L" THEN
            "c" => CH;
         ELSE
            %20 => CH;
         FI
      FI
   FI
   OUT.CH (CH);
   1 +> COL;
OD
@BOX 4.1
0 => DISPLAY.STATE;
MAX.COLS => DISPLAY.COL;
@BOX 5.1
END
@END
@TITLE EDT03.26(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
UPDATE AFTER INSERT (INSERT COUNT, TEMP LINE, TEMP.COL, DUMP BLOCK, DUMP PTR)
@BOX 2.0
CALCULATE NEW WINDOW POSITION
IF NECESSARY, AND UPDATE
[EDT03.5]
@BOX 3.0
END
@BOX 1.1
PROC UPDATE.AFTER.INSERT (INS.CNT, T.LINE, T.COL, DUMP.BLOCK, DUMP.PTR);
INTEGER COUNT;
@BOX 2.1
IF C.LINE = T.LINE THEN
   IF INS.CNT + CH.CNT OF SCREEN.LIST [C.LINE]
      =< MAX.COLS OR C.LINE = MAX.LINES - 1 THEN
      1 => COUNT;
   ELSE
      MAX.LINES - C.LINE => COUNT;
   FI
ELSE
   IF T.LINE < MAX.LINES THEN
      MAX.LINES - C.LINE => COUNT;
   ELSE
      1 => CLEAR.SCREEN.FLAG;
      0 => C.LINE => C.COL;
      STRT.OF.GAP => STRT.OF.WINDOW;
      IF GAP.PTR - T.COL => W.STRT.PTR < 0 THEN
         SYS14.PAGE.SIZE +> W.STRT.PTR;
         1 -> STRT.OF.WINDOW;
      FI
      STRT.OF.WINDOW => DUMP.BLOCK;
      W.STRT.PTR => DUMP.PTR;
      MAX.LINES => COUNT;
   FI
FI
UPDATE (DUMP.BLOCK, DUMP.PTR, C.LINE, C.COL, COUNT);
@BOX 3.1
END
@END
@TITLE EDT03.27(1,11)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
FAULT TRAP (TRAP NO, REASON)
@BOX 2.0
RELEASE SEGMENTS
RESTORE ORIGINAL TERMINAL STATE
@BOX 3.0
ENTER TRAP (TRAP NO, REASON)
@BOX 4.0
END
@BOX 1.1
PROC FAULT.TRAP(TRAP.NO,REASON);
INTEGER I;
CAPTION (%"I.SEG.NO ");OUT.I (I.SEG.NO, 12);NEW.LINES (1);
CAPTION (%"END.OF.BLKS ");OUT.I (END.OF.BLKS, 12);NEW.LINES (1);
CAPTION (%"DATA.PTR ");OUT.I (DATA.PTR, 12);NEW.LINES (1);
CAPTION (%"DATAPTR.END ");OUT.I (DATA.PTR.END, 12);NEW.LINES (1);
CAPTION (%"GAP.PTR ");OUT.I (GAP.PTR, 12);NEW.LINES (1);
CAPTION (%"STRT.OF.DATA ");OUT.I (STRT.OF.DATA, 12);NEW.LINES (1);
CAPTION (%"ETX.POS ");OUT.I (ETX.POS, 12);NEW.LINES (1);
CAPTION (%"GAP.PTR.STRT ");OUT.I (GAP.PTR.STRT, 12); NEW.LINES (1);
CAPTION (%"STRT.OF.GAP ");OUT.I (STRT.OF.GAP, 12); NEW.LINES (1);
@BOX 2.1
FOR I < 8 DO
   SET.TRAP (I, OLD.TRAP.PROC.ADDR [I]);
OD
LIB07.RELEASE.BUFFER.SEG(I.SEG.NO);
RELEASESEGMENT(BUF.SEG.NO);
RELEASESEGMENT(KILL.SEG.NO);
RELEASESEGMENT(NEW.SEG);
BREAKOUTPUT(0);
WAIT(0,2);
CHANGE.CHANNEL(PERI.SPN,1,OLD.P.MODE);
@BOX 3.1
STOP (0);
ENTER.TRAP (TRAP.NO,REASON);
@BOX 4.1
END
@END

