|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 100608 (0x18900) Types: TextFile Names: »disccopy5tx «
└─⟦01e83a425⟧ Bits:30008166 Bånd med SW8010 og SW8500 source code └─⟦75ff9bef3⟧ └─⟦this⟧ »disccopy5tx «
begin integer array kind(0:100),alphabet(0:127),zdescr,ia(1:21),shdescr(1:12), entrybase,ownbase(1:2); real array ra(0:100),par,auxname,docname,name,toname,fromname, act_auxname,act_docname,maincatname(1:2); long array program(1:2); integer sep,space_name,point_name,space_integer,point_integer,i,j, type,paramno,firstentryname,no_of_entries,devno,todevno, fromdevno,scopetype,blocklen,tosegm,fromsegm,number_of_segments, firstbuffer,topbuffer,topinbuf,curfirstbuf,curtopbuf, curbufsize,base_lower,base_upper,permkey,start_pos,list,last, slicelength,slices,segments,entries,bytes,basetype,totalsegments, chain_addr; long maximum,topfromsegm,toptosegm; boolean maincatrem,output,ok,fp_mode,scope,base, area,morelines, checkread, olddisk; integer array field iaf; real array field areaname; zone zhelp(1,1,stderror),zdisc(5*128,1,ownerror); \f procedure result (no, text, name, res, exit); integer no, res ; string text ; real array name ; boolean exit ; begin integer i; real mon_name, mon_res; errorbits := 1; <*warning.no, ok.no*> write (out, "nl", 1, "*", 3, <: monitor result ::>); i := 1; if no < 0 then <*result from operation sent*> write (out, "nl", 1, text, <: : :>, string name (increase (i)), "nl", 1, "sp", 1, <:result : :>, case res of ( <::>, <:process not reserver of disc process:>, <:receiver logical disc or physical disc with logical discs connected:>), "nl", 1) else begin <*monitor procedure result*> if no = 40 then begin mon_name := real <:create entry:>; mon_res := real ( case res of ( <::>, <:catalog i/o error, document not mounted or not ready:>, <:name conflict:>, <:claims exceeded:>, <:cat base outside std base:>, <:name format of entry or document illegal:>, <:main catalog not present:> )); end \f else if no = 54 then begin mon_name := real <:create peripheral process:>; mon_res := real ( case res of ( <:function forbidden in calling process:>, <:calling process not user, catalog i/o error:>, <:name conflict, not same disc:>, <:device number does not exist:>, <:device is reserved by another user:>, <:name format illegal:>, <::>)); end else if no = 90 then begin mon_name := real <:permanent entry into aux cat:>; mon_res := real ( case res of ( <::>, <:document not ready, document does not exist, catalog i/o error:>, <:name conflict in aux cat, entry not found:>, <:entry protected, i.e. outside maxbases, permkey illegal:>, <:area used by another process, entry already permanent in another auxcat:>, <:name format illegal, claims exceeded:>, <:main catalog not present:> )); end \f else if no = 102 then begin mon_name := real <:prepare backing storage:>; mon_res := real ( case res of ( <:area claims exceeded, function forbidden in calling process:>, <:catalog i/o error:>, <:auxcat name overlap, auxcat name exists already:>, <:document device does not exist, document device is not a bs device, document device not reserved:>, <:auxcat size <= 0 or auxcat size too large, chainhead chain inconsistent, auxcat chain inconsistent, illegal kind of chaintable, permkey of auxcat illegal, too many slices, claims exceeded (too few slices for chaintable), -,- (auxcat too large), -,- (no room in maincat):>, <:auxcat name format illegal, doc name format illegal:>, <:no chains idle:> )); end else if no = 104 then begin mon_name := real <:insert entry:>; mon_res := real ( case res of ( <:function forbidden in calling process:>, <:catalog i/o error, document not found, state of document does not permit the call:>, <:name overlap, name exists already:>, <:calling process not user of the device:>, <:permkey illegal, interval illegal, chain overlap, chain outside limits:>, <:name format illegal, docname format illegal, claims exceeded:>, <:main catalog not present:> )); end \f else if no = 106 then begin mon_name := real <:insert backing storage:>; mon_res := real (case res of ( <:function forbidden in calling process:>, <:document not found, state of document does not permit call:>, <::>, <:calling process not user of device:>, <::>, <:docname format illegal:>, <::>)); end else if no = 108 then begin mon_name := real <:delete backing storage:>; mon_res := real (case res of ( <:function forbidden in calling process:>, <:document not found, catalog i/o error:>, <::>, <:calling process not user of device:>, <:area processes exist for the document:>, <:docname format illegal, main catalog on the document:>, <::>)); end else if no = 110 then begin mon_name := real <:delete entries:>; mon_res := real (case res of ( <:function forbidden in calling process:>, <:document not found, catalog i/o error, state of document does not permit call:>, <:not all entries deleted yet:>, <:calling process not user of device:>, <::>, <:docname format illegal:>, <::>)); end \f else if no = 120 then begin mon_name := real <:create aux entry and area process:>; mon_res := real (case res of ( <:function forbidden in calling process, area claims exceeded:>, <:catalog i/o error, document not found, state of document does not permit the call:>, <:procname overlap, procname exists already, entryname overlap (in auxcat), entryname exists already (in auxcat):>, <:calling process not user of the device, claims exceeded:>, <:key illegal, interval illegal:>, <:entry name format illegal, proc name format illegal, doc name format illegal:>, <::> )); end; write (out, "nl", 1, string mon_name, <: : :>, string name (increase (i)), "nl", 1, "sp", 1, <:result : :>, string mon_res, "nl", 1); end <*monitor procedure result*>; if not fpmode then stopzone (out, false); if exit then begin close (zdisc, true); reset_catbase; if fp_mode then goto aftererror else goto next_line; end <*exit*>; end procedure result; \f procedure maybe_device_status (z); zone z ; <***********************************************************> <* *> <* The procedure writes on the zone z a device status mes- *> <* sage with document name and status bit names the same *> <* way fp does if the program was to terminate with a give *> <* up alarm instead of having trapped one. *> <* *> <***********************************************************> begin integer status, cause, param, bit; long array text (1:4); long array field docname; docname := 8; <*fields possible docname in text*> status := getalarm (text); cause := alarmcause extract 24 ; param := alarmcause shift (-24); if cause = -11 then begin <*give up*> write (z, "nl", 1, <:device status :>, text.docname); for bit := 0 step 1 until 23 do if status shift bit < 0 then write (z, "nl", 1, case (bit + 1) of ( <:intervention:>, <:parity error:>, <:timer:>, <:data overrun:>, <:block length error:>, <:end of document:>, <:load point:>, <:tape mark or attention:>, <:writing enabled:>, <:mode error:>, <:read error:>, <:card rejected or disk error:>, <:checksum error:>, <:bit 13:>, <:bit 14:>, <:stopped:>, <:word defect:>, <:position error:>, <:process does not exist:>, <:disconnected:>, <:unintelligible:>, <:rejected:>, <:normal:>, <:hard error:>)); write (z, "nl", 1); end; end rs_alarm; \f integer procedure process_description (devno, proc_area); value devno ; integer devno ; integer array proc_area ; begin integer i; system (5, 74, proc_area); i:= proc_area(1)+devno*2; if i>=proc_area(2) then writeerror (<:devno outside limits:>); system(5, i, proc_area); process_description:= proc_area(1); system(5,proc_area(1), proc_area); end process_description; \f integer procedure device_number (proc_address); value proc_address ; integer proc_address ; begin integer array ia (1:2); integer i, max_device; system (5, 74, ia); max_device:= (ia(2)-ia(1))//2; begin integer array name_table (0:max_device); integer array field iff; iff := -2; system(5, ia(1), name_table.iff); for i:= 0 step 1 until max_device do begin if proc_address=name_table(i) then begin device_number:= i; i:= max_device; end; end; end; end device_number; procedure typetext(text); string text; begin write(out, text); if -,fp_mode then setposition(out,0,0); end; procedure typein(number); integer number; begin setposition(in, 0, 0); read(in, number); end; \f procedure alarm(text); string text; begin typetext(text); typetext(<:<10>:>); goto after_error; end; procedure caterror(z,s,b); zone z ; integer s,b ; if s shift (-18) extract 1 = 1 then b:= 34 else if s shift (-2) extract 1 = 1 then stderror(z,s,b); procedure end_of_document(z); zone z ; begin getshare6(z,shdescr,1); write(out,<:<10>:>,if shdescr(4) shift (-12) = 3 then <:input from segment : :> else <:output to segment : :>,<<ddddddd>,shdescr(7), <: - end of document:>); typetext(<:<10>:>); end; procedure status (z, s, b); zone z; integer s, b; begin integer bit; integer array zdescr(1:20), shdescr(1:12); long array field zname; zname := 2; getzone6 (z, zdescr); getshare6 (z, shdescr, 1); write (out, <:<10>:>, if shdescr(4) shift (-12) = 3 then <:input from: :> else <:output to : :>); write (out, false add 32, 12 - write (out, zdescr.zname)); write (out, <<dddddd>, <: segm::>, shdescr(7), <: status=:>); for bit := 0 step 1 until 23 do write (out, if s shift bit < 0 then <:1:> else <:.:>); typetext (<:<10>:>); end procedure status; \f procedure ownerror (z, s, b); zone z; integer s, b; begin status (z, s, b); stderror (z, s, b); end; boolean procedure transfer (z, cursegment, topsegment); zone z; integer cursegment; long topsegment; begin integer mode; long remaining_bytes; integer logstatus, segments, repcount; integer array answer(1:8); repcount := 0; curfirstbuf := firstbuffer; curbufsize := curtopbuf - firstbuffer; remaining_bytes := (topsegment - cursegment) shift 9; if remaining_bytes < curbufsize then begin curbufsize := remaining_bytes; curtopbuf := curfirstbuf + curbufsize; end; next_block: if curfirstbuf = curtopbuf then goto exit; mode := if checkread and not olddisk and output then 1 else 0; <*if checkread and not old disk and output then read after write*> <*write (out, "nl", 2, <:*********** mode = :>, mode, <: **************:>); *> shdescr (4) := (if output then 5 else 3) shift 12 + mode; shdescr (5) := curfirstbuf; shdescr (6) := curfirstbuf + curbufsize - 2; shdescr (7) := cursegment; setshare6 (z, shdescr, 1); monitor (16) send message :( z, 1, shdescr); logstatus := 1 shift monitor (18) wait answer :( z, 1, answer); bytes := if logstatus = 2 <* normal answer *> then answer (2) else 0; \f if logstatus = 2 <* normal answer *> then logstatus := logstatus + answer (1); if (logstatus shift(-18) extract 1 = 1 and logstatus shift(-1) extract 1 = 1 and curbufsize = 512 and -,area ) or logstatus = 1 shift 18 + 1 shift 1 <* end document *> then curtopbuf:= curfirstbuf + bytes else if logstatus <> 1 shift 1 then begin <* transfer not ok *> if curbufsize <> 512 then begin <* repeat same transfer, but with size = 512 bytes *> bytes := 0; curbufsize := 512; end else begin <*single segment transfer was not ok*> repcount := repcount + 1; if repcount < 6 then bytes := 0 <*retry*> else begin <*give up*> repcount := 0; errorbits := 3; status (z, logstatus, bytes); bytes := 512; <*simulate transfer of one segment*> if logstatus extract 6 <> 2 <*normal answer*> and logstatus extract 6 <> 1 shift 4 <*malfnct, i.e. bus parity*> then begin <*simulate end of document*> curtopbuf := firstbuffer; goto exit; end <*simulate*>; end <*give up*>; end <*single transfer not ok*>; end else begin <*transfer ok*> repcount := 0; if curbufsize <> 512 then curbufsize := curbufsize - bytes; end <*transfer ok*>; curfirstbuf := curfirstbuf + bytes; segments := bytes shift (-9); cursegment := cursegment + segments; goto next_block; exit: transfer := curtopbuf <> firstbuffer; end procedure transfer; \f procedure copyarea(tosegm, fromsegm, size); value tosegm, fromsegm, size; integer tosegm, fromsegm; long size; <* this procedure will perform the actual copying*> begin if fpmode then begin <*the segments involved in copyarea must be transferred*> <*to core and locked before data buffer is allocated *> integer oldtrapmode; oldtrapmode :=trapmode; trapmode := 1 shift 1; <*stack alarm masked off*> trap (maybe_stack); lock ( transfer, getdevorname, setshare6, 1 , monitor , 3 ); maybe_stack: if alarmcause extract 24 = -1 then alarm ( <:process too small:> ) else if alarmcause extract 24 < 0 then alarm ( <:alarm:> ); trapmode := old_trapmode; end; blocklen := system(2 <*free core*>, 0, name) -1624 <* space for local variables and procedure calls *>; blocklen := blocklen shift (-9) shift 9; if blocklen < 512 then alarm (<:process too small:>); begin integer i; integer array todesc, fromdesc(1:20), procdescr (1:1); zone z(blocklen//4, 1, status); procedure prepout; begin getzone6(z,fromdesc); setzone6(z,todesc); output:=true; end prepout; procedure prepin; begin getzone6(z,todesc); setzone6(z,fromdesc); output:=false; end prepin; \f i:=1; getzone6(z,todesc); open(z,0,string fromname(increase(i)),-1 shift 2 - 1 shift 8); <* all except normal answer and stopped *> if area then monitor(52,z,0,ia); monitor(6)initialize:(z,0,ia); prepout; i:=1; open(z,0,string toname(increase(i)),-1 shift 2 - 1 shift 8); <* all except normal answer and stopped *> if area then monitor(52,z,0,ia); monitor(8)reserve:(z,0,ia); procdescr (1) := monitor (4, z, 0, procdescr); if procdescr (1) <> 0 then begin <*process exists*> if area then system (5, procdescr (1) + 10, procdescr); <*main disc*> system (5, procdescr (1), procdescr); <*procdescr (1) = kind*> end; olddisk := procdescr (1) <> 6; <*not exist or kind <> 6*> prepin; firstbuffer := fromdesc (19) + 1; topbuffer := fromdesc (20) * 4 <* buffersize in bytes *> + firstbuffer; getshare6 (z, shdescr, 1); topfromsegm := size + fromsegm; toptosegm := size + tosegm; nextblock: curtopbuf := topbuffer; if transfer (z, fromsegm, topfromsegm) then begin topinbuf := curtopbuf; prepout; transfer (z, tosegm, toptosegm); prepin; if topinbuf = curtopbuf then goto nextblock; prepout; end_of_document(z); prepin; end; getshare6(z,shdescr,1); totalsegments:= shdescr(7) + bytes shift (-9); <* no. of last segment copied *> close(z,true); monitor(64)remove process:(z,0,ia); prepout; close(z,true); monitor(64)remove process:(z,0,ia); prepin; end; end copyarea; \f boolean procedure getdevorname(getdevice,devno,name,auxname,chain_addr); boolean getdevice; integer devno,chain_addr; real array name,auxname; begin integer chainentry, firstdeviceinnametable, device; integer array coreword(1:1), bspointers(1:3), chainhead(1:17); real field docname1, docname2, auxcatname1, auxcatname2; integer field documentnametableaddress; docname1 := 20; docname2 := docname1 + 4; documentnametableaddress := docname1 + 6; auxcatname1:= 10; auxcatname2:= 14; <* get nametable address of first,top chain *> system(5, 92, bspointers); <* get nametable address of first device *> system(5, 74, coreword); firstdeviceinnametable := coreword(1); <* scan all chaintables to find the rigth one *> for chainentry := bspointers(3) - 2 <* last chaintable *> step - 2 <* size of nametable entry *> until bspointers(1) <* first chaintable *> do begin <* get chaintable address *> system(5, chainentry, coreword); <* get chainhead from chaintable *> system(5, coreword(1) - 34, chainhead); <* compute devicenumber of discdrive *> device := (chainhead.documentnametableaddress - firstdeviceinnametable ) // 2; if chainhead.docname1 shift (-24) extract 24 <> 0 and (if -, getdevice then device = devno else (name(1) = chainhead.docname1 and name(2) = chainhead.docname2 ) ) then goto chaintablefound; <* this chaintable was not the rigth one *> end; <* no chaintables was found good enough *> getdevorname := true; goto exit; chaintablefound: devno := device; name(1) := chainhead.docname1; name(2) := chainhead.docname2; auxname(1):= chainhead.auxcatname1; auxname(2):= chainhead.auxcatname2; chain_addr:= coreword(1); getdevorname := false; exit: end procedure getdevorname; \f boolean procedure connect(devno, name); integer devno; real array name; begin integer repcount; integer array zdescr(1:20); real array field zname; procedure repeatproc(z, s, b); zone z; integer s, b; begin repcount := repcount + 1; if repcount < 3 and s = 1 shift 5 then goto try_once_more; b := 512; connect := true; write (out, <:intervention on :>, <<zdd>, devno); typetext (<:<10>:>); end procedure repeatproc; repcount := 0; connect := false; try_once_more: begin zone device(128, 1, repeatproc); zname := 2; i := 1; open(device, 0, string name(increase(i)), 1 shift 5); i := monitor(54 <*create peripheral proc*>, device, devno, zdescr); if i <> 0 then begin result(54, <::>, name, i,false); connect := true; end else begin inrec6(device, 0); <*try to read a block *> getzone6(device, zdescr); name(1) := zdescr.zname(1); name(2) := zdescr.zname(2); end; end; end procedure connect; \f boolean procedure kitoff(docname); real array docname; begin integer array tail (1:10); long array field dname; integer i,k; zone z (512,1,stderror); long array progname(1:2); dname := 2; <*fields docname in tail*> kitoff := false; <*assume succes in removal*> for i := 1 step 1 until 4 do ia(17+i) := docname.iaf(i); k:=monitor(108)delete bs:(z,0,ia); if k=5 <* area processes exists for same document *> then begin <*remove area process*> <*maybe remove program area proc*> system (2, 0, progname); open (z, 4, progname, 0); tail.dname (1) := tail.dname (2) := long <::>; if monitor (42) lookup tail :(z, i, tail) = 0 and tail.dname (1) = long docname (1) and tail.dname (2) = long docname (2) then begin <*lock all program segments and remove proc*> if fp_mode then lockall; close (z, true); typetext (<:notice : disc with program file is removed<10>:>); end else close (z, false); <*maybe remove fp area process*> open (z, 4, <:fp:>, 0); tail.dname (1) := tail.dname (2) := long <::>; if monitor (42) lookup tail :(z, i, tail) = 0 and tail.dname (1) = long docname (1) and tail.dname (2) = long docname (2) then begin close (z, true); typetext (<:notice : disc with fp prog file is removed<10>:>); end_action := 1; <*end prog condition := finis*> end else close (z, false); k := monitor (108) delete bs :(z, 0, ia); end <*remove area processes*>; if k=6 <* maincat on same document*> then begin maincatrem := 0 = monitor(114)remove main catalog:(z,0,ia); if maincatrem then typetext (<:notice : disc with main catalog is removed<10>:>); k:=monitor(108)delete bs:(z,0,ia); end; \f if k<>0 and k<>2 then begin kitoff := true; result(108, <::>, docname, k,true); end else begin for k:=monitor(110)delete entries:(z,0,ia) while k=3 do; if k<>0 and k<>7 then begin kitoff := true; result(110, <::>, docname, k,true); end; end; end procedure kitoff; \f procedure list_entry(entry,k); integer k ; real array entry ; begin boolean sp; long array field entryname; sp:= false add 32; entryname:= 6; outchar(out,10); write(out,sp,18-write(out,entry.entryname)); if entry.iaf(8) >= 0 then write(out,<<dddddd>,entry.iaf(8)) else write(out,sp,6); write(out,<<-ddddddd>,sp,5,entry.iaf(2),sp,5,entry.iaf(3)); if k <> 0 then write(out,<: - not ok:>, "nl", 1, <:result = :>, case k of ( <:function forbidden in calling process:>, <:catalog i/o error, document not found, state illegal:>, <:name overlap/exists already:>, <:calling process not user of the device:>, <:permkey/interval illegal, chain overlap/outside limits:>, <:name/docname format illegal, claims exceeded:>, <:main catalog not present:> ), "nl", 1); if -,fp_mode then setposition(out,0,0); end listentry; \f procedure kiton(devno,docname,list,insert_entry_incl,wrkname); boolean insert__entry_incl,wrkname; integer devno,list; real array docname; begin long array field auxcat,document; zone zcat(128,1,ownerror); integer k,i,catsize, first_slice_chain, last_slice_doc, no_of_slices, chain_length; integer array shdescr (1:12); long array field laf; boolean head_listed; document:= 16; auxcat:= 6; laf:=6; docname(1) := 0; if connect(devno, docname) then goto if fp_mode then aftererror else nextline; i := 1; open (zdisc, 6, string docname (increase (i)), 0); <*read chain*> inrec6(zdisc,34); first_slice_chain := zdisc.iaf (15) extract 12; last__slice_doc := zdisc.iaf (15) shift (-12) extract 12; no_of_slices := last_slice_doc - first_slice_chain + 1; chain_length := ((34 + no_of_slices + 511) // 512) * 512; setposition (zdisc, 0, 0); getshare6 (zdisc, shdescr, 1); shdescr (3) := shdescr (2) + chain_length - 1; <*last sh := first sh + ...*> setshare6 (zdisc, shdescr, 1); inrec6 (zdisc, chainlength); <*just the necessary no of segments*> if -,wrkname then begin <* create ph. proc. with correct documentname *> getzone6(zdisc,ia); for i:= 2 step 1 until 5 do docname.iaf(i-1):= ia(i):= zdisc.iaf(i+7); setzone6(zdisc,ia); monitor(54)create ph proc:(zdisc,devno,ia); end else begin <* insert wrkname for document and auxcat in chainhead *> for i:= 1 step 1 until 4 do begin <* save actual names before insertion of wrknames *> act_auxname.iaf(i):= zdisc.iaf(i+3); <* save auxname *> act_docname.iaf(i) := zdisc.iaf(i+8); <* save docname *> end; monitor(68)generate wrkname:(zcat,0,ia); getzone6(zcat,ia); for i:= 1 step 1 until 4 do begin zdisc.iaf(i+8):= docname.iaf(i); <* document *> zdisc.iaf(i+3):= ia(i+1); <* auxcat *> end; close(zcat,false); end; slicelength:= zdisc.iaf(14); monitor(8)reserve:(zdisc,i,ia); k := monitor(102)prepare bs:(zdisc,i,ia); if k <> 0 then result(102, <::>, docname, k, true); if maincatrem then begin <* connect maincat if possible *> i:= 1; open(zcat,4,string zdisc.laf(increase(i)),0); close(zcat,true); <* remove area process for auxcat *> maincatname(1):= real<:catal:> add 111; maincatname(2):= real<:g:>; maincatrem:= monitor(112)connect maincat:(zdisc,0,maincatname.iaf) <> 0; write (out, "nl", 1, <:main catalog :>, if maincatrem then <:not :> else <: :>, <:reconnected:>); typetext (<:<10>:>); end; if insert_entry_incl then begin <* insert entries in maincatalog *> head_listed := false; i:=1; open(zcat,4,string zdisc.laf(increase(i)),0); catsize:=zdisc.iaf(8)*15; for i:=1 step 1 until catsize do begin inrec6(zcat,34); <*if entry used then insert entry*> if zcat.iaf(1)<>-1 then begin k:= monitor(104)insert entry:(zdisc,0,zcat.iaf); if not head_listed and (list = 2 or list = 3 and (extend zcat.iaf (2) > extend (-8388607) or extend zcat.iaf (3) < extend 8388605) or list = 4 and k > 0 and k <> 3 or list = 5 and k = 3) then begin write(out,<:<10>*kiton, :>,case list of (<::>, <:entries inserted::>, <:non system entries inserted::>, <:errors during insertion::>, <:entries not inserted due to name overlap::>), <:<10><10>:>, <:entry name size :>, <:lower base upper base:>, "nl", 1); head_listed := true; end; case list of begin ; <* list.no *> list_entry(zcat,k) ; <* list.yes *> if extend zcat.iaf(2) > extend (-8388607) or extend zcat.iaf(3) < extend 8388605 then list_entry(zcat,k) ; <* list.nonsys *> if k <> 0 and k <> 3 then list_entry(zcat,k) ; <* list.error *> if k = 3 then list_entry(zcat,0) ; <* list.warning *> end; end; end; close(zcat,true); if -,wrkname then close(zdisc,true); open (zcat, 4, <:fp:>, 0); if monitor (52) create area proc :(zcat, 1, ia) = 0 then endaction := 0; <*fp area proc intact*> close (zcat, false); end; end procedure kiton; \f procedure lockall; lock (0, progsize - 1); <*lock all upper part of prog in core*> \f boolean procedure next_param(arr,no,type,optional); value optional ; boolean optional ; integer no,type ; array arr ; begin comment this procedure returns call-parameter number 'no' in array 'arr'. type-checking is performed as follows: type = 1: space-name is demanded type = 2: point-name is demanded type = 3: space-integer is demanded type = 4: point-integer is demanded type = 5: point-integer or point-name is demanded 'optional' indicates whether the next parameter is optional or not. the procedure operates in fp-mode or in conversational mode. ; procedure conv_error(number,i,type,delim); value number,i,type,delim ; integer number,i,type,delim ; begin <* error-messages in conversational mode *> write(out,<:<10>illegal parameter no. :>,no, <:,must be :>,case type of (<:<sp><name>:>, <:.<name>:>,<:<sp><integer>:>, <:.<integer>:>,<:.<integer> or .<name>:>), <: read: :>); if delim = 0 then write(out,<:<integer>:>) else outchar(out,delim); if kind(i) = 6 <* text *> then write(out,string ra(increase(i))) else if kind(i) = 2 <* legal number *> then write(out,round ra(i)) else write(out,<: illegal number :>); write(out,<:<10>:>); if -,fp_mode then setposition(out,0,0); goto next_line; end conv_error; boolean ok,continue; real array op_name(1:2); integer sep,action,number,delim,separator; if optional then begin op_name(1):= arr(1); op_name(2):= arr(2); end; continue:= true; if fp_mode then begin <* fp_mode *> sep:= system(4,no,arr); if sep <> 0 then begin if optional then begin if sep = (case type of (space_name,point_name,space_integer, point_integer)) then begin if op_name(1) <> arr(1) or op_name(2) <> arr(2) then begin i:= 1; write(out,<:<10>illegal parameter no. :>,no, <:,must be: :>,string op_name(increase(i))); i:= 1; write(out,<: read: :>,string arr(increase(i))); goto endprogram; end; end else continue:= false; end optional; if continue then begin case type of begin ok:= sep = space_name; ok:= sep = point_name; ok:= sep = space_integer; ok:= sep = point_integer; begin type:= if sep = point_name then 2 else 4; <* return-value *> ok:= sep = point_name or sep = point_integer; end; end; if -,ok then begin separator:= 5; for i:= 1 step 1 until 4 do if sep = ( case i of (space_name,point_name,space_integer, point_integer)) then separator:= i ; write(out,<:<10>***:>,program,<:: illegal fpparameter no. :>, no,<:,must be :>,case type of (<:<sp><name>:>, <:.<name>:>,<:<sp><integer>:>,<:.<integer>:>), <: read::>,case separator of (<:<sp>:>,<:.:>, <:<sp>:>,<:.:>,<::>)); if separator < 3 <* name *> then begin i:= 1; write(out,string arr(increase(i))); end else write(out,round arr(1)); goto endprogram; end -, ok; end; end; next_param:= if optional then continue and sep <> 0 else sep <> 0; end else begin <* conversational mode *> delim:= 0; number:= -1; <* search item *> for i:= 0,i + 1 while kind(i) <> 8 and number < no do begin action:= case ((kind(i)-1)*8 + kind(i+1)) of <* kind(i+1) *> ( 3 , 3 , 3 , 3 , 3 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , <* kind(i) *> 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 2 , 2 , 2 , 1 , 1 , 3 , 3 , 3 , 1 , 2 , 2 ) ; case action of begin number:= number + 1; <* text or integer found *> ; <* skip *> begin <* error *> write(out,<:<10>action-table in error:>); goto endprogram; end; end; end for-loop; if number = no then begin <* now 'i' points at the first element of the item in array 'ra' . get the item and check it . *> if optional then begin if round ra(i-1) = (case type of (32,46,32,46)) then begin if op_name(1) <> ra(i) then begin j:= 1; write(out,<:<10>illegal parameter no. :>,no, <:,must be: :>,string op_name(increase(j)), <: read: :>,string ra(increase(i)),<:<10>:>); if -,fp_mode then setposition(out,0,0); goto next_line; end; end else continue:= false; end optional; if continue then begin if kind(i-1) = 7 then delim:= round ra(i-1); case type of begin <* space-name *> if delim <> 32 or kind(i) <> 6 then conv_error(number,i,1,delim); <* point-name *> if delim <> 46 or kind(i) <> 6 then converror(number,i,2,delim); <* space-int. *> if delim <> 32 or kind(i) <> 2 then conv_error(number,i,3,delim); <* point-int. *> if delim <> 46 or kind(i) <> 2 then conv_error(number,i,4,delim); <* point-int. or point-name *> begin if delim=46 and kind(i)=6 then type:= 2 else if delim=46 and kind(i)=2 then type:= 4 else conv_error(number,i,5,delim); end; end case; <* return item in 'arr' *> if type < 3 then begin <* text *> arr(1):= ra(i); arr(2):= if kind(i+1) <> 6 then real <::> else ra(i+1) shift(-8) shift 8; <* max 11 chars *> end else arr(1):= ra(i); end; end; next_param:= if optional then continue and number = no <* optional param. present *> else number = no; end conversational mode; if continue then no:= no + 1; end next_param; \f procedure dump_actual_names(devno); integer devno ; begin <* dumps actual names of auxcat and document in chainhead. *> zone zdisc (128, 1, ownerror); docname(1):= 0; connect(devno,docname); <* create ph. proc with wrkname *> i:= 1; open(zdisc,6,string docname(increase(i)),0); swoprec6(zdisc,34); <* get chainhead *> for i:= 1 step 1 until 4 do begin zdisc.iaf(i+3):= act_auxname.iaf(i); <* reestablish auxname *> zdisc.iaf(i+8):= act_docname.iaf(i); <* reestablish docname *> end; close(zdisc,true); monitor(64)remove process:(zdisc,0,ia); end; \f integer procedure convert_to_number(arr); array arr ; begin integer i; convert_to_number:= 13; for i:= 1 step 1 until 12 do begin if arr(1) = ( case i of ( real<:discc:> add 'o', real<:kitna:> add 'm', real<:kiton:> , real<:kitof:> add 'f', real<:packo:> add 'n', real<:packo:> add 'f', real<:kitla:> add 'b', real<:end:> , real<:save:> , real<:load:> , real<:bin:> , real<:typei:> add 'n' )) and arr(2) = ( case i of ( real<:py:> , real<:e:> , real<::> , real<::> , real<::> , real<:f:> , real<:el:> , real<::> , real<::> , real<::> , real<::> , real<::> )) then convert_to_number:= i; end; end convert_to_number; \f procedure outtable(alphabet,length); value length ; integer length ; integer array alphabet ; begin zone alpha(25,1,blockproc); integer class,char,i; procedure blockproc(z,s,b); zone z ; integer s,b ; if (s shift (-5)) extract 1 <> 1 then stderror(z,s,b) else b:= 25*4; if length < 0 or length > 127 then length:= 127; open(alpha,0,<::>,1 shift 5); for i:= 0 step 1 until length do write(alpha,false add i,1); write(alpha,false add 10,1); setposition(alpha,0,0); for i:= 0 step 1 until length do begin class:= readchar(alpha,char); if char <> i then begin class:= 0; repeatchar(alpha); end; alphabet(i):= class shift 12 + i; end; end outtable; integer procedure convert_param(arr); array arr ; begin integer i; convert_param:= 7; for i:= 1 step 1 until 6 do if arr (1) = ( case i of ( real<:from:> , real<:to:> , real<:scope:> , real<:base:> , real<:list:> , real<:check:> add 'r' )) then convert_param := i; end; \f procedure write_error(cause); string cause ; begin write (out, "nl", 1); if fp_mode then write (out, <:***:>, program, <:, :>); write (out, cause, "nl", 1); if fp_mode then goto after_error else begin setposition(out,0,0); goto next_line; end; end; procedure check_scope; begin for i:= 1 step 1 until 3 do if par(1) = (case i of ( real<:syste:> add 109, real<:proje:> add 99 , real<:user:> )) and par(2) = (case i of ( real<::> , real<:t:> , real<::> )) then scopetype:= i; if scopetype = 0 then writeerror(<:scope must be 'system','project' or 'user':>); end; \f boolean procedure entry_ok(entry,names,entry_found); real array entry,names ; boolean array entry_found ; begin <* this procedure checks a catalogentry according to the call-parameters. *> integer i; boolean ok; real array entryname(1:2); <* check base *> entrybase(1):= entry.iaf(2); entrybase(2):= entry.iaf(3); if base then ok:= extend entrybase(1) >= extend base_lower and extend entrybase(2) <= extend base_upper and entry.iaf(1) extract 3 >= 2 <* min auxcat permkey *> else ok:= extend entrybase(1) = extend base_lower and extend entrybase(2) = extend base_upper and entry.iaf(1) extract 3 = 3; <* permkey *> if ok then begin <* check if entryname match with entrynames in call - if any *> if firstentryname > 0 then begin for i:= 1 step 1 until 4 do entryname.iaf(i):= entry.iaf(i+3); <* get entryname *> ok:= false; for i:= 1,i+1 while i <= no_of_entries and -,ok do if entryname(1) = names(i,1) and entryname(2) = names(i,2) then ok:= entry_found(i):= true; end; end; entry_ok:= ok; end entry_ok; \f procedure initbases; begin integer array iarr(1:8); system(11)catalog bases:(i,iarr); ownbase(1):= iarr(1); ownbase(2):= iarr(2); if -,base then begin base_lower:= (case scopetype of (-8388607,iarr(7),iarr(5))); base_upper:= (case scopetype of (8388605 ,iarr(8),iarr(6))); end; end; \f procedure set_catbase (base); integer array base ; <***********************************************************> <* *> <* The procedure changes the catalog base of own process *> <* to the base given. *> <* If the result becomes 4 : new base illegal, it is sup- *> <* posed that the new base is outside the max base of the *> <* process and the procedure will set cat base to max base.*> <* *> <* Call : set_catbase (entry); *> <* *> <* base (call value, integer array). The new base *> <* in base (1:2). *> <* *> <***********************************************************> begin own boolean called_before; integer i; integer array own_bases (1:8); integer result; integer array field max; zone z (1, 1, stderror); if -,called_before then begin called_before := true; reset_catbase; <*init reset catbase*> end; open (z, 0, <::>, 0); <*own process*> close (z, true); for i := 1, 2 do own_bases (i) := base (i); <*to avoid fielding in call of system*> result := monitor (72, z, 0, own_bases); if result = 4 then begin <*outside max*> max := 12; <*fields max base in own_bases (7:8)*> system (11 )bases:( 0, own_bases); set_catbase (own_bases.max); end <*outside max*> else if result <> 0 then system (9, result, <:<10>cat base:>); end set_catbase; \f procedure reset_catbase; <***********************************************************> <* *> <* The procedure resets the catbase of own process *> <* to the original catbase before the first change *> <* of catbase by a call of set_catbase. *> <* *> <***********************************************************> begin own boolean called_before; own integer catbase_lower, catbase_upper; if -,called_before then begin <*save catbase and init branch*> called_before := true; catbase_lower := ownbase (1); catbase_upper := ownbase (2); reset_catbase; end else begin <*set catbase*> integer array catbase (1:2); catbase (1) := catbase_lower; catbase (2) := catbase_upper; set_catbase (catbase); end <*set catbase*>; end reset_catbase; \f procedure read_base_params; begin integer array iarr(1:8); integer type; type:= 5; <* name or integer *> if next_param(par,paramno,type,false) then begin if type = 4 <* returnvalue - integer *> then begin base_lower:= round par(1); if next_param(par,paramno,4,false) then base_upper:= round par(1) else writeerror(<:upper base is missing:>); if base_upper < base_lower then writeerror(<:'upper-base' is less than 'lower-base':>); end else begin <* returnvalue - text *> basetype:= if par(1) = real<:syste:> add 109 then 1 else if par(1) = real<:proje:> add 99 and par(2) = real<:t:> then 2 else if par(1) = real<:user:> then 3 else 0; if basetype = 0 then writeerror(<:'base' must be 'system','project' or 'user':>) else begin system(11)process bases:(i,iarr); base_lower:= (case basetype of (-8388607,iarr(7),iarr(5)) ); base_upper:= (case basetype of (8388605 ,iarr(8),iarr(6)) ); end; end end else writeerror(<:'base-params' are incomplete:>); end read_base_params; \f procedure call_save(displ); value displ ; integer displ ; begin zone zcat(128,1,caterror); integer k,i,first_slice; integer array core,chain_start(1:1); long array entryname(1:2); real array from_docname(1:2); boolean anywhere,listing,found,head; area:= found:= true; base:= scope:= head:= listing:= checkread:= false; basetype:= firstentryname:= scopetype:= segments:= slices:= entries:= 0; no_of_entries:= 1; paramno:= 1+displ; docname(1):= docname(2):= 0; todevno:= -1; while next_param(par,paramno,1,false) do begin case convert_param(par) of begin begin <* from *> if next_param(par,paramno,2,false) then begin from_docname(1):= docname(1):= par(1); from_docname(2):= docname(2):= par(2); end else write_error(<:no document-name :>); end; begin <* to *> if next_param(par,paramno,4,false) then todevno:= round par(1) else write_error(<:no device-number:>); end; begin <* scope *> scope:= true; if todevno < 0 then writeerror(<:to.<devno> must be specified before scope:>); if next_param(par,paramno,2,false) then check_scope else writeerror(<:'scope'-parameters are incomplete:>); end; begin <* base *> base:= true; if todevno < 0 then writeerror(<:to.<devno> must be specified before base:>); read_base_params; end; begin <* list *> if next_param(par,paramno,2,false) then begin if par(1) <> real<:no:> and par(1) <> real<:yes:> then writeerror(<:listoption must be 'yes' or 'no':>) else listing:= par(1) = real<:yes:>; end else writeerror(<:no listoption:>); end; begin <* checkread *> set_checkread; end; begin <* entrynames *> if todevno < 0 then writeerror(<:to.<devno> must be specified before entrynames:>) else begin firstentryname:= paramno-1; no_of_entries:= 1; while next_param(par,paramno,1,false) do no_of_entries:= no_of_entries+1; end end entrynames; end case; end while-loop; begin real array names(1:no_of_entries,1:2); boolean array entry_found(1:no_of_entries); if todevno < 0 then writeerror(<:to.<devno> must be specified :>); if firstentryname > 0 then begin paramno:= firstentryname; for i:= 1 step 1 until no_of_entries do begin next_param(par,paramno,1,false); names(i,1):= par(1); names(i,2):= par(2); entry_found(i):= false; end; end; if -,base and -,scope then scopetype:= 1; <* default scope.system *> anywhere:= docname(1) = 0; if -,anywhere then begin if get_dev_or_name(true,devno,docname,auxname,chain_addr) then writeerror(<:source disc does not exist:>); end; kiton(todevno,docname,1,true,true); <* include to-device *> for i:= 1 step 1 until 4 do ia(17+i):= docname.iaf(i); initbases; i:= 1; if listing then write(out,<:<12><10>entries saved on :>, string act_docname(increase(i)),<::<10><10>:>, <:entryname :>, <:size lower-base upper-base:>); i:= 1; open(zcat,4,if anywhere then <:catalog:> else string auxname(increase(i)),1 shift 18); comment scan catalog ( auxiliary or maincat ); for i:= inrec6(zcat,34) while i > 0 do begin <* check entry *> if zcat.iaf(1) <> -1 <* used catalog entry *> then begin fromname(1):= zcat.areaname(1); fromname(2):= zcat.areaname(2); if entry_ok(zcat,names,entry_found) then begin <* entry ok - try to save it *> zone z(1,1,stderror); set_catbase (entry_base); i:= 1; open(z,0,string fromname(increase(i)),0); monitor(76)head and tail:(z,0,ia); close(z,false); reset_catbase; if -,anywhere then begin <* the entry is checked to be ok so far - check if *> <* correct document *> first_slice:= ia(1) shift (-12) extract 12; if first_slice >= 2048 <* non area entry *> then begin <* compute chain table address *> system(5,92,core); system(5,core(1) + (first_slice - 2048),chain_start); found:= chain_start(1) = chain_addr; end else found:= from_docname.iaf(1) = ia(9) and from_docname.iaf(2) = ia(10) and from_docname.iaf(3) = ia(11) and from_docname.iaf(4) = ia(12); end; if found then begin open(z,0,<::>,0); set_catbase (entry_base); k:= monitor(120)create aux entry:(z,0,ia); reset_catbase; if k <> 0 then begin if k = 3 <* nameoverlap *> then begin i:= 1; write(out,<:<10>entry already exists in auxcat ::>, string fromname(increase(i)) ); if -,fp_mode then setposition(out,0,0) else errorbits := 1 shift 1; <*warning.yes ok.yes*> end else begin close (zcat, true); kitoff (docname); dump_actual_names (to_devno); result(120, <::>, fromname,k,true); end; end else begin entries:= entries+1; if listing then list_entry(zcat,0); set_catbase (entry_base); if ia(8) > 0 <* area describing entry *> then begin close(z,false); getzone(z,zdescr); for i:= 2 step 1 until 5 do toname.iaf(i-1):=zdescr(i); copyarea(0,0,maximum); segments := segments + ia (8); <*size*> slices := slices + (ia (8) - 1) // slicelength + 1; end else begin <* remove area process *> close(z,true); monitor(64)remove process:(z,0,ia); end; reset_catbase; end; end; end; end; end while_loop; close(zdisc,true); close(zcat,true); kitoff(docname); dump_actual_names(todevno); if entries > 0 then begin write(out,<:<10><10>:>,<<dddd>,entries,<: entries, :>, <<dddddddd>,segments,<: segments<10>:>,<<dddd>, slices,<: slices *:>,slicelength,<: =:>,<<ddddd>, slices*slicelength,<: segments<10><10>:>); if -,fp_mode then setposition(out,0,0); end; if firstentryname > 0 then begin <* check if all entries are saved *> for i:= 1 step 1 until no_of_entries do if -,entry_found(i) then begin if -,head then begin write(out,<:<10>***entries not found :<10>:>); errorbits := 1 shift 1; <*warning.yes, ok.yes*> head:= true; j:= 0; end; entryname(1):= long names(i,1); entryname(2):= long names(i,2); j:= j + write(out,false add 32,2,entryname); if j > 65 then begin j:= 0; typetext(<:<10>:>) end; end; typetext(<:<10>:>); end; end; end call_save; \f procedure call_load(displ); value displ ; integer displ ; begin integer array tail(1:10),core,chain_start(1:1); long array entryname(1:2); real array wrkname,name,fromkitname,old_docname(1:2); integer i,k,pos1,pos2,first_slice,act_chain_addr; boolean listing,head,ok; zone zwrk,z(1,1,stderror),zcat(128,1,caterror); basetype:= scopetype:= segments:= slices:= entries:= 0; area:= true; base:= scope:= head:= listing:= checkread:= false; firstentryname:= 0; no_of_entries:= 1; paramno:= 1+displ; docname(1):= docname(2):= 0; fromdevno:= -1; while next_param(par,paramno,1,false) do begin case convert_param(par) of begin begin <* from *> if next_param(par,paramno,4,false) then fromdevno:= round par(1) else writeerror(<:no 'from'-devicenumber:>); end; begin <* to *> if next_param(par,paramno,2,false) then begin docname(1):= par(1); docname(2):= par(2); end else writeerror(<:no 'to'-documentname:>); end; begin <* scope *> scope:= true; if docname(1) = 0 then writeerror(<:to.<docname> must be specified before scope:>) else if fromdevno < 0 then writeerror(<:from.<devno> must be specified before scope:>) else begin if next_param(par,paramno,2,false) then check_scope else writeerror(<:'scope'_parameters are incomplete:>); end; end; begin <* base *> base:= true; if docname(1) = 0 then writeerror(<:to.<docname> must be specified before base :>) else if fromdevno < 0 then writeerror(<:from.<devno> must be specified before base :>) else read_base_params; end; begin <* list *> if next_param(par,paramno,2,false) then begin if par(1) <> real<:no:> and par(1) <> real<:yes:> then writeerror(<:listoption must be 'yes' or 'no':>) else listing:= par(1) = real<:yes:>; end else writeerror(<:no listoption :>); end; begin <* checkread *> set_checkread; end; begin <* entrynames *> if docname(1) = 0 then writeerror(<:to.<docname> must be specified before entrynames:>) else if fromdevno < 0 then writeerror(<:from.<devno> must be specified before entrynames:>) else begin firstentryname:= paramno-1; no_of_entries:= 1; while next_param(par,paramno,1,false) do no_of_entries:= no_of_entries+1; end end entrynames; end case; end while-loop; begin real array names(1:no_of_entries,1:2); boolean array entry_found(1:no_of_entries); for i:= 1 step 1 until no_of_entries do entry_found(i):= false; if docname(1) = 0 or fromdevno < 0 then writeerror(<:from.<devno> and to.<docname> must be specified:>); if firstentryname > 0 then begin paramno:= firstentryname; for i:= 1 step 1 until no_of_entries do begin next_param(par,paramno,1,false); names(i,1):= par(1); names(i,2):= par(2); end; end; if -,base and -,scope then scopetype:= 1; <* default scope.system *> if get_dev_or_name(true,devno,docname,auxname,act_chain_addr) then writeerror(<:object disc not included in bs-system:>); initbases; kiton(fromdevno,fromkitname,1,false,true); <* entries are not inserted *> <* get name of auxcat *> get_dev_or_name(true,fromdevno,fromkitname,auxname,chain_addr); i:= 1; if listing then write(out,<:<12><10>entries loaded to :>, string docname(increase(i)),<::<10><10>:>, <:entryname :>, <:size lower-base upper-base:>); i:= 1; open(zcat,4,string auxname(increase(i)),1 shift 18); comment scan auxiliary catalog; inrec_entry: for i:= inrec6(zcat,34) while i > 0 do begin if zcat.iaf(1) <> -1 then begin if entry_ok(zcat,names,entry_found) then begin <* entry ok - load it *> toname(1):= zcat.areaname(1); toname(2):= zcat.areaname(2); set_catbase (entry_base); monitor(68)generate wrkname:(zwrk,0,entrybase); getzone(zwrk,zdescr); for j:= 2 step 1 until 5 do begin <* insert wrknames *> old_docname.iaf(j-1):= zcat.iaf(j+7); zcat.areaname.iaf(j-1):= fromname.iaf(j-1):= zdescr(j); zcat.iaf(j+7):= fromkitname.iaf(j-1); end; <* insert entry with workname *> k:= monitor(104)insert entry:(zdisc,0,zcat.iaf); reset_catbase; if k <> 0 then begin if k = 6 <* claims exceeded *> then begin <* remove entries inserted with wrknames *> getposition(zcat,pos1,pos2); close(zcat,true); close(zdisc,true); kitoff(fromkitname); kiton(fromdevno,fromkitname,1,false,true); get_dev_or_name(true,fromdevno,fromkitname,auxname,chain_addr); j:= 1; open(zcat,4,string auxname(increase(j)),1 shift 18); setposition(zcat,pos1,pos2); goto inrec_entry; end else begin close (zcat, true); kitoff (from_kitname); result(104, <::>, toname,k,true); end; end; for j:= 1 step 1 until 10 do tail(j):= zcat.iaf(j+7); j:= 1; open(z,0,string toname(increase(j)),0); set_catbase (entry_base); if monitor(76)head and tail:(z,0,ia) = 0 and extend ia(2) = extend entrybase(1) and extend ia(3) = extend entrybase(2) then begin <* entry included - change it if correct document *> reset_catbase; first_slice:= ia(1) shift (-12) extract 12; if first_slice >= 2048 <* non area entry *> then begin <* compute chain table address *> system(5,92,core); system(5,core(1) + (first_slice-2048),chain_start); ok:= chain_start(1) = act_chain_addr; if ok then for j:= 1 step 1 until 4 do tail(j+1):= old_docname.iaf(j); <* insert correct document *> end else ok:= ia(9) = docname.iaf(1) and ia(10) = docname.iaf(2) and ia(11) = docname.iaf(3) and ia(12) = docname.iaf(4); if ok then begin set_catbase (entry_base); monitor (44) change entry :(z, 0, tail); reset_catbase; end else begin close (z, false); j:= 1; write(out,<:<10>entry already included from another document : :>, string toname(increase(j)) ); if -,fp_mode then setposition(out,0,0) else errorbits := 1 shift 1; <*warning.yes, ok.yes*> goto inrec_entry; end; end else begin <* entry does not exist - create on document specified *> reset_catbase; for j:= 1 step 1 until 4 do tail(j+1):= if zcat.iaf(8) < 0 then old_docname.iaf(j) else docname.iaf(j); set_catbase (entry_base); j:= monitor(40)create entry:(z,0,tail); reset_catbase; if j <> 0 then begin close (zcat, true); kitoff (from_kitname); result(40, <::>, toname,j,true); end; set_catbase (entry_base); j:= monitor(90)perm into auxcat:(z,3,docname.iaf); reset_catbase; if j <> 0 then begin close (zcat, true); kitoff (from_kitname); result(90, <::>, toname,j,true); end; end; if listing then begin for j:= 1 step 1 until 4 do zcat.areaname.iaf(j):= toname.iaf(j); listentry(zcat,0); end; set_catbase (entry_base); if zcat.iaf(8) > 0 <* area describing entry *> then begin copyarea(0,0,maximum); segments := segments + zcat.iaf (8); end; entries := entries + 1; close(z,true); reset_catbase; end; end; end while_loop; close(zdisc,true); close (zcat,true); kitoff(fromkitname); if entries > 0 then begin write(out,<:<10><10>:>,<<dddd>,entries,<: entries, :>, <<dddddddd>,segments,<: segments<10>:>); if -,fp_mode then setposition(out,0,0); end; if firstentryname > 0 then begin <* check if all entries are loaded *> for i:= 1 step 1 until no_of_entries do if -,entry_found(i) then begin if -,head then begin write(out,<:<10>***entries not found:<10>:>); errorbits := 1 shift 1; <*warning.yes, ok.yes*> head:= true; j:= 0; end; entryname(1):= long names(i,1); entryname(2):= long names(i,2); j:= j + write(out,false add 32,2,entryname); if j > 65 then begin j:= 0; typetext(<:<10>:>) end; end; typetext(<:<10>:>); end; end; end call_load; \f procedure call_bin(displ); value displ ; integer displ ; begin boolean all,all_from,all_to; integer no_of_devices,physical_disc__addr,i, maincatdev, mainautodev; integer array core(1:2), main (1:1), proc (1:30); real array main_name, mainautoname (1:2); long array field laf; all_from:= all_to:= all:= area:= checkread:= false; todevno:= fromdevno:= -1; laf := 0; paramno:= displ + 1; if -,next_param(par,paramno,1,false) then begin <* no parameters - copy specified parts of discpacks *> call_spec; goto if fp_mode then endprogram else nextline; end else paramno:= paramno-1; while next_param(par,paramno,1,false) do begin case convert_param(par) of begin begin <* from *> next_param(par,paramno,4,false); fromdevno:= round par(1); par(1):= real<:all:>; par(2):= real<::>; <* all-param is optional *> if next_param(par,paramno,2,true) then all:= all_from:= true; end; begin <* to *> next_param(par,paramno,4,false); todevno:= round par(1); par(1):= real <:all:>; <* all-param is optional *> par(2):= real<::>; if next_param(par,paramno,2,true) then all:= all_to:= true; end;;;; begin <* checkread *> set_checkread; end; begin i:= 1; write(out,<:illegal parameter : :>,string par(increase(i))); if fp_mode then goto after_error else begin setposition(out,0,0); goto nextline; end; end; end case; end while-loop; if todevno < 0 or fromdevno < 0 then writeerror(<:to.<devno> and from.<devno> must be specified:>); system (5) move core :( 98, core); <*chaintable maincatdev*> system (5) move core :(core (1) - 10, core); <*name table address *> system (5) move core :(core (1) , core); <*proc descr address *> system (5) move core :(core (1) + 2, main_name); <*proc name *> system (5) move core :(core (1) + 10, main ); <*main process *> maincatdev := device_number (core (1)); <*device number*> system(5)move core area:(74,core); no_of_devices:= (core(2) - core(1))//2 ; begin integer array device_addr(0:no_of_devices - 1); boolean array remember (0 : no_of_devices - 1); boolean error, maincatdev_wr_enabled; integer array field iff; iff := -2; for i := 0 step 1 until no_of_devices - 1 do begin remember (i) := false; j := process_description (i, proc); if (proc ( 1) = 62 or proc ( 1) = 6) and proc ( 6) = main (1) and proc (15) = 0 <*first segment*> then begin <*autoload disc on same physical as maincat disc*> main_auto_dev := i; system (5) move core :(j + 2, main_auto_name); end; end; error := maincatdev_wr_enabled := false; <*decide whether or not to be copied from or to physical disc *> system(5)move core area:(core(1),device_addr.iff); <*get physical source disc*> physical_disc_addr := deviceaddr (fromdevno); system (5) move core :(deviceaddr (fromdevno), ia); if ia (1) = 6 then system (5) move core :(ia (6), main); <*get main*> if ia (1) = 62 <*disc not ida*> and ia (6) = 0 <*no main *> or ia (1) = 6 <*disc ida*> and main (1) = 20 <*main is ida*> then begin <*from device is itself a physical disc*> physical_disc_addr := device_addr (fromdevno); all := all_from := true; end else if ia (1) = 62 <*disc not ida*> and ia (6) > 0 <*has a main *> or ia (1) = 6 <*disc ida*> and main (1) = 6 <*main is ida*> then physical_disc_addr := ia (6); <*main*> if all_from then begin <*get dev no of physical disc*> for devno := 0 step 1 until no_of_devices - 1 do if device_addr (devno) = physical_disc_addr then begin from_devno := devno; devno := noofdevices; end; system (5) move core :(physical_disc_addr, ia); if ia (1) = 6 then begin <*ida, pack it off*> trap (on_again); packoff (fromdevno, false) <*no power down*> end else begin <*not ida*> for devno := 0 step 1 until no_of_devices - 1 do begin <*kitoff logical discs on the physical*> system (5) move core :(deviceaddr (devno), ia); if (ia (1) = 62 <*disc not ida*> or ia (1) = 6 <*disc ida*>) and ia (6) = physical_disc_addr then begin if -,getdevorname (false, devno, docname, auxname, chainaddr) then begin if -,kitoff ( docname) then begin write (out, "nl", 1, true, 12, docname.laf, <: dismounted from :>, <<ddd>, devno); typetext (<:<10>:>); trap (on_again); remember (devno) := true; end; end; end; end <*kitoff*>; end <*not ida*>; end <*get device number of physical source disc*>; <*get physical object disc*> system (5) move core :(deviceaddr (todevno), ia); if ia (1) = 6 then system (5) move core :(ia (6), main); if ia (1) = 62 <*disc not ida*> and ia (6) = 0 <*has no main*> or ia (1) = 6 <*disc ida*> and main (1) = 20 <*main is ida*> then begin <*to device is itselt a physical disc*> physical_disc_addr := device_addr (todevno); all := all_to := true; end else if ia (1) = 62 <*disc not ida*> and ia (6) > 0 <*has a main *> or ia (1) = 6 <*disc ida*> and main (1) = 6 <*has a main *> then physical_disc_addr := ia (6); if all_to then begin <*get device no of physical disc*> for devno := 0 step 1 until no_of_devices - 1 do if deviceaddr (devno) = physical_disc_addr then begin todevno := devno; devno := noofdevices; end; end <*get*>; if all then begin write(out,<:<10>source disc: :>,fromdevno, <:<10>object disc: :>,todevno,<:<10>:>); if -,fp_mode then setposition(out,0,0); end; toname (1) := 0; if connect (todevno, toname) then type_text (<:<10>object disc not connected<10>:>) else begin <*todev connected*> if -,get_dev_or_name (false, fromdevno, docname, auxname, chainaddr) then begin if -,kitoff (docname) then begin write (out, "nl", 1, true, 12, docname.laf, <: dismounted from :>, <<ddd>, fromdevno); typetext (<:<10>:>); trap (on_again); remember (fromdevno) := true; end; end; fromname (1) := 0; if connect (fromdevno, fromname) then type_text (<:<10>source disc not connected<10>:>) else begin <*fromdev connected*> copyarea (0, 0, maximum); write (out, "nl", 1, <:copying terminated:>, "nl", 1, <:number of segments copied : :>, <<ddddddd>, totalsegments); typetext (<:<10>:>); end <*fromdev connected*>; end <*todev connected*>; on_again: trap (0); <*check if disc with maincat is wr enabled*> maincatdev_wr_enabled := if mainautoname (1) shift (-24) extract 24 = 0 then -,connect (mainautodev, mainautoname) else true; if maincatdev_wr_enabled then begin <*connectable*> zone z (128, 1, check_malfnc); procedure check_malfnc (z, s, b); zone z ; integer s, b ; begin if s extract 1 = 1 then stderror (z, s, b) else begin maincatdev_wr_enabled := false; b := 512; s := 0; end; end check_malfnc; laf := 0; open (z, 6, main_auto_name.laf, 60); <*dummy answer*> monitor (8) reserve :(z, 1, core); maincatdev_wr_enabled := true; inrec_6 (z, 512); setposition (z, 0, 0); outrec6 (z, 512); close (z, true); <*release process*> end <*connectable*>; if -,maincatdev_wr_enabled then write (out, "nl", 1, <:notice : disc with main catalog disconnected or write protected:>) else if all_from then begin <*if ida then packon again*> system (5) move core :(device_addr (from_devno), ia); if ia (1) = 6 <*ida disc*> then pack_on (from_devno, false, 5); <*no power up, list.warning*> end; if remember (maincatdev) or main_cat_rem then begin <*write enabled and dismounted*> kiton (maincatdev, docname, 4 <*list error*>, true <*insert bs*>, false <*wrk name*>); for i := 1 step 1 until 4 do ia (17 + i) := docname.iaf (i); i := monitor (106) insert bs :(out, 0, ia); if i <> 0 then result (106, <::>, docname, i, false); remember (maincatdev) := false; write (out, "nl", 1, true, 12, docname.laf, if i <> 0 then <: not:> else <::>, <: mounted on :>, <<ddd>, maincatdev); end <*write enabled and dismounted*>; typetext (<:<10>:>); if maincatdev_wr_enabled then begin <*kit on discs previously kitted of*> for devno := 0 step 1 until no_of_devices - 1 do if remember (devno) then begin kiton (devno, docname, 4 <*list error*>, true <*insert entries*>, false <*wrk name*>); for i := 1 step 1 until 4 do ia (17 + i) := docname.iaf (i); i := monitor (106) insert bs :(out, 0, ia); if i <> 0 then result (106, <::>, docname, i, false); remember (devno) := false; write (out, "nl", 1, true, 12, docname.laf, if i <> 0 then <: not:> else <::>, <: mounted on :>, <<ddd>, devno); typetext (<:<10>:>); end; end <*kit on discs previously kitted off*>; if error then goto if fpmode then aftererror else nextline; end; end call_bin; \f procedure call_kiton; begin integer list,k; long array field laf; zone z(1,1,stderror); list:= 5; <*list.warning as default*> laf := 0; paramno:= 1; if next_param(par,paramno,1,false) then begin if par(1) = real <:devno:> then begin if next_param(par,paramno,4,false) then devno:= round par(1) else writeerror(<:device-number is missing:>); end else writeerror(<:first parameter must be devno.<devno> :>); end else writeerror(<:no parameters:>); if next_param(par,paramno,1,false) then begin if par(1) = real<:list:> then begin if next_param(par,paramno,2,false) then begin if par(1) = real<:no:> then else if par(1) = real<:yes:> then list:= 2 else if par(1) = real<:nonsy:> add 115 then list:= 3 else if par(1) = real<:error:> then list:= 4 else if par(1) = real<:warni:> add 110 and par(2) = real<:g:> then list:= 5 else writeerror(<:illegal list-option :>); end else writeerror(<:listoption is missing:>); end else begin i:= 1; write(out,<:unknown parameter : :>,string par(increase(i))); if fp_mode then goto after_error else begin setposition(out,0,0); goto next_line; end; end; end; kiton(devno,fromname,list,true,false); for i:= 1 step 1 until 4 do ia(17+i):= fromname.iaf(i); k:= monitor(106)insert bs:(z,0,ia); if k <> 0 then result(106, <::>, fromname,k, false); write(out,"nl", 2, true, 12, fromname.laf, if k <> 0 then <: not:> else <::>, <: mounted on :>,<<ddd>,devno,<:<10>:>); if -,fp_mode then setposition(out,0,0); end call_kiton; \f procedure call_kitoff; begin long array field laf; laf := 0; paramno:= 1; if next_param(par,paramno,1,false) then begin if par(1) = real<:devno:> then begin if next_param(par,paramno,4,false) then devno:= round par(1) else writeerror(<:device-number is missing:>); end else writeerror(<:first parameter must be devno.<devno>:>); end else writeerror(<:no parameters:>); if -,get_dev_or_name(false,devno,docname,auxname,chain_addr) then begin if -,kitoff (docname) then begin write (out, "nl", 1, true, 12, docname.laf, <: dismounted from :>, <<ddd>, devno); typetext (<:<10>:>); end; end; end call_kitoff; \f procedure mount_disc; begin integer list; list:= 5; <*list.warning as default*> paramno:= 1; if next_param(par,paramno,1,false) then begin if par(1) = real <:devno:> then begin if next_param(par,paramno,4,false) then devno:= round par(1) else writeerror(<:device-number is missing:>); end else writeerror(<:first parameter must be devno.<devno> :>); end else writeerror(<:no parameters:>); if next_param(par,paramno,1,false) then begin if par(1) = real<:list:> then begin if next_param(par,paramno,2,false) then begin if par(1) = real<:no:> then else if par(1) = real<:yes:> then list:= 2 else if par(1) = real<:nonsy:> add 115 then list:= 3 else if par(1) = real<:error:> then list:= 4 else if par(1) = real<:warni:> add 110 and par(2) = real<:g:> then list:= 5 else writeerror(<:illegal list-option :>); end else writeerror(<:listoption is missing:>); end else begin i:= 1; write(out,<:unknown parameter : :>,string par(increase(i))); if fp_mode then goto after_error else begin setposition(out,0,0); goto next_line; end; end; end; pack_on (devno, true, list); <*power up*> end procedure mount_disc; procedure pack_on (devno, power_up, list); value devno ; integer devno, list ; boolean power_up ; begin integer k, disc_count, disc_descr_size, disc; integer first_segment, segments, type, log_devno; integer array field log_entry; long array field laf; integer field count_f; integer array field iaf; real array field raf; real array za (1:128); zone z(128,1,stderror); laf := 0; process_description (devno, ia); if ia(1)<>6 then begin writeerror (<:not connected or not ida disc:>); end; raf:= 2; iaf:= 0; tofrom (docname, ia.raf, 8); if ia(8) shift (-12) <> 0 then write_error (<:not physical disc:>); if docname.iaf(1) = 0 then begin if connect (devno, docname) then begin if fp_mode then goto after_error else goto next_line; end; end; open (z, 0, docname, 0); if power_up then begin monitor (8, z, i, ia); getshare6 (z, shdescr, 1); for i:= 4 step 1 until 7 do shdescr(i):= 0; shdescr(4):= 10 shift 12 + 0; <* power up spindle *> setshare6 (z, shdescr, 1); i:= 1; monitor (16, z, i, ia); <* send message *> i := monitor (18, z, i, shdescr); <* wait answer *> monitor (10, z, 0, ia); if i<>1 then result(-1, <:power up spindle:>, docname, i, true); end; setposition (z, 0, 0); inrec6 (z, 512); tofrom (za, z, 512); close (z, false); process_description (devno, ia); system (5, ia(6), ia); tofrom (docname, ia.raf, 8); open (z, 0, docname, 0); count_f := 2; <* files in autoload description *> count_f := (za.count_f*4) + 4; <* logical disc files *> disc_descr_size := za.count_f shift (-12) extract 12; disc_count := za.count_f extract 12; log_entry:= count_f; for disc:= 1 step 1 until disc_count do begin comment linkup logical discs; first_segment:= za.log_entry(1); segments:= za.log_entry(2); type:= za.log_entry(3) shift (-12); log_devno:= za.log_entry(3) extract 12; getshare6 (z, shdescr, 1); shdescr(4):= 16 shift 12 + (type extract 1); <* link logical disc *> shdescr(5):= log_devno; shdescr(6):= devno; shdescr(7):= first_segment; shdescr(8):= segments; setshare6 (z, shdescr, 1); i:= 1; monitor(16, z, i, ia); i:= monitor(18, z, i, ia); if i<>1 then begin write (out, <:<10>linkup logical disc, devno=:>, << dd>, log_devno, <:, on device=:>, devno, <:, result=:>, i); if fp_mode then goto after_error else begin setposition (out, 0, 0); goto next_line; end; end; log_devno:= ia(2); if type shift (-1) = 1 then begin comment catalog on disc; kiton(log_devno,fromname,list,true,false); for i:= 1 step 1 until 4 do ia(17+i):= fromname.iaf(i); k:= monitor(106)insert bs:(z,0,ia); if k <> 0 then result(106, <::>, fromname,k, false); write (out, "nl", 2, true, 12, fromname.laf, if k <> 0 then <: not:> else <::>, <: mounted on :>, <<ddd>, logdevno); typetext (<:<10>:>); end else begin comment disc has no katalog; real array docname (1:2); docname(1):= real<::>; if connect (log_devno, docname) then begin if fp_mode then goto after_error else begin setposition (out, 0, 0); goto next_line; end; end; write (out, "nl", 1, true, 12, docname.laf, <: mounted on :>, <<ddd>, logdevno); typetext (<: - no auxcat -<10>:>); if -, fp_mode then setposition (out, 0, 0); end; log_entry:= log_entry + disc_descr_size; end; close (z, false); if -,fp_mode then setposition(out,0,0); end pack_on; \f procedure remove_disc; begin paramno:= 1; if next_param(par,paramno,1,false) then begin if par(1) = real<:devno:> then begin if next_param(par,paramno,4,false) then devno:= round par(1) else writeerror(<:device-number is missing:>); end else writeerror(<:first parameter must be devno.<devno>:>); end else writeerror(<:no parameters:>); pack_off (devno, true); <*power down*> end procedure remove_disc; procedure pack_off (devno, power_down); value devno ; integer devno ; boolean power_down ; begin integer log_devno, next_logical, log_disc; long array field laf; integer array field iaf; real array field raf; zone z (1, 1, stderror); laf := 0; next_logical:= process_description (devno, ia)+22; if ia(1)<>6 then write_error (<:not connected or not ida disc:>); if ia(8) shift (-12)<>0 then write_error (<:not physical disc:>); system (5, ia(6), ia); raf:= 2;iaf:= 0; tofrom (docname, ia.raf, 8); open (z, 0, docname, 0); system (5, next_logical, ia); log_disc:= ia(1); close (z, false); while log_disc > 0 do begin system (5, log_disc, ia); tofrom (docname, ia.raf, 8); log_devno:= device_number (log_disc); if ia(8) shift (-13) extract 11 = 1 then begin if -,kitoff (docname) then begin write (out, "nl", 1, true, 12, docname.laf, <: dismounted from :>, <<ddd>, logdevno); typetext (<:<10>:>); end; end; getshare6 (z, shdescr, 1); for i:= 4 step 1 until 8 do shdescr(i):= 0; shdescr(4):= 18 shift 12 + 0; <* unlink logical disc *> shdescr(5):= log_devno; setshare6 (z, shdescr, 1); i:=1; monitor (16, z, i, shdescr); i:= monitor (18, z, i, ia); if i<>1 then begin result (-1, <:unlink logical disc:>, docname, i, false); end; system (5, next_logical, ia); log_disc:= ia(1); end; process_description (devno, ia); tofrom (docname, ia.raf, 8); if docname.iaf(1)=0 then connect (devno, docname); if power_down then begin open (z, 0, docname, 0); close (z, false); monitor (8, z, i, ia); getshare6 (z, shdescr, 1); for i:= 4 step 1 until 5 do shdescr(i):= 0; shdescr(4):= 12 shift 12 + 0; <* power down spindle *> setshare6 (z, shdescr, 1); i:= 1; monitor (16, z, i, ia); i:= monitor (18, z, i, ia); if i<>1 then result (-1, <:power down spindle:>, docname, i, false); monitor (10, z, 1, ia); end <*power down*>; end pack_off; \f procedure call_kitlabel; begin integer field devno,catsize,slicelength,size,catfirst,catlast, lastslice,i,segm; boolean field slicerel; integer kind; integer array ia(1:1); long array name,auxname(1:2); zone disc(128,1,stderror); procedure discerror(z,s,b); zone z; integer s,b; begin own boolean aftererror; if aftererror then stderror(z,s,b); aftererror:= true; goto again; end; paramno:= 1; if next_param(par,paramno,3,false) then begin devno:= round par(1); <* devicenumber *> if next_param(par,paramno,1,false) then begin name(1):= long par(1); name(2):= long par(2) shift (-8) shift 8; <* max 11 chars *> end else writeerror(<:no documentname:>); if next_param(par,paramno,1,false) then begin auxname(1):= long par(1); auxname(2):= long par(2) shift (-8) shift 8 ; <* max 11 chars *> end else writeerror(<:no auxcat-name:>); end else writeerror(<:no device-number:>); next_param(par,paramno,1,false); if par(1) = real<:slow:> then kind:= 1 else if par(1) = real<:fast:> then kind:= 0 else writeerror(<:kind must be 'slow' or 'fast':>); for i:= 1 step 1 until 3 do begin if next_param(par,paramno,3,false) then begin case i of begin catsize:= round par(1); slicelength:= round par(1); size:= round par(1); end; end else case i of begin writeerror(<:catsize-param is missing:>); writeerror(<:slicelength-param is missing:>); writeerror(<:size-param is missing:>); end; end for-loop; again: <* compute first, last slice of aux cat *> catfirst := (( 34 <* size of chainhead *> + size <* size of chaintable *> + 511) // 512 <* counted in segments *> + slicelength - 1 <* round up *> ) // slicelength; catlast := catfirst + (catsize - 1) // slicelength; <* compute last slicenumber of disc *> lastslice:= size - 1; open(disc, 0, <::>, 0); <* create peripheral process, wrk-name *> monitor(54, disc, devno, ia); <* reserve process *> monitor(8 , disc, 0 , ia); <* prepare chainhead *> outrec6(disc, 34); for i := 2 step 2 until 34 do disc.i := case i shift (-1) of (catfirst shift 12 +kind shift 3 + 3<*1st catslice,kind*8+key*> , -8388607 <* lower catalog interval *> , 8388606 <* upper catalog interval *> , auxname.iaf(1) <* auxcat name *> , auxname.iaf(2) , auxname.iaf(3) , auxname.iaf(4) , catsize <* size of auxcat *> , name.iaf(1) <* document name *> , name.iaf(2) , name.iaf(3) , name.iaf(4) , 0 <* not used *> , slicelength , lastslice shift 12 + 0 <* last slice of disc, first of chain*> , (-1) shift 12 + 0 <* auxcat, zero *> , 0 <* zero, zero *> ); <* initialize chain for chaintable + auxcat *> outrec6(disc, outrec6(disc, 0)); for slicerel := 1 step 1 until catlast do disc.slicerel := false add 1; disc.slicerel := false; <* clear space between cahintable and catalog *> outrec6(disc, 0); <* change buffer *> getposition(disc, 0, segm); for segm := segm step 1 until catfirst * slicelength - 1 do outrec6(disc, 512); <* write empty auxcat *> setposition(disc, 0, catfirst * slicelength); for segm := 1 step 1 until catsize do begin outrec6(disc, 512); for i := 2 step 2 until 510 do disc.i := -1; <* unused catalog entries *> disc.i := 0; <* entry count *> end; <* terminate last block and release disc *> close(disc, true); goto if fp_mode then endprogram else nextline; end call_kitlabel; \f procedure call_kitname; begin <* rename document and auxiliary catalog *> paramno := 1; if next_param(par,paramno,3,false) then devno:= round par(1) else writeerror(<: devicenumber is missing :>); if next_param(par,paramno,1,false) then begin actdocname(1):= par(1); actdocname(2):= par(2); end else writeerror(<:documentname is missing:>); if next_param(par,paramno,1,false) then begin actauxname(1):= par(1); actauxname(2):= par(2); end else writeerror(<:auxcatname is missing:>); if -,get_dev_or_name(false,devno,docname,auxname,chain_addr) then kitoff(docname); dump_actual_names(devno); end call_name; \f procedure call_spec; begin <* used for copying specified parts of devices *> typetext(<:to device: :>); typein(todevno); typetext(<:start segment: :>); typein(tosegm); typetext(<:from device: :>); typein(fromdevno); typetext(<:start segment: :>); typein(fromsegm); typetext(<:number of segments: :>); typein(number_of_segments); if -,get_dev_or_name(false,todevno,toname,auxname,chain_addr) then kitoff(toname); if -,get_dev_or_name(false,fromdevno,fromname,auxname,chain_addr) then kitoff(fromname); toname(1):= 0; connect(todevno,toname); fromname(1):= 0; connect(fromdevno,fromname); copyarea(tosegm,fromsegm,extend number_of_segments); write(out,<:<10>copying terminated<10>:>, <:number of segments copied: :>,<<ddddddd>, totalsegments-(if shdescr(4) shift (-12) = 3 <* input *> then fromsegm else tosegm) ); typetext(<:<10>:>); end; procedure set_checkread; begin if next_param (par, paramno, 2, false) then begin if par (1) = real <:yes:> or par (1) = real <:no:> then checkread := par (1) = real <:yes:> else write_error (<:checkread option must be 'yes' or 'no':>) end else write_error (<:checkread.yes or checkread.no:>); end set_checkread; \f <* m a i n p r o g r a m *> open(zhelp,0,<::>,0); trapmode:= 0; <* write all alarms *> trap(after_error); maximum:= 10 000 000; maincat_rem:= false; area:= false; areaname:= 6; ok:= false; iaf:= 0; permkey:= 3; scopetype:= 0; scope:= base:= false; space_name:= 4 shift 12 + 10; point_name:= 8 shift 12 + 10; space_integer:= 4 shift 12 + 4; point_integer:= 8 shift 12 + 4; fp_mode:= true; checkread := false; kind(0):= 7; <* delimiter *> ra(0):= 32 ; <* space *> base := true; init_bases; base := false; reset_catbase; <*to initialize reset catbase*> <* decide name of program *> system(4,0,par); tofrom(program,par,8); case convert_to_number(par) of begin begin <* disccopy *> paramno:= 1; next_param(par,paramno,1,false); <* decide action *> type:= convert_to_number(par); if type < 9 then type:= 13; case type-8 of begin call_save(1); call_load(1); call_bin(1) ; begin <* enter conversational mode *> fp_mode:= false; lockall; <* modify standardalphabet *> outtable(alphabet,127); for i:= 39,43,46 do alphabet(i):= 7 shift 12 + i; intable(alphabet); tableindex:= 0; nextline: morelines:= true; start_pos:= 1; while morelines do begin <* read lines of command *> setposition(in,0,0); i:= readall(in,ra,kind,start_pos); if i < 0 then begin <* array bounds exceeded *> write(out,<:<10>command too long - last line skipped<10>:>); if -,fp_mode then setposition(out,0,0); kind(start_pos):= 8; <* terminates inf. in 'ra' and 'kind'*> morelines:= false; end else begin <* check if current line terminates command *> for i:= 0,i+1 while round ra(i) = 32 do; if kind(i) = 8 then goto nextline; <* skip if no command *> for i:= startpos,i+1 while kind(i) <> 8 do; last:= i; ra(last):= 32; kind(last):= 7; for i:= i,i-1 while kind(i) = 7 and round ra(i) = 32 do; if (kind(i) = 7 and round ra(i) = 44) <* comma *> then begin ra(i):= ra(i+1):= 32; <* space *> kind(i):= kind(i+1):= 7; startpos:= i+1; end else begin morelines:= false; kind(last):= 8; end; end; end while_loop; <* start execution of command *> paramno:= 0; next_param(par,paramno,1,false); case convert_to_number(par) of begin <* disccopy ignored *> ; call_kitname; call_kiton; call_kitoff; mount_disc; remove_disc; call_kitlabel; goto endprogram; <* end *> call_save(0); call_load(0); call_bin(0); <* typein ignored *> ; begin <* unknown command *> i:= 1; write(out,<:<10>illegal command : :>, string par(increase(i)),<:<10>:>); if -,fp_mode then setposition(out,0,0); end; end case; close(zdisc,true); goto nextline; end conv_mode; begin <* unknown fpparameter *> i:= 1; write(out,<:<10>***disccopy: unknown fpparameter : :>, string par(increase(i))); goto endprogram; end; end case; end disccopy; call_kitname; call_kiton; call_kitoff; mount_disc; remove_disc; call_kitlabel; <*8*>; <*9*>; <*10*>; <*11*>; <*12*>; write(out,<:<10>unknown program name: :>,program); end case; goto end_program; after_error: errorbits:= 3; <*warning.yes, ok.no*> may_be_device_status (out); endprogram: end; ▶EOF◀