Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM I/MPM I SOURCE/07/sub.plm
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

1 line
9.3 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

$title ('MP/M 1.1 Submit')
submit:
do;
$include (copyrt.lit)
/*
Revised:
19 Jan 80 by Thomas Rolander
*/
declare start label;
declare jmp$to$start structure (
jmp$instr byte,
jmp$location address ) data (
0C3H,
.start-3);
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;
mon2a:
procedure (func,info) address external;
declare func byte;
declare info address;
end mon2a;
declare fcb (1) byte external;
declare fcb16 (1) byte external;
declare tbuff (1) byte external;
/**************************************
* *
* B D O S Externals *
* *
**************************************/
print$console$buffer:
procedure (buffer$address);
declare buffer$address address;
call mon1 (9,buffer$address);
end print$console$buffer;
open$file:
procedure (fcb$address) byte;
declare fcb$address address;
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;
delete$file:
procedure (fcb$address);
declare fcb$address address;
call mon1 (19,fcb$address);
end delete$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;
create$file:
procedure (fcb$address) byte;
declare fcb$address address;
return mon2 (22,fcb$address);
end create$file;
/**************************************
* *
* X D O S Externals *
* *
**************************************/
terminate:
procedure;
call mon1 (143,0);
end terminate;
get$console$number:
procedure byte;
return mon2 (153,0);
end get$console$number;
system$data$adr:
procedure address;
return mon2a (154,0);
end system$data$adr;
declare
copyright(*) byte data
(' Copyright(c) 1979, Digital Research ');
declare subflgadr address;
declare subflg based subflgadr (1) byte;
declare
ln(5) byte initial('001 $'),
ln1 byte at(.ln(0)),
ln2 byte at(.ln(1)),
ln3 byte at(.ln(2)),
dfcb(33) byte initial(1,'$$$ ','SUB',0),
console byte at(.dfcb(2)), /* current console number */
drec byte at(.dfcb(32)), /* current record */
buff(128) byte at(.tbuff), /* default buffer */
sfcb(33) byte at(.fcb); /* default fcb */
/* t h e m p / m 's u b m i t' f u n c t i o n
*/
declare lit literally 'literally',
dcl lit 'declare',
proc lit 'procedure',
addr lit 'address',
lca lit '110$0001b', /* lower case a */
lcz lit '111$1010b', /* lower case z */
endfile lit '1ah'; /* cp/m end of file */
declare
true literally '1',
false literally '0',
forever literally 'while true',
cr literally '13',
lf literally '10',
what literally '63';
move: procedure(s,d,n);
declare (s,d) address, n byte;
declare a based s byte, b based d byte;
do while (n := n - 1) <> 255;
b = a; s = s + 1; d = d + 1;
end;
end move;
error: procedure(a);
declare a address;
call print$console$buffer(.(cr,lf,'$'));
call print$console$buffer(.('error on line $'));
call print$console$buffer(.ln1);
call print$console$buffer(a);
call terminate;
end error;
declare sstring(128) byte, /* substitute string */
sbp byte; /* source buffer pointer (0-128) */
setup: procedure;
subflgadr = system$data$adr + 128;
console = get$console$number + '0';
/* move buffer to substitute string */
call move(.buff(1),.sstring(0),127);
sstring(buff(0))=0; /* mark end of string */
call move(.('SUB'),.sfcb(9),3); /* set file type to sub */
if open$file(.sfcb(0)) = 255 then
call error(.('no ''SUB'' file present$'));
/* otherwise file is open - read subsequent data */
sbp = 128; /* causes read below */
sfcb(32) = 0; /* nr = 0 for sub file to read */
end setup;
getsource: procedure byte;
/* read the next source character */
declare b byte;
if sbp > 127 then
do; if read$record(.sfcb(0)) <> 0 then
return endfile;
sbp = 0;
end;
if (b := buff((sbp:=sbp+1)-1)) = cr then
do; /* increment line */
if (ln3 := ln3 + 1) > '9' then
do; ln3 = '0';
if (ln2 := ln2 + 1) > '9' then
do; ln2 = '0';
ln1 = ln1 + 1;
end;
end;
end;
/* translate to upper case */
if (b-61h) < 26 then /* lower case alpha */
b = b and 5fh; /* change to upper case */
return b;
end getsource;
writebuff: procedure;
/* write the contents of the buffer to disk */
if write$record(.dfcb) <> 0 then /* error */
call error(.('disk write error$'));
end writebuff;
declare rbuff(2048) byte, /* jcl buffer */
rbp address, /* jcl buffer pointer */
rlen byte; /* length of current command */
fillrbuff: procedure;
declare (s,ssbp) byte; /* sub string buffer pointer */
notend: procedure byte;
/* look at next character in sstring, return
true if not at the end of the string - char passed
back in 's' */
if not ((s := sstring(ssbp)) = ' ' or s = 0) then
do;
ssbp = ssbp + 1;
return true;
end;
return false;
end notend;
deblankparm: procedure;
/* clear to next non blank substitute string */
do while sstring(ssbp) = ' ';
ssbp = ssbp + 1;
end;
end deblankparm;
putrbuff: procedure(b);
declare b byte;
if (rbp := rbp + 1) > last(rbuff) then
call error(.('command buffer overflow$'));
rbuff(rbp) = b;
/* len: c1 ... c125 :00:$ = 128 chars */
if (rlen := rlen + 1) > 125 then
call error(.('command too long$'));
end putrbuff;
declare (reading,b) byte;
/* fill the jcl buffer */
rbuff(0),rbp = 0;
reading = true;
do while reading;
rlen = 0; /* reset command length */
do while (b:=getsource) <> endfile and b <> cr;
if b <> lf then
do; if b = '$' then /* copy substitute string */
do; if (b:=getsource) = '$' then
/* $$ replaced by $ */
call putrbuff(b); else
if (b := b - '0') > 9 then
call error(.('parameter error$')); else
do; /* find string 'b' in sstring */
ssbp = 0; call deblankparm;
/* ready to scan sstring */
do while b <> 0; b = b - 1;
/* clear next parameter */
do while notend;
end;
call deblankparm;
end;
/* ready to copy substitute string from
position ssbp */
do while notend;
call putrbuff(s);
end;
end;
end; else /* not a '$' */
if b = '^' then /* control character */
do; /* must be ^a ... ^z */
if (b:=getsource - 'A') > 25 then
call error(.(
'invalid control character$'));
else
call putrbuff(b+1);
end; else /* not $ or ^ */
call putrbuff(b);
end;
end; /* of line or input file - compute length */
reading = b = cr;
call putrbuff(rlen); /* store length */
end;
/* entire file has been read and processed */
end fillrbuff;
makefile: procedure;
/* write resulting command file */
declare i byte;
getrbuff: procedure byte;
return rbuff(rbp := rbp - 1);
end getrbuff;
call delete$file(.dfcb);
drec = 0; /* zero the next record to write */
if create$file(.dfcb) = 255
then call error(.('directory full$'));
do while (i := getrbuff) <> 0;
/* copy i characters to buffer */
/* 00 $ at end of line gives 1.3 & 1.4 compatibility */
buff(0) = i; buff(i+1) = 00; buff(i+2) = '$';
do while i > 0;
buff(i) = getrbuff; i=i-1;
end;
/* buffer filled to $ */
call writebuff;
end;
if close$file(.dfcb) = 255
then call error(.('close error$'));
else subflg(get$console$number) = true;
end makefile;
declare last$dseg$byte byte
initial (0);
start:
do;
call setup;
call fillrbuff;
call makefile;
call terminate;
end;
end submit;