home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
draco
/
draco-1.ark
/
HEDIT.DRC
< prev
next >
Wrap
Text File
|
1986-11-12
|
18KB
|
858 lines
#util.g
#crt.g
word BUFFSIZE = 1024;
ushort
FILECOL = 2,
ROCOL = 17,
POSCOL = 22,
HEXCOL = 29,
ERRORCOL = 34;
ushort NLines, NCols;
file(BUFFSIZE) Fyle;
channel input binary Chin;
channel output binary Chout;
channel output text CRTOut;
*char FileName;
word FilePos, WindowPos, EndPos;
ushort FilePosHigh, WindowPosHigh, EndPosHigh;
ushort CursorLine, CursorColHex, CursorColChar;
bool ReadOnly, Binary, HadError;
proc nonrec err(*char message)void:
CRT_Move(NLines - 1, ERRORCOL);
CRT_EnterHighLight();
write(CRTOut; message);
CRT_ExitHighLight();
HadError := true;
corp;
proc nonrec abort(*char message)void:
CRT_Move(NLines - 1, ERRORCOL);
CRT_EnterHighLight();
write(CRTOut; message, ' ', ioerror(Chin), ' ', ioerror(Chout));
CRT_ExitHighLight();
CRT_Scroll();
CRT_Abort();
corp;
proc nonrec endOfFile()void:
err("End of file");
corp;
proc nonrec startOfFile()void:
err("Beginning of file");
corp;
proc nonrec displayPos()void:
CRT_Move(NLines - 1, POSCOL);
write(CRTOut; FilePosHigh : x : -2, FilePos : x : -4);
corp;
proc nonrec displayStatus()void:
ushort i;
HadError := false;
CRT_ClearLine(NLines - 1);
for i from 0 upto NCols - 2 do
write(CRTOut; '-');
od;
CRT_Move(NLines - 1, FILECOL);
write(CRTOut; FileName);
if ReadOnly then
CRT_Move(NLines - 1, ROCOL);
write(CRTOut; "[RO]");
fi;
displayPos();
CRT_Move(NLines - 1, HEXCOL);
write(CRTOut; if Binary then "hex-" else "char" fi);
corp;
proc nonrec clearError()void:
ushort i;
if HadError then
HadError := false;
CRT_Move(NLines - 1, ERRORCOL);
for i from ERRORCOL + 2 upto NCols do
write(CRTOut; '-');
od;
fi;
corp;
proc nonrec getChar1()char:
char ch;
while
ch := CRT_GetChar();
ch = '\e'
do
od;
ch
corp;
proc nonrec getChar()char:
char ch;
ch := getChar1();
clearError();
ch
corp;
proc nonrec ASCIIPut(byte b)void:
write(CRTOut; if b + '\e' >= ' ' and b + '\e' <= '~' then
b + '\e'
else
'.'
fi);
corp;
proc nonrec seek(ushort posHigh; word pos)void:
if not SeekIn(Chin, posHigh, pos) then
abort("Seek failed");
fi;
corp;
proc nonrec unCursor()void:
byte b;
seek(FilePosHigh, FilePos);
read(Chin; b);
CRT_Move(CursorLine, CursorColHex);
write(CRTOut; b : x : -2);
CRT_Move(CursorLine, CursorColChar);
ASCIIPut(b);
corp;
proc nonrec putCursor()void:
byte b;
seek(FilePosHigh, FilePos);
read(Chin; b);
CRT_EnterHighLight();
CRT_Move(CursorLine, CursorColHex);
write(CRTOut; b : x : -2);
CRT_Move(CursorLine, CursorColChar);
ASCIIPut(b);
CRT_ExitHighLight();
corp;
proc nonrec displayScreen()void:
word pos;
ushort posHigh, l, c;
[16] byte buff;
CRT_Move(0, 0);
posHigh := WindowPosHigh;
pos := WindowPos;
l := 0;
seek(WindowPosHigh, WindowPos);
while read(Chin; buff[0]) and l ~= NLines - 1 do
l := l + 1;
write(CRTOut; posHigh : x : -2, pos : x : -4, ": ",
buff[0] : x : -2, ' ');
pos := pos + 1;
for c from 1 upto 15 do
read(Chin; buff[c]);
write(CRTOut; buff[c] : x : -2, ' ');
pos := pos + 1;
od;
pos := pos - 16;
write(CRTOut; " *");
for c from 0 upto 15 do
ASCIIPut(buff[c]);
pos := pos + 1;
od;
if pos = 0x0000 then
posHigh := posHigh + 1;
fi;
write (CRTOut; "*\r\n");
od;
pretend(ioerror(Chin), void);
while l ~= NLines - 1 do
CRT_ClearLine(l);
l := l + 1;
od;
putCursor();
corp;
proc nonrec scroll()void:
word pos;
ushort posHigh, c;
[16] byte buff;
pos := WindowPos + make(NLines - 1, word) * 16;
posHigh :=
if pos < WindowPos then WindowPosHigh + 1 else WindowPosHigh fi;
if EndPosHigh > posHigh or EndPosHigh = posHigh and EndPos > pos then
CRT_ClearLine(NLines - 1);
seek(posHigh, pos);
write(CRTOut; posHigh : x : -2, pos : x : -4, ": ");
for c from 0 upto 15 do
read(Chin; buff[c]);
write(CRTOut; buff[c] : x : -2, ' ');
od;
write(CRTOut; " *");
for c from 0 upto 15 do
ASCIIPut(buff[c]);
od;
write(CRTOut; "*\r\n");
WindowPos := WindowPos + 16;
if WindowPos = 0x0000 then
WindowPosHigh := WindowPosHigh + 1;
fi;
if CursorLine = 0 then
FilePos := FilePos + 16;
if FilePos = 0x0000 then
FilePosHigh := FilePosHigh + 1;
fi;
putCursor();
else
CursorLine := CursorLine - 1;
fi;
displayStatus();
else
endOfFile();
fi;
corp;
proc nonrec cursorForward()void:
if FilePos & 0x000f = 0x000f and CursorLine = NLines - 2 then
scroll();
fi;
if FilePosHigh ~= EndPosHigh or FilePos ~= EndPos - 1 then
unCursor();
if FilePos = 0xffff then
FilePos := 0;
FilePosHigh := FilePosHigh + 1;
else
FilePos := FilePos + 1;
fi;
if FilePos & 0x000f = 0x0000 then
CursorLine := CursorLine + 1;
CursorColHex := 9;
CursorColChar := 59;
else
CursorColHex := CursorColHex + 3;
CursorColChar := CursorColChar + 1;
fi;
putCursor();
displayPos();
else
endOfFile();
fi;
corp;
proc nonrec cursorBackward()void:
if FilePos ~= 0 or FilePosHigh ~= 0 then
unCursor();
if FilePos = 0 then
FilePos := 0xffff;
FilePosHigh := FilePosHigh - 1;
else
FilePos := FilePos - 1;
fi;
if FilePos & 0x000f = 0x000f then
CursorColHex := 9 + 30 + 15;
CursorColChar := 59 + 15;
if CursorLine = 0 then
if WindowPos = 0 then
WindowPos := 0xfff0;
WindowPosHigh := WindowPosHigh - 1;
else
WindowPos := WindowPos - 16;
fi;
CRT_ClearScreen();
displayScreen();
displayStatus();
else
CursorLine := CursorLine - 1;
fi;
else
CursorColHex := CursorColHex - 3;
CursorColChar := CursorColChar - 1;
fi;
putCursor();
displayPos();
else
startOfFile();
fi;
corp;
proc nonrec cursorUp()void:
if FilePosHigh ~= 0 or FilePos >= 16 then
unCursor();
if FilePos <= 0x000f then
FilePosHigh := FilePosHigh - 1;
fi;
FilePos := FilePos - 16;
if CursorLine = 0 then
if WindowPos = 0 then
WindowPos := 0xfff0;
WindowPosHigh := WindowPosHigh - 1;
else
WindowPos := WindowPos - 16;
fi;
CRT_ClearScreen();
displayScreen();
displayStatus();
else
CursorLine := CursorLine - 1;
fi;
putCursor();
displayPos();
else
startOfFile();
fi;
corp;
proc nonrec cursorDown()void:
if CursorLine = NLines - 2 then
scroll();
fi;
if FilePosHigh ~= EndPosHigh or FilePos < EndPos - 16 then
unCursor();
FilePos := FilePos + 16;
if FilePos <= 0x000f then
FilePosHigh := FilePosHigh + 1;
fi;
CursorLine := CursorLine + 1;
putCursor();
displayPos();
else
endOfFile();
fi;
corp;
proc nonrec cursorHome()void:
bool redraw;
unCursor();
redraw := WindowPosHigh ~= 0 or WindowPos ~= 0;
FilePosHigh := 0;
FilePos := 0;
WindowPosHigh := 0;
WindowPos := 0;
CursorLine := 0;
CursorColHex := 9;
CursorColChar := 59;
if redraw then
CRT_ClearScreen();
displayScreen();
displayStatus();
putCursor();
else
putCursor();
displayPos();
fi;
corp;
proc nonrec pageForward()void:
word pos, old;
ushort posHigh;
pos := WindowPos + make(NLines - 3, word) * 16;
posHigh :=
if pos < WindowPos then WindowPosHigh + 1 else WindowPosHigh fi;
if EndPosHigh > posHigh or EndPosHigh = posHigh and EndPos > pos then
WindowPos := pos;
WindowPosHigh := posHigh;
old := FilePos;
FilePos := FilePos + make(NLines - 3, word) * 16;
if FilePos < old then
FilePosHigh := FilePosHigh + 1;
fi;
if FilePosHigh > EndPosHigh or
FilePosHigh = EndPosHigh and FilePos >= EndPos then
CursorLine := (EndPos - WindowPos) / 16 - 1;
CursorColHex := 9 + 30 + 15;
CursorColChar := 59 + 15;
FilePosHigh := EndPosHigh;
FilePos := EndPos - 1;
fi;
CRT_ClearScreen();
displayScreen();
displayStatus();
else
endOfFile();
fi;
corp;
proc nonrec pageBackward()void:
word old;
if WindowPosHigh ~= 0 or WindowPos ~= 0 then
if WindowPosHigh ~= 0 or WindowPos >= make(NLines - 1,word) * 16 then
old := WindowPos;
WindowPos := WindowPos - make(NLines - 3, word) * 16;
if WindowPos > old then
WindowPosHigh := WindowPosHigh - 1;
fi;
old := FilePos;
FilePos := FilePos - make(NLines - 3, word) * 16;
if FilePos > old then
FilePosHigh := FilePosHigh - 1;
fi;
else
FilePos := FilePos - WindowPos;
FilePosHigh := 0;
WindowPos := 0;
WindowPosHigh := 0;
fi;
CRT_ClearScreen();
displayScreen();
displayStatus();
else
startOfFile();
fi;
corp;
proc nonrec getHex()byte:
char ch;
while
ch := getChar1();
not (ch >= '0' and ch <= '9' or
ch >= 'a' and ch <= 'f' or
ch >= 'A' and ch <= 'F' or
ch = '\r' or ch = '\b')
do
od;
if ch >= 'A' and ch <= 'F' then
ch - 'A' + 10
elif ch >= 'a' and ch <= 'f' then
ch - 'a' + 10
elif ch = '\r' then
255
elif ch = '\b' then
254
else
ch - '0'
fi
corp;
proc nonrec gotoDisplay(ushort posHigh; word pos; bool redraw)void:
if not redraw then
unCursor();
CursorLine := CursorLine + (pos / 16 - FilePos / 16);
fi;
FilePosHigh := posHigh;
FilePos := pos;
CursorColHex := (FilePos & 0x000f) * 3 + 9;
CursorColChar := (FilePos & 0x000f) + 59;
if redraw then
CRT_ClearScreen();
CursorLine := 0;
displayScreen();
displayStatus();
else
displayPos();
fi;
putCursor();
corp;
proc nonrec goto()void:
word pos, endPos;
byte b;
ushort posHigh, endPosHigh, p, q;
[6] byte buff;
err("Enter location to go to");
CRT_Move(NLines - 1, POSCOL);
write(CRTOut; " ");
CRT_Move(NLines - 1, POSCOL);
p := 0;
while
while
b := getHex();
b = 0 and p = 0
do
od;
b ~= 255
do
if b = 254 then
if p ~= 0 then
p := p - 1;
write(CRTOut; "\b \b");
fi;
elif p = 6 then
write(CRTOut; '\(0x07)');
else
write(CRTOut; if b < 10 then b + '0' else b - 10 + 'a' fi);
buff[p] := b;
p := p + 1;
fi;
od;
if p = 0 then
clearError();
err("OK - no goto done");
displayPos();
else
q := 6;
while p ~= 0 do
p := p - 1;
q := q - 1;
buff[q] := buff[p];
od;
while q ~= 0 do
q := q - 1;
buff[q] := 0;
od;
posHigh := buff[0] << 4 + buff[1];
pos := (make(buff[2], word) << 12) +
(make(buff[3], word) << 8) +
(make(buff[4], word) << 4) +
make(buff[5], word);
if posHigh = FilePosHigh and pos = FilePos then
;
elif posHigh < FilePosHigh or
posHigh = FilePosHigh and pos < FilePos then
if posHigh < WindowPosHigh or
posHigh = WindowPosHigh and pos < WindowPos then
WindowPosHigh := posHigh;
WindowPos := pos & 0xfff0;
gotoDisplay(posHigh, pos, true);
else
gotoDisplay(posHigh, pos, false);
fi;
else
if posHigh > EndPosHigh or
posHigh = EndPosHigh and pos >= EndPos then
endOfFile();
posHigh := EndPosHigh;
pos := EndPos - 1;
fi;
endPos := WindowPos + make(NLines - 1, word) * 16;
endPosHigh :=
if endPos < WindowPos then
WindowPosHigh + 1
else
WindowPosHigh
fi;
if posHigh > endPosHigh or
posHigh = endPosHigh and pos >= endPos then
WindowPosHigh := posHigh;
WindowPos := pos & 0xfff0;
gotoDisplay(posHigh, pos, true);
else
gotoDisplay(posHigh, pos, false);
fi;
fi;
clearError();
fi;
corp;
proc nonrec toDec()void:
word num;
ushort p;
byte b;
err("Enter hex value to convert");
CRT_Move(NLines - 1, POSCOL);
write(CRTOut; "- -");
CRT_Move(NLines - 1, POSCOL + 1);
num := 0;
p := 0;
while
while
b := getHex();
b = 0 and p = 0
do
od;
b ~= 255
do
if b = 254 then
if p ~= 0 then
num := num >> 4;
p := p - 1;
write(CRTOut; "\b \b");
fi;
elif p = 4 then
write(CRTOut; '\(0x07)');
else
write(CRTOut; if b < 10 then b + '0' else b - 10 + 'a' fi);
num := (num << 4) + b;
p := p + 1;
fi;
od;
clearError();
if p ~= 0 then
err("Decimal value is ");
CRT_Move(NLines - 1, ERRORCOL + 17);
CRT_EnterHighLight();
write(CRTOut; num : u);
CRT_ExitHighLight();
fi;
displayPos();
corp;
proc nonrec toHex()void:
word num;
ushort p;
char ch;
err("Enter decimal value to convert");
CRT_Move(NLines - 1, POSCOL);
write(CRTOut; " -");
CRT_Move(NLines - 1, POSCOL);
num := 0;
p := 0;
while
while
while
ch := getChar1();
not (ch >= '0' and ch <= '9' or
ch = '\r' or ch = '\b')
do
od;
ch = '0' and p = 0
do
od;
ch ~= '\r'
do
if ch = '\b' then
if p ~= 0 then
num := num / 10;
p := p - 1;
write(CRTOut; "\b \b");
fi;
elif p = 5 then
write(CRTOut; '\(0x07)');
else
write(CRTOut; ch);
num := (num * 10) + (ch - '0');
p := p + 1;
fi;
od;
clearError();
if p ~= 0 then
err("Hex value is ");
CRT_Move(NLines - 1, ERRORCOL + 13);
CRT_EnterHighLight();
write(CRTOut; num : x : -4);
CRT_ExitHighLight();
fi;
displayPos();
corp;
proc nonrec helpScreen()void:
CRT_ClearScreen();
write(CRTOut;
"\n"
"\n"
"\n"
"\n"
"\t\tCommands are:\r\n"
"\n"
"\tESC - exit\r\n"
"\tarrow keys - move cursor\r\n"
"\tHOME - move to beginning of file\r\n"
"\tRETURN - scroll screen\r\n"
"\tCNTL-Q - page forward\r\n"
"\tCNTL-S - page backward\r\n"
"\tCNTL-G - go to specific location\r\n"
"\tCNTL-T - toggle hex/char mode\r\n"
"\tCNTL-R - redraw screen\r\n"
"\tCNTL-X - convert decimal value to hex\r\n"
"\tCNTL-D - convert hex value to decimal\r\n"
"\tnon-control - replace char when not Read-Only"
);
CRT_Continue();
CRT_ClearScreen();
displayScreen();
displayStatus();
corp;
proc nonrec writeByte(byte b)void:
if not SeekOut(Chout, FilePosHigh, FilePos) then
abort("Write seek failed");
fi;
write(Chout; b);
cursorForward();
corp;
proc nonrec edit()void:
byte b, b2;
char cmd;
EndPos := GetInMax(Chin, &EndPosHigh);
displayScreen();
while
CRT_Move(CursorLine,
if Binary then CursorColHex else CursorColChar fi);
cmd := getChar();
cmd ~= '\(0x1b)'
do
case cmd
incase '\(0x06)':
cursorForward();
incase '\(0x15)':
incase '\(0x08)':
cursorBackward();
incase '\(0x1a)':
cursorUp();
incase '\(0x0a)':
cursorDown();
incase '\(0x01)':
cursorHome();
incase '\(0x0d)':
scroll();
incase '\(0x11)':
pageForward();
incase '\(0x13)':
pageBackward();
incase '\(0x07)':
goto();
incase '\(0x12)':
CRT_Reset();
CRT_ClearScreen();
displayScreen();
displayStatus();
incase '\(0x14)':
CRT_Move(NLines - 1, HEXCOL);
if Binary then
Binary := false;
write(CRTOut; "char");
else
Binary := true;
write(CRTOut; "hex-");
fi;
incase '\(0x04)':
toDec();
incase '\(0x18)':
toHex();
incase '\(0x1c)':
helpScreen();
default:
if cmd >= ' ' and cmd <= '~' then
if ReadOnly then
err("Modifications not allowed");
elif Binary then
if cmd >= '0' and cmd <= '9' or
cmd >= 'a' and cmd <= 'f' or
cmd >= 'A' and cmd <= 'F' then
b :=
if cmd >= '0' and cmd <= '9' then
cmd - '0'
elif cmd >= 'a' and cmd <= 'f' then
cmd - 'a' + 10
else
cmd - 'A' + 10
fi;
CRT_EnterHighLight();
write(CRTOut;
if b >= 10 then b - 10 + 'a' else b + '0' fi);
CRT_ExitHighLight();
b2 := getHex();
if b2 = 255 then
writeByte(b);
elif b2 = 254 then
putCursor();
else
writeByte(b << 4 + b2);
fi;
else
err("Bad hexadecimal digit");
fi;
else
write(CRTOut; cmd);
CRT_Move(CursorLine, CursorColHex);
write(CRTOut; cmd - '\e' : x : -2);
writeByte(cmd - '\e');
fi;
else
err("Invalid; CNTL-\\ for help");
fi;
esac;
od;
if not ReadOnly then
close(Chout);
fi;
close(Chin);
corp;
proc nonrec badUse()void:
writeln("Use is: hedit [-w] file1.typ ... filen.typ");
exit(1);
corp;
proc nonrec main()void:
*char par;
ReadOnly := true;
Binary := true;
par := GetPar();
if par ~= nil and par* = '-' then
while
par := par + 1;
par* ~= '\e'
do
case par*
incase 'W':
ReadOnly := false;
default:
badUse();
esac;
od;
par := GetPar();
fi;
if par = nil then
badUse();
fi;
CRT_AbortDisable();
NLines := CRT_NLines();
NCols := CRT_NCols();
open(CRTOut, CRT_PutChar);
while par ~= nil do
FilePosHigh := 0;
WindowPosHigh := 0;
FilePos := 0;
WindowPos := 0;
CursorLine := 0;
CursorColHex := 9;
CursorColChar := 59;
CRT_ClearScreen();
FileName := par;
if open(Chin, Fyle, FileName) then
displayStatus();
if not ReadOnly then
ReOpen(Chin, Chout);
fi;
if not SeekIn(Chin, 0, 0) then
err("File is empty - press a key");
pretend(getChar(), void);
else
edit();
fi;
else
displayStatus();
err("File doesn't exist - press a key");
pretend(getChar(), void);
fi;
par := GetPar();
od;
CRT_Abort();
corp;