Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 3.X/CPM 3.0/SOURCE/minhlp.plm
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

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;