// Oedit.bcpl // Copyright Xerox Corporation 1979,1980 // Oedit was rewritten by Lyle Ramshaw in November/December, 1979, // to put in Trident drives other than drive #0 // Each file now has an optional <disk>: in front of the file // name, as in "TP3:name.ext" or "DP1:name.ext". Default // disk is DP0. // In addition, the new OEdit allows input in modes other than octal, // and a iterative find/replace command; check out the documentation // in the standard place, <altodocs>oedit.tty. // OEdit has the two files OEdit and OEditCom; one defs files for the // mode conventions, OEdit.D. In addition, the system needs UtilDP, // GP, Template, InterDisk, Trident file stuff, Diablo file stuff. get "streams.d" get "oedit.d" external [ //import from the OS Gets; Puts; dsp; keys; Wss; SetFilePos; Resets; Closes; Endofs; fpComCm CreateDisplayStream; ShowDisplayStream; TruncateDiskStream FileLength; Usc; Ws; CallSwat DoubleAdd; OpenFile; ReadBlock; MoveBlock InitializeZone; GetFixed; FixedLeft //import from GP SetupReadParam; ReadParam; AddItem //import from Template PutTemplate //import from UtilDP SetUpDP DoubleUsc; AssignDP; NegateDP; DoubleLShift; DoubleRShift zeroDP; oneDP; minusOneDP //import from InterDisk SetUpInterDisk InterDiskOpenFile OverwriteLoadRam //import from OEditCom ReadAndDoCommand ] external [ //export to OEditCom data; addr; lastVal; outstream dataFlag; writeFlag; standard; files; modes GetKeys; PutbackKeys; Display; DisplayValue WriteFile; PositionFile AsciiToEbcdic; EbcdicToAscii ] manifest [ diskZoneSize = 10000 //Should be enough for 5 files on 5 //different Tridents; what do you want? numInputFiles = 50 ] static [ modes ] static [ files; fLens; addr; data; firstName; lastVal = 0 ] static [ writeFlag=false; dataFlag; outstream; dispStream ] static [ dribbleFlag = false; dribbleFile ] static [ putbackInForce = false; putbackChar ] static [ standard = octal+halfOctal+halfAscii ] let Oedit(v, switches) be [ let staticDPwords = vec 6 SetUpDP(staticDPwords) modes = table [ 0; halfAscii; 0; halfAscii; decimal; halfEbcdic; 0; 0; halfOctal; 0; 0; 0; 0; 0; halfDecimal; octal; 0; 0; 0; halfAscii; 0; 0; 0; 0; halfHex; 0; 0 ] let zoneVec = vec diskZoneSize let zone = InitializeZone(zoneVec, diskZoneSize) SetUpInterDisk(zone) //Read the switches on the command name OEdit, which can reset the // standard display mode: let val = true for i = 1 to 999 do [ switchon switches!i into [ case $T: case $t: AnnounceNewTri() case $W: case $w: writeFlag = val; endcase case $O: case $o: SetStd(octal, val); endcase case $H: case $h: SetStd(halfOctal, val); endcase case $A: case $a: SetStd(halfAscii, val); endcase case $S: case $s: SetStd(halfAscii, val); endcase case $C: case $c: SetStd(halfAscii, val); endcase case $X: case $x: SetStd(halfHex, val); endcase case $E: case $e: SetStd(halfEbcdic, val); endcase case $D: case $d: SetStd(decimal, val); endcase case $N: case $n: SetStd(halfDecimal, val); endcase case $F: case $f: case $L: case $l: dribbleFlag = val; endcase case $-: val = not val; loop case 0: break; default: endcase ] val = true ] let name = vec 256; let sw=vec 128 SetupReadParam(name, sw) let firstNameVec = vec 256; firstName=firstNameVec Ws("This is OEdit of November 23, 1980.*N") //open the input files: let filesVec=vec numInputFiles; files=filesVec files!0=0 let fLensVec=vec 2*numInputFiles; fLens=fLensVec for cnt=1 to numInputFiles do [ let f=ReadParam("P", -1) if f eq -1 then break let acc=nil test (cnt eq 1)& writeFlag ifso acc=ksTypeReadWrite ifnot acc=ksTypeReadOnly if cnt eq 1 then MoveBlock(firstName, name, 256) f=InterDiskOpenFile(name, acc, wordItem) if f eq 0 then [ PutTemplate(dsp,"$S not found, ignored*N",name) loop ] AddItem(files, f) ] //now that all files are open, the LoadRam stuff can be // overlaid; we will steal the rest of core for display purposes OverwriteLoadRam() //first, try for the font Gacha10.al let fontFile = OpenFile("Gacha10.al",ksTypeReadOnly,wordItem) let font = nil if fontFile then [ let fontLen = vec 1 FileLength(fontFile, fontLen) let fontLenWords = (fontLen!1+1) rshift 1 font = GetFixed(fontLenWords) Resets(fontFile) ReadBlock(fontFile, font, fontLenWords) font = font+2 ] let dispSize = FixedLeft()-2000 let dispVec = GetFixed(dispSize) test fontFile ifso dispStream = CreateDisplayStream(#60, dispVec, dispSize, font) ifnot dispStream = CreateDisplayStream(#60, dispVec, dispSize) ShowDisplayStream(dispStream) //now, check if we should be dribbling //and construct the outstream accordingly let outstreamVec = vec lST; outstream = outstreamVec test dribbleFlag ifso [ dribbleFile = OpenFile("OEdit.lst", ksTypeReadWrite, charItem) outstream>>ST.puts = PutsOutstream outstream>>ST.reset = ResetsOutstream outstream>>ST.close = ClosesOutstream let commandLine = OpenFile("Com.Cm", ksTypeReadOnly, charItem, 0, fpComCm) if commandLine ne 0 then until Endofs(commandLine) do Puts(dribbleFile, Gets(commandLine)) ] ifnot outstream = dispStream // find lengths and print them PutTemplate(outstream,"*N*N Length (bytes) ") for i=1 to files!0 do [ let bytepos=vec 1 FileLength(files!i, bytepos) PutTemplate(outstream,"$9EO", bytepos) //Now to change the length from bytes to words, rounding up, and // store the word length in fLens DoubleAdd(bytepos, oneDP) DoubleRShift(lv fLens>>DPV.Elt↑i, bytepos, 1) ] PutTemplate(outstream,"*N Length (words) ") for i=1 to files!0 do PutTemplate(outstream,"$9EO", lv fLens>>DPV.Elt↑i) Puts(outstream,$*N) let addrVec = vec 1; addr=addrVec AssignDP(addr, zeroDP) let dataVec = vec 1; data=dataVec //now, go into the main command loop let fullPageDisplay=false fullPageDisplay = ReadAndDoCommand(fullPageDisplay) repeat ] and Display(modeWord) be [ Puts(outstream, $*N) PutTemplate(outstream,"$UEO", addr) LJust(outstream,addr,9) for i=1 to files!0 do test PositionFile(i, addr) ifnot PutTemplate(outstream, " overflow ") ifso [ lastVal=Gets(files!i) let left, right = lastVal<<left, lastVal<<right if (octal & modeWord) ne 0 then PutTemplate(outstream, "$8UO ",lastVal) if (halfOctal & modeWord) ne 0 then PutTemplate(outstream, "$3O $3O ", left, right) if (halfAscii & modeWord) ne 0 then PutTemplate(outstream, "$P $P ", ShowChar, left, ShowChar, right) if (halfHex & modeWord) ne 0 then PutTemplate(outstream, "$P $P ", ShowHex, left, ShowHex, right) if (halfEbcdic & modeWord) ne 0 then PutTemplate(outstream, "$P $P ", ShowEBCDIC, left, ShowEBCDIC, right) if (decimal & modeWord) ne 0 then PutTemplate(outstream, "$8D ", lastVal) if (halfDecimal & modeWord) ne 0 then PutTemplate(outstream, "$3D $3D ", left, right) ] Puts(outstream, $*S) ] and DisplayValue() be [ Puts(outstream, $*N) PutTemplate(outstream," $EUOb = $ED.", data, data) ] and SetStd(mask, sense) be test sense ifso standard = standard % mask ifnot standard = standard & (not mask) and WriteFile() be [ if files!0 ls 1 then //no file to write in! [ Wss(outstream, "?*NNo first file to write in!") return ] if writeFlag eq false then [ Wss(outstream, "*NOpen first file for writing [confirm with CR]") test GetKeys() eq $*N ifso [ Closes(files!1) let f=InterDiskOpenFile(firstName,ksTypeReadWrite,wordItem) if f eq 0 then [ Wss(dsp, "*NSorry, reopen not successful.") abort ] files!1=f writeFlag = true ] ifnot [ Wss(outstream, "?*nCancelling the write request!") return ] ] test PositionFile(1, addr) ifso Puts(files!1, data>>DP.Low) ifnot Wss(outstream," Overflow") ] // f is a fileVec index. // If p gr fLens>>DPV.Elt↑i (double-precision) resultis false and no // positioning is done. Otherwise resultis true and PositionFile(f, p)=valof [ // check for overflow if DoubleUsc(p, lv fLens>>DPV.Elt↑f) ge 0 then resultis false f=files!f let pBytes = vec 1 DoubleLShift(pBytes, p, 1) SetFilePos(f, pBytes) resultis true ] and ClosesOutstream(s) be [ Closes(dispStream) TruncateDiskStream(dribbleFile) Closes(dribbleFile) ] and PutsOutstream(s, c) be [ Puts(dispStream, c) Puts(dribbleFile, c) ] and ResetsOutstream(s) be Resets(dispStream) and LJust(s, dA, fL) be [ for i = 1 to fL-(dA!0? 5+LJHigh(dA!0), LJLow(dA!1)) do Puts(s,$*S) ] and LJLow(n) = (n𘚠) ne 0? 6, (n𑅰) ne 0? 5, (n᭘) ne 0? 4, (nʼ) ne 0? 3, (nF) ne 0? 2, 1 and LJHigh(n) = (n𢋠) ne 0? 6, (n蓐) ne 0? 5, (nൈ) ne 0? 4, (nŔ) ne 0? 3, (n") ne 0? 2, 1 and ShowChar(s, c) be PutTemplate(s, (c ge #177? " ", c>#37? "*S$C", "↑$C"), (c>#37? c, c+#100)) and ShowHex(s, c) be for i = 0 to 1 do [ let b = (c rshift 4) Puts(s, b<10? $0+b, ($A-10)+b); c = c lshift 4 ] and ShowEBCDIC(s, c) be Puts(s, EbcdicToAscii(c)) and EbcdicToAscii(c) = (c ls #100? $~, ( table [ $*S;$~;$~;$~;$~;$~;$~;$~; $~;$~;$\;$.;$<;$(;$+;$|; $&;$~;$~;$~;$~;$~;$~;$~; $~;$~;$!;$$;$**;$);$;;$↑; $-;$/;$~;$~;$~;$~;$~;$~; $~;$~;$~;$,;$%;$←;$>;$?; $~;$~;$~;$~;$~;$~;$~;$~; $~;$~;$:;$#;$@;$';$=;$"; $~;$a;$b;$c;$d;$e;$f;$g; $h;$i;$~;$~;$~;$~;$~;$~; $~;$j;$k;$l;$m;$n;$o;$p; $q;$r;$~;$~;$~;$~;$~;$~; $~;$~;$s;$t;$u;$v;$w;$x; $y;$z;$~;$~;$~;$~;$~;$~; $~;$~;$~;$~;$~;$~;$~;$~; $~;$~;$~;$~;$~;$~;$~;$~; $~;$A;$B;$C;$D;$E;$F;$G; $H;$I;$~;$~;$~;$~;$~;$~; $~;$J;$K;$L;$M;$N;$O;$P; $Q;$R;$~;$~;$~;$~;$~;$~; $~;$~;$S;$T;$U;$V;$W;$X; $Y;$Z;$~;$~;$~;$~;$~;$~; $0;$1;$2;$3;$4;$5;$6;$7; $8;$9;$~;$~;$~;$~;$~;$~ ] ) ! (c-#100) ) and AsciiToEbcdic(c) = valof [ if c eq $~ then resultis 0 for ind = #100 to #377 do if EbcdicToAscii(ind) eq c then resultis ind resultis 0 ] and GetKeys() = valof test putbackInForce ifso [ putbackInForce = false resultis putbackChar ] ifnot resultis Gets(keys) and PutbackKeys(char) be [ if putbackInForce then CallSwat("Attempt to putback with a putback in force.") putbackInForce = true putbackChar = char ] and AnnounceNewTri() be [ Ws("OEdit no longer allows the /T switch.*n") Ws("Instead, precede each file name by a drive specification*n") Ws(" of the form *"DPi:*" or *"TPi:*".*n") abort ]