mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 00:44:23 +00:00
780 lines
21 KiB
Plaintext
780 lines
21 KiB
Plaintext
$title ('Help Utility Version 1.1')
|
|
help:
|
|
do;
|
|
|
|
/* [JCE] Cut-down version of help that only does [C]reate */
|
|
|
|
/*
|
|
Copyright (C) 1982
|
|
Digital Research
|
|
P.O. 579
|
|
Pacific Grove, CA 93950
|
|
|
|
Revised:
|
|
06 Dec 82 by Bruce Skidmore
|
|
*/
|
|
|
|
declare plm label public;
|
|
|
|
/**********************************************
|
|
Interface Procedures
|
|
**********************************************/
|
|
mon1:
|
|
procedure (func,info) external;
|
|
declare func byte;
|
|
declare info address;
|
|
end mon1;
|
|
|
|
mon2:
|
|
procedure (func,info) byte external;
|
|
declare func byte;
|
|
declare info address;
|
|
end mon2;
|
|
|
|
mon3:
|
|
procedure (func,info) address external;
|
|
declare func byte;
|
|
declare info address;
|
|
end mon3;
|
|
|
|
/**********************************************
|
|
Global Variables
|
|
**********************************************/
|
|
|
|
declare (list$mode,nopage$mode,create$mode,extract$mode,page$mode) byte;
|
|
declare (offset,eod) byte;
|
|
|
|
declare cmdrv (1) byte external; /* [JCE] Help patch 2 */
|
|
declare fcb (13) byte external;
|
|
declare fcb2 (36) byte;
|
|
|
|
declare maxb address external;
|
|
declare fcb16 (1) byte external;
|
|
declare tbuff (128) byte external;
|
|
|
|
declare control$z literally '1AH';
|
|
declare cr literally '0DH';
|
|
declare lf literally '0AH';
|
|
declare tab literally '09H';
|
|
declare slash literally '''/''';
|
|
declare true literally '0FFH';
|
|
declare false literally '00H';
|
|
|
|
declare (cnt,index) byte;
|
|
declare sub(12) byte;
|
|
declare com(11) structure(
|
|
name(15) byte);
|
|
|
|
declare sysbuff(8) structure(
|
|
subject(12) byte,
|
|
record address,
|
|
rec$offset byte,
|
|
level byte) at (.memory);
|
|
|
|
declare name(12) byte;
|
|
declare level byte;
|
|
declare gindex address;
|
|
declare tcnt byte;
|
|
declare version address;
|
|
|
|
/**************************************
|
|
* *
|
|
* B D O S Externals *
|
|
* *
|
|
**************************************/
|
|
|
|
read$console:
|
|
procedure byte;
|
|
return mon2 (1,0);
|
|
end read$console;
|
|
|
|
write$console:
|
|
procedure (char);
|
|
declare char byte;
|
|
call mon1 (2,char);
|
|
end write$console;
|
|
|
|
print$console$buf:
|
|
procedure (buff$adr);
|
|
declare buff$adr address;
|
|
call mon1 (9,buff$adr);
|
|
end print$console$buf;
|
|
|
|
read$console$buff:
|
|
procedure (buff$adr);
|
|
declare buff$adr address;
|
|
call mon1(10,buff$adr);
|
|
end read$console$buff;
|
|
|
|
direct$con$io:
|
|
procedure(func) byte;
|
|
declare func byte;
|
|
return mon2(6,func);
|
|
end direct$con$io;
|
|
|
|
get$version:
|
|
procedure address;
|
|
return mon3(12,0);
|
|
end get$version;
|
|
|
|
delete$file:
|
|
procedure (fcb$address);
|
|
declare fcb$address address;
|
|
call mon1(19,fcb$address);
|
|
end delete$file;
|
|
|
|
open$file:
|
|
procedure (fcb$address) byte;
|
|
declare fcb$address address;
|
|
declare fcb based fcb$address (1) byte;
|
|
fcb(12) = 0; /* EX = 0 */
|
|
fcb(32) = 0; /* CR = 0 */
|
|
return mon2 (15,fcb$address);
|
|
end open$file;
|
|
|
|
close$file:
|
|
procedure (fcb$address) byte;
|
|
declare fcb$address address;
|
|
return mon2 (16,fcb$address);
|
|
end close$file;
|
|
|
|
read$record:
|
|
procedure (fcb$address) byte;
|
|
declare fcb$address address;
|
|
return mon2 (20,fcb$address);
|
|
end read$record;
|
|
|
|
write$record:
|
|
procedure (fcb$address) byte;
|
|
declare fcb$address address;
|
|
return mon2(21,fcb$address);
|
|
end write$record;
|
|
|
|
make$file:
|
|
procedure (fcb$address) byte;
|
|
declare fcb$address address;
|
|
declare fcb based fcb$address (1) byte;
|
|
fcb(12) = 0; /* EX = 0 */
|
|
fcb(32) = 0; /* CR = 0 */
|
|
return mon2(22,fcb$address);
|
|
end make$file;
|
|
|
|
read$rand:
|
|
procedure (fcb$address) byte;
|
|
declare fcb$address address;
|
|
return mon2(33,fcb$address);
|
|
end read$rand;
|
|
|
|
set$dma:
|
|
procedure (dma$address);
|
|
declare dma$address address;
|
|
call mon1(26,dma$address);
|
|
end set$dma;
|
|
|
|
set$rand$rec:
|
|
procedure (fcb$address);
|
|
declare fcb$address address;
|
|
call mon1(36,fcb$address);
|
|
end set$rand$rec;
|
|
|
|
terminate:
|
|
procedure;
|
|
call mon1 (0,0);
|
|
end terminate;
|
|
|
|
/*********************************************
|
|
Error Procedure
|
|
|
|
Displays error messages and
|
|
terminates if required.
|
|
*********************************************/
|
|
error:
|
|
procedure(term$code,err$msg$adr);
|
|
declare term$code byte;
|
|
declare err$msg$adr address;
|
|
|
|
call print$console$buf(.(cr,lf,'ERROR: $'));
|
|
call print$console$buf(err$msg$adr);
|
|
call print$console$buf(.(cr,lf,'$'));
|
|
if term$code then
|
|
call terminate;
|
|
end error;
|
|
|
|
/*********************************************
|
|
Move Procedure
|
|
|
|
Moves specified number of bytes
|
|
from the Source address to the
|
|
Destination address.
|
|
*********************************************/
|
|
movef:
|
|
procedure (mvcnt,source$addr,dest$addr);
|
|
declare (source$addr,dest$addr) address;
|
|
declare mvcnt byte;
|
|
call move(mvcnt,source$addr,dest$addr);
|
|
return;
|
|
end movef;
|
|
|
|
/*********************************************
|
|
Compare Function
|
|
|
|
Compares 12 byte strings
|
|
|
|
Results: 0 - string1 = string2
|
|
1 - string1 < string2
|
|
2 - string1 > string2
|
|
*********************************************/
|
|
compare:
|
|
procedure(str1$addr,str2$addr) byte;
|
|
declare (str1$addr,str2$addr) address;
|
|
declare string1 based str1$addr (12) byte;
|
|
declare string2 based str2$addr (12) byte;
|
|
declare (result,i) byte;
|
|
result,
|
|
i = 0;
|
|
do while ((i < 12) and (string1(i) <> ' '));
|
|
if string1(i) <> string2(i) then
|
|
do;
|
|
if string1(i) < string2(i) then
|
|
do;
|
|
result = 1;
|
|
end;
|
|
else
|
|
do;
|
|
result = 2;
|
|
end;
|
|
i = 11;
|
|
end;
|
|
i = i + 1;
|
|
end;
|
|
return result;
|
|
end compare;
|
|
|
|
/*********************************************
|
|
Increment Procedure
|
|
|
|
Increments through a record.
|
|
*********************************************/
|
|
inc:
|
|
procedure (inci) byte;
|
|
declare inci byte;
|
|
inci = inci + 1;
|
|
if inci > 127 then
|
|
do;
|
|
if read$record(.fcb) = 0 then
|
|
do;
|
|
inci = 0;
|
|
end;
|
|
else
|
|
do;
|
|
eod = true;
|
|
inci = 0;
|
|
end;
|
|
end;
|
|
return inci;
|
|
end inc;
|
|
|
|
/*******************************************
|
|
Init Procedure
|
|
|
|
Reads the index into memory
|
|
*******************************************/
|
|
init:
|
|
procedure;
|
|
declare (buf$size,max$buf,init$i) address;
|
|
declare end$index byte;
|
|
buf$size = maxb - .memory;
|
|
max$buf = buf$size;
|
|
end$index = 0;
|
|
init$i = 7;
|
|
do while (not end$index) and (max$buf > 127);
|
|
call set$dma(.sysbuff(init$i-7).subject);
|
|
if read$record(.fcb) <> 0 then
|
|
do;
|
|
init$i = close$file(.fcb);
|
|
call error(true,.('Reading HELP.HLP index.$'));
|
|
end;
|
|
if sysbuff(init$i).subject(0) = '$' then end$index = true;
|
|
if not end$index then
|
|
do;
|
|
max$buf = max$buf - 128;
|
|
init$i = init$i + 8;
|
|
end;
|
|
end;
|
|
call set$dma(.tbuff);
|
|
if (max$buf < 128) and (not end$index) then
|
|
do;
|
|
init$i = close$file(.fcb);
|
|
call error(true,.('Too many entries in Index Table.',
|
|
' Not enough memory.$'));
|
|
end;
|
|
end init;
|
|
|
|
|
|
/*******************************************
|
|
Parse Procedure
|
|
|
|
Parses the command tail
|
|
*******************************************/
|
|
parse:
|
|
procedure byte;
|
|
declare (index,begin,cnt,i,stop,bracket) byte;
|
|
index = 0;
|
|
if tbuff(0) <> 0 then
|
|
do;
|
|
do index = 1 to tbuff(0);
|
|
if tbuff(index) = tab then tbuff(index) = ' ';
|
|
else if tbuff(index) = ',' then tbuff(index) = ' ';
|
|
end;
|
|
index = 1;
|
|
do while(index < tbuff(0)) and (tbuff(index) = ' ');
|
|
index = index + 1;
|
|
end;
|
|
if tbuff(index) = '.' then
|
|
do;
|
|
begin = level;
|
|
tbuff(index) = ' ';
|
|
end;
|
|
else
|
|
begin = 0;
|
|
do index = begin to 10;
|
|
call movef(15,.(' ',cr,'$'),.com(index).name);
|
|
end;
|
|
index = begin;
|
|
cnt = 1;
|
|
stop,
|
|
bracket = 0;
|
|
do while (tbuff(cnt) <> 0) and (not stop);
|
|
if (tbuff(cnt) <> 20H) then
|
|
do;
|
|
i = 0;
|
|
do while (((tbuff(cnt) <> 20H) and (tbuff(cnt) <> '[')) and
|
|
(tbuff(cnt) <> 0)) and ((i < 12) and (index < 11));
|
|
if (tbuff(cnt) > 60H) and (tbuff(cnt) < 7BH) then
|
|
do;
|
|
com(index).name(i) = tbuff(cnt) - 20H;
|
|
end;
|
|
else
|
|
do;
|
|
com(index).name(i) = tbuff(cnt);
|
|
end;
|
|
cnt = cnt + 1;
|
|
i = i + 1;
|
|
end;
|
|
index = index + 1;
|
|
if (bracket or (index > 10)) then
|
|
do;
|
|
stop = true;
|
|
end;
|
|
else
|
|
if tbuff(cnt) = '[' then
|
|
do;
|
|
if com(index-1).name(0) = ' ' then index = index - 1;
|
|
com(index).name(0) = '[';
|
|
cnt = cnt + 1;
|
|
index = index + 1;
|
|
bracket = true;
|
|
end;
|
|
end;
|
|
else
|
|
do;
|
|
cnt = cnt + 1;
|
|
end;
|
|
end;
|
|
end;
|
|
list$mode,
|
|
nopage$mode,
|
|
create$mode,
|
|
extract$mode = false;
|
|
if index > 0 then
|
|
do;
|
|
i = 0;
|
|
do while (i < 10);
|
|
if com(i).name(0) = '[' then
|
|
do;
|
|
if (com(i+1).name(0) = 'C') then
|
|
do;
|
|
create$mode = true;
|
|
index = index - 2;
|
|
end;
|
|
else if (com(i+1).name(0) = 'E') then
|
|
do;
|
|
extract$mode = true;
|
|
index = index - 2;
|
|
end;
|
|
else if (com(i+1).name(0) = 'N') then
|
|
do;
|
|
nopage$mode =true;
|
|
index = index - 2;
|
|
end;
|
|
else if (com(i+1).name(0) = 'L') then
|
|
do;
|
|
list$mode = true;
|
|
nopage$mode = true;
|
|
index = index - 2;
|
|
end;
|
|
else if (com(i+1).name(0) <> ' ') then
|
|
do;
|
|
index = index - 2;
|
|
end;
|
|
else
|
|
do;
|
|
index = index - 1;
|
|
end;
|
|
i = 10;
|
|
end;
|
|
i = i + 1;
|
|
end;
|
|
end;
|
|
return index;
|
|
end parse;
|
|
|
|
/******************************************
|
|
Create$index Procedure
|
|
|
|
Creates HELP.HLP from HELP.DAT
|
|
******************************************/
|
|
create$index:
|
|
procedure;
|
|
declare (cnt, i, rec$cnt) byte;
|
|
declare (index,count,count2,max$buf,save$size) address;
|
|
declare fcb3(36) byte;
|
|
call print$console$buf(.(cr,lf,'Creating HELP.HLP....$'));
|
|
do i = 0 to 7;
|
|
call movef(12,.('$ '),.sysbuff(i).subject);
|
|
end;
|
|
rec$cnt,
|
|
index = 0;
|
|
save$size = maxb - .memory;
|
|
max$buf = save$size;
|
|
call movef(13,.(0,'HELP DAT',0),.fcb);
|
|
if open$file(.fcb) = 0FFH then
|
|
do;
|
|
call error(true,.('HELP.DAT not on current drive.$'));
|
|
end;
|
|
eod = 0;
|
|
do while (not eod) and (read$record(.fcb) = 0);
|
|
i = 0;
|
|
do while(i < 128) and (not eod);
|
|
if tbuff(i) = control$z then
|
|
do;
|
|
eod = true;
|
|
end;
|
|
else
|
|
do;
|
|
if tbuff(i) = slash then
|
|
do;
|
|
cnt = 0;
|
|
do while(not eod) and (tbuff(i) = slash);
|
|
i = inc(i);
|
|
cnt = cnt + 1;
|
|
end;
|
|
if (cnt = 3) and (not eod) then
|
|
do;
|
|
sysbuff(index).level = tbuff(i) - '0';
|
|
i = inc(i);
|
|
cnt = 0;
|
|
do while ((cnt < 12) and (not eod)) and (tbuff(i) <> cr);
|
|
if (tbuff(i) > 60H) and (tbuff(i) < 7BH) then
|
|
do;
|
|
sysbuff(index).subject(cnt) = tbuff(i) - 20H;
|
|
end;
|
|
else
|
|
do;
|
|
sysbuff(index).subject(cnt) = tbuff(i);
|
|
end;
|
|
i = inc(i);
|
|
cnt = cnt + 1;
|
|
end;
|
|
if (not eod) then
|
|
do;
|
|
call set$rand$rec(.fcb);
|
|
call movef(1,.fcb(33),.sysbuff(index).record);
|
|
call movef(1,.fcb(34),.sysbuff(index).record+1);
|
|
sysbuff(index).record = sysbuff(index).record - 0001H;
|
|
sysbuff(index).rec$offset = i;
|
|
index = index + 1;
|
|
if ((index mod 8) = 0) then
|
|
do;
|
|
rec$cnt = rec$cnt + 1;
|
|
max$buf = max$buf - 128;
|
|
if (max$buf < 128) and (not eod) then
|
|
do;
|
|
cnt = close$file(.fcb);
|
|
call error(true,
|
|
.('Too many entries in Index Table.',
|
|
' Not enough memory.$'));
|
|
end;
|
|
else
|
|
do count = index to index + 7;
|
|
call movef(12,.('$ '),
|
|
.sysbuff(count).subject);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
else
|
|
do;
|
|
i = inc(i);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
call set$dma(.sysbuff);
|
|
rec$cnt = rec$cnt + 1;
|
|
/********************************
|
|
create HELP.HLP
|
|
********************************/
|
|
call movef(13,.(0,'HELP HLP',0),.fcb3);
|
|
call delete$file(.fcb3);
|
|
if make$file(.fcb3) = 0FFH then
|
|
do;
|
|
cnt = close$file(.fcb2);
|
|
call delete$file(.fcb2);
|
|
cnt = close$file(.fcb);
|
|
call error(true,.('Unable to Make HELP.HLP.$'));
|
|
end;
|
|
call movef(4,.(0,0,0,0),.fcb2+32);
|
|
cnt = read$rand(.fcb2);
|
|
do count = 0 to index - 1;
|
|
sysbuff(count).record = sysbuff(count).record + rec$cnt;
|
|
end;
|
|
do count = 0 to rec$cnt - 1;
|
|
call set$dma(.memory(shl(count,7)));
|
|
if write$record(.fcb3) = 0FFH then
|
|
do;
|
|
cnt = close$file(.fcb3);
|
|
call delete$file(.fcb3);
|
|
cnt = close$file(.fcb2);
|
|
call delete$file(.fcb2);
|
|
cnt = close$file(.fcb);
|
|
call error(true,.('Writing file HELP.HLP.$'));
|
|
end;
|
|
end;
|
|
call movef(4,.(0,0,0,0),.fcb+32);
|
|
cnt = read$rand(.fcb);
|
|
eod = 0;
|
|
do while (not eod);
|
|
count = 0;
|
|
max$buf = save$size;
|
|
do while (not eod) and (max$buf > 127);
|
|
call set$dma(.memory(shl(count,7)));
|
|
if read$record(.fcb) <> 0 then
|
|
do;
|
|
eod = true;
|
|
end;
|
|
else
|
|
do;
|
|
max$buf = max$buf - 128;
|
|
count = count + 1;
|
|
end;
|
|
end;
|
|
do count2 = 0 to count-1;
|
|
call set$dma(.memory(shl(count2,7)));
|
|
if write$record(.fcb3) = 0FFH then
|
|
do;
|
|
i = close$file(.fcb3);
|
|
call delete$file(.fcb3);
|
|
i = close$file(.fcb);
|
|
call error(true,.('Writing file HELP.HLP.$'));
|
|
end;
|
|
end;
|
|
end;
|
|
if close$file(.fcb) = 0FFH then
|
|
do;
|
|
cnt = close$file(.fcb3);
|
|
call error(true,.('Closing file HELP.DAT.$'));
|
|
end;
|
|
if close$file(.fcb3) = 0FFH then
|
|
do;
|
|
call error(true,.(false,'Closing file HELP.HLP.$'));
|
|
end;
|
|
call print$console$buf(.('HELP.HLP created',cr,lf,'$'));
|
|
end create$index;
|
|
|
|
/********************************************
|
|
Extract$file Procedure
|
|
|
|
Creates HELP.DAT from HELP.HLP
|
|
********************************************/
|
|
extract$file:
|
|
procedure;
|
|
declare (end$index,i) byte;
|
|
declare (count,count2,max$buf,save$size) address;
|
|
|
|
call print$console$buf(.(cr,lf,'Extracting data....$'));
|
|
call movef(13,.(0,'HELP HLP',0),.fcb);
|
|
if open$file(.fcb) = 0FFH then
|
|
do;
|
|
call error(true,.('Unable to find file HELP.HLP.$'));
|
|
end;
|
|
call movef(13,.(0,'HELP DAT',0),.fcb2);
|
|
call delete$file(.fcb2);
|
|
if make$file(.fcb2) = 0FFH then
|
|
do;
|
|
i = close$file(.fcb);
|
|
call error(true,.('Unable to Make HELP.DAT.$'));
|
|
end;
|
|
call set$dma(.sysbuff);
|
|
end$index = 0;
|
|
do while ((i := read$record(.fcb)) = 0) and (not end$index);
|
|
if sysbuff(7).subject(0) = '$' then end$index = true;
|
|
end;
|
|
eod = 0;
|
|
if i <> 0 then eod = true;
|
|
i = write$record(.fcb2);
|
|
save$size = maxb - .memory;
|
|
do while (not eod);
|
|
count = 0;
|
|
max$buf = save$size;
|
|
do while (not eod) and (max$buf > 127);
|
|
call set$dma(.memory(shl(count,7)));
|
|
if read$record(.fcb) <> 0 then
|
|
do;
|
|
eod = true;
|
|
end;
|
|
else
|
|
do;
|
|
max$buf = max$buf - 128;
|
|
count = count + 1;
|
|
end;
|
|
end;
|
|
do count2 = 0 to count-1;
|
|
call set$dma(.memory(shl(count2,7)));
|
|
if write$record(.fcb2) = 0FFH then
|
|
do;
|
|
i = close$file(.fcb2);
|
|
call delete$file(.fcb2);
|
|
i = close$file(.fcb);
|
|
call error(true,.('Writing file HELP.DAT.$'));
|
|
end;
|
|
end;
|
|
end;
|
|
if close$file(.fcb) = 0FFH then
|
|
do;
|
|
call error(false,.('Unable to Close HELP.HLP.$'));
|
|
end;
|
|
if close$file(.fcb2) = 0FFH then
|
|
do;
|
|
call delete$file(.fcb2);
|
|
call error(true,.('Unable to Close HELP.DAT.$'));
|
|
end;
|
|
call print$console$buf(.('Extraction complete',cr,lf,lf,
|
|
'HELP.DAT created',cr,lf,'$'));
|
|
|
|
end extract$file;
|
|
|
|
/*********************************************
|
|
Search$file Procedure
|
|
|
|
Searches the index table for the key
|
|
*********************************************/
|
|
search$file:
|
|
procedure byte;
|
|
declare (eod, error, cnt, found, saved, save$level) byte;
|
|
declare index address;
|
|
eod,
|
|
error,
|
|
found,
|
|
saved,
|
|
index = 0;
|
|
do while(not eod) and (not error);
|
|
if sysbuff(index).subject(0) <> '$' then
|
|
do;
|
|
if sysbuff(index).level = level + 1 then
|
|
do;
|
|
cnt = compare(.com(level).name,.sysbuff(index).subject);
|
|
if cnt = 0 then
|
|
do;
|
|
call movef(12,.sysbuff(index).subject,.com(level).name);
|
|
level = level + 1;
|
|
if (not saved) then
|
|
do;
|
|
save$level = level;
|
|
saved = true;
|
|
end;
|
|
if ((level > 8) or (com(level).name(0) = ' '))
|
|
or (com(level).name(0) = '[') then
|
|
do;
|
|
found = true;
|
|
eod = true;
|
|
end;
|
|
else
|
|
do;
|
|
index = index + 1;
|
|
found = 0;
|
|
end;
|
|
end;
|
|
else
|
|
do;
|
|
index = index + 1;
|
|
end;
|
|
end;
|
|
else
|
|
do;
|
|
if saved then
|
|
do;
|
|
if save$level < sysbuff(index).level then
|
|
do;
|
|
index = index + 1;
|
|
end;
|
|
else
|
|
do;
|
|
error = true;
|
|
end;
|
|
end;
|
|
else
|
|
do;
|
|
index = index + 1;
|
|
end;
|
|
end;
|
|
end;
|
|
else
|
|
do;
|
|
error = true;
|
|
end;
|
|
end;
|
|
if found then
|
|
do;
|
|
gindex = index + 1;
|
|
call movef(1,.sysbuff(index).record,.fcb(33));
|
|
call movef(1,.sysbuff(index).record+1,.fcb(34));
|
|
fcb(35) = 0;
|
|
offset = sysbuff(index).rec$offset;
|
|
level = sysbuff(index).level;
|
|
end;
|
|
return error;
|
|
end search$file;
|
|
|
|
/**************************************
|
|
Main Program
|
|
**************************************/
|
|
|
|
declare last$dseg$byte byte
|
|
initial (0);
|
|
|
|
|
|
plm:
|
|
do;
|
|
eod,
|
|
tcnt = 0;
|
|
version = get$version;
|
|
if (high(version) = 1) or (low(version) < 30h) then
|
|
do;
|
|
call error(true,.('Requires CP/M Version 3$'));
|
|
end;
|
|
cnt = parse;
|
|
if create$mode then
|
|
do;
|
|
call create$index;
|
|
end;
|
|
else
|
|
if extract$mode then
|
|
do;
|
|
call extract$file;
|
|
end;
|
|
end;
|
|
call terminate;
|
|
end help;
|