Trailing-Edge
-
PDP-10 Archives
-
-
There are no other files named in the archive.
!
Copyright (c) 1977 by Pentti Kanerva
All rights reserved
;
!****** INITIALIZATION ******
*******************************;
FORWARD SUBROUTINE rename#File;
FORWARD SUBROUTINE restart;
SUBROUTINE copySOS (BOOLEAN retain);
! -------
Copy SOS file to new format and make DIR page.
RETAIN = FALSE to delete line numbers, TRUE to convert them
to normal text.
Changes SOS page marks to FF.
Assumptions:
(a) Lines do not cross file page boundaries,
(b) line format ok: [line#,@], TAB, line, CR, LF,
(c) page marks ok: [SP^5,@], [CR,CR,FF,0,0] (real SOS)
or [CR,FF,0,0,0] (DEC EDIT).
Keeps old file as old version.
Global args: EOFPAGE, EOFWC.
;
BEGIN "copySOS" INTEGER pg, nV, gp;
start#File; gp _ (-eofWC) LSH 18; ! To get up to EOF;
FOR pg _ eofPage downto 0 DO
BEGIN
outStr ("." & cvs(pg));
pMap (file(pg), fork(tBufMP), rd#);
pMap (#file(pg), fork(oBufMP), rd#+wr#);
START!CODE LABEL loop, put, bot, sosWd, getFF, don;
DEFINE wd# = "2", gp# = "3", pp# = "4",
nLF# = "5", nFF# = "6", pm1# = "7", pm2# = "'10",
pm2X# = "'11";
move pm1#, ['201004020100]; ! [SP,SP,SP,SP,SP] is the 1st
word of SOS page mark without
the extra bit (bit 35);
move pm2#, ['064321400000]; ! [CR,CR,FF,0,0] is the 2nd
word of SOS page mark;
move pm2X#, ['064300000000]; ! [CR,FF,0,0,0] - DEC version;
setzb nlf#, nff#;
move gp#, gp; ! Get pointer;
movei pp#, oBuf-1; ! Put (push) pointer. Its LH counts!;
loop: skipn wd#, tBuf(gp#);
jrst bot; ! Ignor 0-words;
trze wd#, 1; ! Line number? Clear SOS bit;
aoja nlf#, sosWd; ! Yes. Count lines;
put: push pp#, wd#; ! Put (push) the word;
bot: aobjn gp#, loop; ! Page finished?;
jrst don;
sosWd: aobjp gp#, don; ! To consume 2nd word;
camn pm1#, wd#; ! SOS page mark a'coming?;
jrst getFF;
! Must be a line no.;
skipe retain;
push pp#, wd#; ! Retain line no.s;
move wd#, tBuf(gp#);
skipn retain;
tlz wd#, '774000; ! Remove TAB of 2nd word;
jrst put;
getFF: came pm2#, tBuf(gp#);! 2nd word must be CR,CR,FF;
camn pm2X#, tBuf(gp#); ! or CR,FF if DEC file;
skipa ;
jrst loop; ! Invalid, treat as regular word;
movei wd#, FF LSH 1;
setz nlf#, ;
aoja nff#, put;
! Prepare dir entry in AC0;
don: dpb nff#, f.nFF;
dpb nlf#, f.nLF;
hlrz pp#, pp#; ! Word count to right half;
imuli pp#, 5; ! Words to bytes;
dpb pp#, f.nCh;
move 1, pg;
movem oDir(1); ! Enter in directory;
END
;
gp _ (-'1000) LSH 18; ! To get full page;
END ! of FOR;
;
! Set file lenght, byte size in FDB, unmap T/OBUFMP, (O)DIRMP,
rename #file to FILENAME, new version;
nV _ newVersion;
newVersion _ TRUE; fin#File (eofPage); rename#File;
newVersion _ nV;
! Start afresh;
restart;
END "copySOS"
;
BOOLEAN SUBROUTINE mapsLinks;
! ---------
TRUE iff maps LINKPAGE of file to LINKMP of fork.
Used in initialization of page-finished file and
inconsistent file.
;
IF NOT exists (linkPage) THEN RETURN (FALSE)
ELSE
BEGIN "mapsLinks"
pMap (file(linkPage), fork(linkMP),
rd# + (IF readOnly THEN copy# ELSE wr#));
RETURN (TRUE);
END "mapsLinks"
;
SUBROUTINE makeLinks;
! ---------
Initialize link page.
i LINKS [i]
----- ---------
0 ...e-1 1,,i+1
e 1,, -1 for E-O-F
e+1 0
e+2 0
e+3 0,, -1 for E-O-free list
e+4...t-1 0,,i-1
t -1
t+1...776 pointers
777 1 segment no.
where e is EOFPAGE, t is TEMPPAGE (=770)
;
BEGIN "makeLinks" INTEGER i;
unMap (fork(linkMP)); setBuf (links, '777777);
! Initialize text page chain;
IF (nText _ eofPage + 1) > 0
THEN BEGIN textP _ 0; links.(eofPage) _ '1777777 END
;
FOR i _ eofPage - 1 downto 0 DO links.(i) _ i + '1000001;
segment _ 1;
IF writeMode THEN
BEGIN
! Initialize free page chain, leave room for page 0 and one extra page;
freeP _ tempPage - 1; links.(eofPage + 3) _ '777777;
FOR i _ eofPage + 4 upto freeP DO links.(i) _ i - 1;
nFree _ tempPage - eofPage - 3;
nHold _ nSafe _ 0;
pMap (fork(linkMP), file(linkPage), rd#+wr#);
IFC tops20.sw THENC
pMap (file(linkPage), fork(linkMP), rd#+wr#);
ENDC
END
;
END "makeLinks"
;
SUBROUTINE getDir;
! ------
Pmap directory page if exists, o.w. create page directory.
If FDBUSW indicates new format (last 3 digits are '252),
get directory from top of EOFPAGE. (252 NOT IMPLEMENTED YET)
;
BEGIN "getDir" INTEGER pg;
IF readOnly THEN unMap (fork(dirMP))
ELSE pMap (file(dirPage), fork(dirMP), rd#+wr#)
;
IF exists (pg _ dirPage) ! Crash file?;
ORIF
( byteSize = 7 ! Finished text file?;
AND
( exists (pg _ oDirPage) ! Old TV?;
ORIF
((pg _ nDirPage) GEQ 0 ANDIF exists (pg)) ! New TV?;
)
)
THEN
BEGIN
pMap (file(pg), fork(tBufMP), rd#);
! Did we succeed in getting a directory page?;
IF pg > '770 AND tBuf.('777) = -1
THEN arrBlt (dir.(0), tBuf.(0), '1000)
ELSE
BEGIN "setB" INTEGER d0;
setBuf (dir, -1);
IF pg < '770
AND tBuf.('777) = FF5 = tBuf.(-1+(d0 _ '776-pg)) THEN
DO dir.(pg) _ tBuf.(d0+pg) ASH -1 UNTIL (dec(pg)) < 0
;
END "setB"
;
unMap (fork(tBufMP));
END
ELSE setBuf (dir, -1)
;
END "getDir"
;
BOOLEAN SUBROUTINE okToEdit;
! --------
Initial checking and preparations.
Maps or makes DIRectory and LINKS.
Assumes FILELENGTH, BYTESIZE to be set, but sets FILELENGTH
to number of 7-bit bytes if was 36-bit bytes.
Initializes FFFP, FUFP, CHRASHFILE, EOFPAGE, EOFBC, EOFWC,
BADEOF, DIR and LINK pages.
TRUE iff succeeds in initializing file for editing.
;
BEGIN "okToEdit"
START!CODE
! First Free File Page, First Used Page thereafter;
move 1, rdJfn;
FFFFP;
hrrem 1, fffp; ! Save no. of first free page;
FFUFP;
seto 1, ; ! -1 means: no used after the free one;
hrrem 1, fufp; ! Save first used;
END
;
! We believe in 7-bit bytes;
IF byteSize = 36 THEN fileLength _ 5*fileLength;
eofPage _ (foo _ fileLength + '4777) DIV '5000 - 1;
! EOFPAGE = -1 means file is empty;
eofWC _ ((eofBC _ foo MOD '5000 + 1) + 4) DIV 5;
badEOF _ sosFile _ FALSE;
IF NOT (crashFile _ 0 LEQ fufp LEQ linkPage) THEN
BEGIN "finished"
IF readonly THEN
BEGIN
IF fffp GEQ tempPage THEN
BEGIN
outStr ("
File too long for TV-Edit.
");
RETURN (FALSE);
END
;
END
ELSE
BEGIN "wrMode"
IF fffp > tempPage - 20 THEN
BEGIN
outstr ("
File is full. Cannot TV-Edit.
");
RETURN (FALSE);
END
;
! SOS file? (if eofpage < 0, pMap blows up, but can't be SOS);
IF eofpage geq 0 THEN
BEGIN "SOS"
pMap (file(0), fork(tBufMP), rd#);
! Does file start with SOS line no. or SOS page mark?;
sosFile _ (tBuf.(0) LAND 1 AND tBuf.(1) LSH -29 = TAB)
OR (tBuf.(0) = '201004020101
AND tBuf.(1) = '064321400000);
unMap (fork(tBufMP));
IF sosFile THEN
BEGIN
sosFate _ "D";
IF rushed ORIF wantsSOS (sosFate) THEN
BEGIN
copySOS (sosFate = "R"); RETURN (okToEdit);
END
ELSE RETURN (FALSE)
;
END
;
END "SOS"
;
END "wrMode"
;
getDir; makeLinks; ! MAKELINKS requires that EOFPAGE be set;
! Set eof-pointer (file might have been appended to);
IF eofPage GEQ 0 THEN
START!CODE DEFINE pg# = "2", de# = "3", nch# = "4";
LABEL loop, don;
move pg#, eofPage;
move de#, dir(pg#); ! Dir Entry;
move 0, de#;
ldb nch#, f.nCh;
camn nch#, eofBC; ! IF NCH NEQ EOFBC ..;
jrst don;
seto 0, ; ! .. THEN ..;
move 1, eofBC;
dpb 1, f.nCh;
movem 0, dir(pg#); ! .. DIR [EOFPAGE] _ [-1,-1,EOFBC];
aojn de#, don; ! Done if old Dir Entry was not -1;
! Undefine last dir entry that was previously defined. That's where
! the old EOF was. The file has been appended to and the old entry
! is no longer valid.
;
loop: sojl pg#, don;
move de#, dir(pg#);
aoje de#, loop; ! IF DIR.(PG) NEQ -1 ..;
setom dir(pg#); ! .. THEN undefine;
don:
END
;
IF writeMode THEN
BEGIN "warn"
! Save 5 FDB words in DIR in case he wants to keep old file;
oFdb11 _ fdb ['11]; oFdb12 _ fdb ['12];
oFdb13 _ fdb ['13]; oFdb14 _ fdb ['14]; oFdb24 _ fdb ['24];
! And original FFFP;
oFffp _ fffp;
! Want non-0 byte size in case of crash;
If (oFdb11 Land '007700000000) = 0 Then ! Byte size = 0?;
Start!code "set7"
move 1, rdJfn;
hrli 1, '11; ! 11,,jfn;
movsi 2, '007700; ! Byte size mask;
movsi 3, '000700; ! Size = 7;
CHFDB; ! Set byte size to 7 bits;
End "set7"
;
! Do dirPage first because existence of linkPage is used to
indicate a crash, and a crash requires a valid dirPage;
secure(dirPage);
secure(linkPage);
END "warn"
;
END "finished"
ELSE
BEGIN
! Page-finished file?;
IF mapsLinks ANDIF linksOk THEN getDir
ELSE
BEGIN
outStr ("
Inconsistent file. Cannot TV-Edit!
");
RETURN (FALSE);
END
;
END
;
RETURN (TRUE);
END "okToEdit"
;
FORWARD SUBROUTINE dMarkPage;
SUBROUTINE startCrash;
! ----------
Starting of edit after crash finish (CRASHFILE TRUE).
;
BEGIN "startCrash" BOOLEAN finCrash;
INTEGER nff, nlf, goNff, goNlf, goP, goL, seg, maxSeg, pg;
SUBROUTINE saveMax;
! -------;
BEGIN goNff _ nff; goNlf _ nlf; maxSeg _ seg END;
! + + + + ;
IF finCrash _ (writeMode AND nExtraFree LEQ 0) THEN warning ("
Will finish the edit of a full file.
CONTINUE, if ok.
");
nff _ nlf _ goNff _ goNlf _ maxSeg _ 0; pg _ textP0;
WHILE (pg _ rightOf (pg)) GEQ 0 DO
BEGIN
IF (seg _ rdSeg.(pg)) THEN BEGIN saveMax; DONE END;
addDirEntry (nff, nlf, pg);
IF (seg _ wrSeg.(pg)) GEQ maxSeg THEN saveMax;
END
;
goP _ goNff + 1; goL _ goNlf + 1;
segment _ (segment LAND '377) MAX 2;
IF finCrash THEN
BEGIN "finFul"
dpb (goP, p.page); dpb (goL, p.line);
filePlaces _ cvs(goP) & "." & cvs(goL);
segment _ 1; ! To no-op FINSEGMENT;
finish(false);
outstr ("
... FINISHED FULL FILE " & fileName
& (IF finNV THEN " [New version]
" ELSE "
"));
endOfEdit _ TRUE;
END "finFul"
ELSE
BEGIN
goToPlace (goP, goL, 1);
IF writeMode THEN
BEGIN
dMarkPage; dMarkPage;
dpyMessage (".CRASHED. OLDER.TEXT.IS.BELOW.THE.PAGE.MARKS");
END
ELSE dpyMessage (".CRASHED. FILE.MIGHT.NEED.CLEAN-UP");
;
END
;
END "startCrash"
;
COMMENT End of file "IOINIT";