|
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: 67584 (0x10800) Types: TextFile Names: »mprocfnc1 «
└─⟦9ccaf6601⟧ Bits:30008165 Bånd med SW8000 kildetekst/release værktøjer └─⟦2ba378e4a⟧ └─⟦this⟧ »mprocfnc1 «
\f m. monprocfnc1 - monitor process functions, part 1 17.0 beta ;88.05.24 08.40 kak change of cpa and address base included ;89 05 23 09.15 kak remove area changed: main address not cleared ; no result inserted in buffs used by the areaprocess ; a new procedure: find idle area introducted ;89 05 25 08.05 kak - - - : clean area processs - ;89 11 21 15 24 kak an error in find idle area corrected b.i30 w. i0=89 05 25, i1=15 21 00 ; if newtime (i0,i1) > oldtime (a133,a134) then oldtime:=newtime; c.i0-a133 c.i0-a133-1, a133=i0, a134=i1, z. c.i1-a134-1, a134=i1, z. z. i10=i0, i20=i1 i15=i10/100000 , i10=i10-i15*100000 , i25=i20/100000 , i20=i20-i25*100000 i14=i10/10000 , i10=i10-i14*10000 , i24=i20/10000 , i20=i20-i24*10000 i13=i10/1000 , i10=i10-i13*1000 , i23=i20/1000 , i20=i20-i23*1000 i12=i10/100 , i10=i10-i12*100 , i22=i20/100 , i20=i20-i22*100 i11=i10/10 , i10=i10-i11*10 , i21=i20/10 , i20=i20-i21*10 i2: <: date :> (:i15+48:)<16+(:i14+48:)<8+46 (:i13+48:)<16+(:i12+48:)<8+46 (:i11+48:)<16+(:i10+48:)<8+32 (:i25+48:)<16+(:i24+48:)<8+46 (:i23+48:)<16+(:i22+48:)<8+46 (:i21+48:)<16+(:i20+48:)<8+ 0 i3: al. w0 i2. ; write date: rs w0 x2+0 ; first free:=start(text); al w2 0 ; jl x3 ; return to slang(status ok); jl. i3. ; e. j. ; rc date ; rc 4000 systems tape, segment 6: process functions. ; leif svalgaard / jørn jensen ; catalog administration; creation, removal, and ; start and stop of processes. ; the code includes certain test options selected by bits in the identifier ; a92 as follows: ; test call included: a92 = a92 o. 1<19 ; monitor test output: a92 = a92 o. 1<20 ; print w, type w: a92 = a92 o. 1<21 s. c10, d50, e99, f100, i70, j21, l150, m280, n50, p65, r7, t40, v40 c.(:a399>23a.1:)-1 h. 0,r.(:(:(:(:k+2047:)/2048:)*2048:) - k:); (first address:=(first address+2047)//2048)*2048; w. m. 1. address z. b60: ; start of proc func w.b127=k, j21, k=k-2 ; use of slang names: ; a: monitor constants, declared and defined before proc func ; b: monitor absolute entry addresses, - - - - ; c: global full word constants ; d: global variables, start addresses for records ; e: procedures, mostly called with w3 as return register ; f: constant names, relative addresses in records ; g: local labels in procedures and actions ; i: process functions (actions) ; j: global points in central administration, error exits ; ; note: in the comments to the code the notation x.b denotes a reference to the ; variable x in the record b. ; definition of catalog parameters: f0 = a88 ; size of one catalog entry: 34 bytes f9 = 512 - 2 ; catalog buffer size - 2 : 510 bytes f10 = f9/f0 ; number of entries per segment: 15 ;definition of results from check users and reserver f20 = 2.000001 ; internal is user f21 = 2.000010 ; internal is reserver f22 = 2.000100 ; other users f23 = 2.001000 ; another internal is reserver f24 = 2.010000 ; internal has writeprotected f25 = 2.100000 ; other(s) has writeprotected ; definition of proc func communications parameters f14 = 3 ; operation read f15 = 5 ; operation write f16 = 48 ; minimum value of digit in identifier f17 = 57 ; maximum - - - - - f18 = 97 ; minimum - - letter - - f19 = 125 ; maximum - - - - - f37 = 0 ; kind: internal process f38 = 4 ; kind: area process ; definition of bits and values of process states f40 = 1<2 ; repeat bit, in proc state f41 = 1<3 ; no stop bit, in proc state f42 = 1<4 ; parent bit, in proc state f43 = 1<5 ; stopped bit, in proc state f44 = 1<6 ; out of q bit,in proc state f45 = 1<7 ; waiting bit, in proc state ; process state values f46 = a95 ; running f47 = a99 ; waiting start by parent f48 = a97 ; waiting stop by parent f49 = a100 ; waiting start by ancestor f50 = a98 ; waiting stop by ancestor ; note: the above a-names are defined before proc func loading. ; running: out of q, no stop ; waiting start by parent stopped, parent, no stop ; waiting stop by parent stopped, parent ; waiting start by ancestor stopped, no stop ; waiting stop by ancestor stopped ; waiting events repeat ; waiting for proc func repeat, out of q ; ; definition of function keys f71 = 1<10 ; bit 1 : aux catalog handling f72 = 1<9 ; bit 2 : main catalog handling f74 = 1<7 ; bit 4 : create peripheral process f75 = 1<6 ; bit 5 : remove peripheral process f76 = 1<5 ; bit 6 : aux entry handling f77 = 1<4 ; bit 7 : set clock ; definition of itc-process states and mt-document states f80 = 0 ; free f81 = 1 ; during connect f82 = 2 ; connected f83 = 3 ; during disconnect f84 = 4 ; intervention f87 = 0 ; identified document mounted f88 = 2 ; unidentified document mounted f89 = 1 ; no document mounted ; definition of logical disc types f90 = 2.00001 ; logical disc - without catalog f91 = 2.00011 ; logical disc - with rc8000 bs catalog ; definition of chain states t0 = 1<0 ; idle t1 = 1<1 ; after prepare t2 = 1<2 ; during insert t3 = 1<3 ; ready t4 = 1<4 ; during delete t5 = 1<5 ; during check t6 = 1<6 ; during aux entry manipulation t20 = t0 ; allowed for prepare bs t21 = t1+t2 ; allowed for insert entry ; insert bs ; connect main catalog t22 = t3 ; allowed for normal use t23 = t1+t2+t3+t4+t5+t6; allowed for delete bs t24 = t4 ; allowed for delete entries t26 = t1+t5 ; allowed for check aux catalog t28 = t1+t2+t6 ; allowed for create aux entry t29 = t1+t2+t3+t4+t5+t6; allowed for set bs-claims t30 = t1+t2+t3+t6 ; allowed for create area process ; format of catalog entry ; the formats of entries in main catalog and auxiliary catalogs are the ; same, except for a field on 4 words that ; - in main catalog contains document name, and ; - in aux catalogs contains ; word0: entry last change (of entry), shortclock ; word1: write access counter ; word2: read access counter ; word3: dummy f4 = 0 ; byte ; <first slice> f3 = 1 ; byte ; <namekey> * 8 + <perm key> f1 = 2 ; word ; <lower base of entry> f2 = 4 ; word ; <upper base of entry> f5 = 6 ; name ; <entry name> f7 = 14 ; word ; <size of entry> f11 = 16 ; name ; main: <document name> f11 = f11 ; word ; aux: <last change> f12 = f11+2 ; double ; <write access counter>,<read access counter> f13 = f12+4 ; word ; <last used> f0 = a88 ; size of catalog entry f6 = 14 ; start of tail f8 = f0-f6 ; size of tail f51 = -8 ; mask for extracting all but perm-key ; format of chainhead f60 = -2 - f0 ; <claims rel address in internal process> f54 = f4 - f0 ; <first slice of aux catalog> f53 = f3 - f0 ; <chain kind> * 8 + <perm key> f55 = f5 - f0 ; <name of aux catalog> f56 = f6 - f0 ; (start of tail) f57 = f7 - f0 ; <size of aux catalog> f61 = f11- f0 ; <document name> f62 = f56+10 ; word ; <name table address of disc process> f64 = f56+12 ; word ; <slice length> f66 = f56+14 ; byte ; <last slice in chaintable> f67 = f56+15 ; byte ; <number of namekeys> f68 = f56+16 ; byte ; <chain state> f69 = f56+17 ; byte ; (not used) f70 = f56+18 ; word ; <name table address of aux catalog area process> ; (used as segment number under include-exclude auxcat) ; each chaintable has a heading as the above given, which has the same ; basic format as a normal catalog entry. ; it describes the aux catalog on the device. ; after the heading follows the chain-area, consisting of one byte for ; each slice. ; record for main catalog pseudo chainhead ; (format as a normal chainhead) d9 = k - f54 ; base of pseudo chainhead: 0, r. f0>1 ; ; description of current catalog c0: 0 ; size of current catalog c1: 0 ; number of namekeys in current catalog d7: 0, r.4 ; name of current catalog 0 ; (name table address of current catalog area process) ; description of catalog message d8: ; cat message: f30 = k - d8, f14<12 ; operation (initially read) f32 = k - d8, d0 ; first address of catalog buffer f34 = k - d8, d18 ; last address of catalog buffer f36 = k - d8, -1 ; current cat segment (initially not existing) ; common work variables: 0 ;-2 work d12: 0 ; return ; procedure set auxcat ; call: jl. w3 e0. ; ; procedure set maincat ; call: jl. w3 e1. ; ; the use of the current catalog is terminated, and the ; new catalog is selected as curcat ; ; error return: result 2, in case of io-errors ; return: all regs undef b. g10, h10 w. e0: ; set auxcat: rl. w1 (h2.) ; catchain := curdoc; jl. g1. ; else e1: ; set maincat: al. w1 d9. ; catchain := pseudo chain for main catalog; g1: sn. w1 (c2.) ; if catchain = curcat then jl x3 ; return; rs. w3 h0. ; save(return); ; notice: be very cautious not to change curcat until all transfers are ; terminated rs. w1 h1. ; save (catchain); jl. w3 e7. ; terminate update; ; (if io-errors the curcat is not changed yet) rl. w1 h1. ; w1 := new cur cat; rl w0 x1+f57 ; move: catsize rs. w0 c0. ; zl w0 x1+f67 ; no. of namekeys rs. w0 c1. ; al w0 -1 ; dummy segment number rs. w0 d8.+f36; (i.e. simulate irrell buffer contents) rl w0 x1+f70 ; name table address of catalog area process rx. w0 d7.+8 ; al w2 x1+f55 ; catalog name; rx. w1 c2. ; curcat := new cur cat; rs w0 x1+f70 ; save old name table address in old curcat; al. w1 d7. ; rl. w3 h0. ; jl. e32. ; return; c2: d9 ; curcat chainhead address (initially: pseudochainhead) h0: 0 ; return h1: 0 ; new curcat h2: d4 e. ; ; procedure dump chaintable ; writes the chaintable of current document back on the device ; ; call: jl. w3 e2. ; error return: result 2, in case of io-errors ; return: all regs undef b. h10 w. e2: ; dump chain table: rs. w3 d12. ; save(return); rl. w3 (l4.) ; w3 := curdoc; al w0 x3-f0 ; first addr := start of head.curdoc; bz w1 x3+f66 ; wa w1 6 ; last addr := start of head.curdoc al w1 x1+511 ; + last slice.curdoc + 511; (i.e. round up) ds. w1 h2. ; al. w1 h0. ; al w3 x3+f61 ; send message(document, output message); jd 1<11+16; al. w1 d16. ; wait answer; jd 1<11+18; rl. w3 (l4.) ; if curdoc.state = during delete then zl w3 x3+f68 ; return; sn w3 t4 ; <ignore error return when called from delete bs> jl. (d12.) ; rl w1 x1 ; sn w0 1 ; if result <> ok se w1 0 ; or status <> 0 then jl. j2. ; goto result 2; jl. (d12.) ; return; h0: f15 < 12 ; output message: 0 ; first address h2: 0 ; last address 0 ; segment number (always zero) e. ; ; procedure compute namekey and segment number ; sets segment number.work:= hash function(name.work) ; and namekey.work := segment mod no. of namekeys ; ; ; ; the hash function delivers a number ranging from 0 to number of segments ; in the catalog and is used to speed up the search for a name in the catalog. ; when an entry is created , the segment number and the namekey is computed , ; and the entry is inserted in the first free entry on "segment number" or ; the following segments. ; (the successor to the last segment is segment 0 ). ; ; the search for an entry continues until segment=segment no. + no. of namekeys - 1. ; ; ; ; call: jl. w3 e3. ; return: w2 = namekey.work < 3 + key.work ; other regs undef e3: ; compute segment no. dl. w2 v13. ; double := name(0), name(2) aa. w2 v14. ; + name(4), name(6); wa w2 2 ; word := double(0) + double(2); ba w2 4 ; word := word + word // 4096; al w1 0 ; wd. w2 c0. ; segment := word mod catsize; rs. w1 d28. ; segment no.work := segment al w2 x1 ; al w1 0 ; wd. w2 c1. ; namekey.work := segment mod no. of namekeys ls w1 3 ; al w2 -f51-1 ; la. w2 v3. ; wa w2 2 ; hs. w2 v3. ; jl x3 ; return; ; the following complex of io-procedures all have a common ; return information: ; return: w0 = namekey of next segment ; w1 = segment number ; w2 = absolute address of start of buffer ; w3 = undef ; cur cat segment defined ; error return: result 2, in case of io-errors ; "namekey of next segment" is used by the calling procedure to check wheter ; the next segment is relevant , as entries only can be saved and retreived ; from segments between segment no.work and the next segment ; with namekey = namekey.work ; ; procedure get key segment ; ensures that the segment given by namekey.work is present ; in the buffer ; ; call: jl. w3 e4. ; ; ; procedure get cat segment ; ensures that the segment given as parameter is present ; ; call: al w2 <segment number> ; jl. w3 e5. ; ; ; procedure get next segment ; gets the next (cyclically numberred) segment into the buffer ; ; call: jl. w3 e6. ; ; ; procedure terminate update ; the current catalog segment is written back, in case of changes ; ; call: jl. w3 e7. b. g10 w. e4: ; get key segment: rl. w2 d28. ; segment := segment no.work e5: ; get cat segment: ; (w2 = segment) se. w2 (d8.+f36); if segment <> current segment then jl. g1. ; goto get segment; g0: ; exit: al w1 x2 ; w1 := segment; al w0 0 ; w0:=next key wd. w1 c1. ; ea. w0 +1 ; if next key := no of keys then sl. w0 (c1.) ; next key := 0 al w0 0 ; al w1 x2 ; restore segment rl. w2 d8.+f32; w2 := abs first of buffer; jl x3 ; return; e6: ; get next segment: am 1-0 ; incr := 1; e7: ; terminate update: al w2 0 ; incr := 0; wa. w2 d8.+f36; segment := current segment + incr; sl. w2 (c0.) ; if segment outside catalog then al w2 0 ; segment := 0; g1: ; get segment: ; (w2 = segment, w3 = return) ds. w3 d12. ; save(segment, return); bz. w0 d8.+f30; se w0 f15 ; if catoperation <> output then jl. g4. ; goto test input nescessary; g2: ; after output: al. w3 d7. ; w3 := catalog name address; bz. w0 d8.+f30; if catoperation = write then sn w0 f15 ; jd 1<11+8 ; reserve process(catalog); (i.e. after update) al. w1 d8. ; jd 1<11+16; send message(catalog, catmessage); al. w1 d16. ; jd 1<11+18; wait answer; zl. w2 d8.+f30 ; sn w2 f15 ; jd 1<11+10 ; al w2 f14 ; hs. w2 d8.+f30 ; al w2 -1 ; (prepare for io-errors) sn w0 1 ; if result <> ok sz w2 (x1) ; or status <> 0 then jl. g5. ; goto catalog io-error; ; a transfer has now been completed. ; if after update the transfer was an output, terminating the earlier ; segment. in this case the new segment must be brougth into the buffer dl. w3 d12. ; restore(segment, return); g4: ; test input nescessary: rx. w2 d8.+f36; current segment := segment; se. w2 (d8.+f36); if current segment <> segment then jl. g2. ; goto after write; jl. g0. ; goto exit; g5: ; catalog io-error: rs. w2 d8.+f36; current segment := -1; ; (i.e. undefined contents of catalog buffer) jl. j2. ; goto result 2; e. ; ; the following set of procedures are intended for updating ; and utilizing the information given in each catalog segment: ; each segment contains a number, <entry count>, stating the ; number of entries with a namekey corresponding to the ; segment-number ; notice: ; ********************************************************* ; * * ; * in case of break-down during a multi-segment updating * ; * the entry count may be one (or more) too large, * ; * but never too small * ; * * ; * i.e. it is actually a maximum number of entries * ; * * ; * it will be reset at the first catalog search with * ; * that particular namekey * ; * * ; ********************************************************* b. g30, h10 w. ; procedure prepare update and change entry count ; call: al w0 <change of entry count> ; al w2 <start of catalog buffer> ; jl. w3 e8. ; return: all regs undef ; ; the corresponding entry count is updated ; and the segment is flagged for being written back e8: ; change entry count and prepare update: wa w0 x2+f9 ; entry count.buffer := rs w0 x2+f9 ; entry count.buffer + change; ; procedure prepare update ; call: jl. w3 e9. ; return: all regs undef ; ; the current catalog segment is flagged for being written back ; at next catalog transfer e9: ; prepare update: al w0 f15 ; catoperation := write; hs. w0 d8.+f30; jl x3 ; return; ; procedure search free entry ; a new entry is to be created. the entry is given in work. ; entry count(namekey.work) is increased, and a free entry is searched ; for. ; if no room, then entry count is decreased again, and error return ; ; ; call: jl. w3 e10. ; jl. no room ; jl. ok ; error return: result 2, in case of io-error ; return: cur entry (and segment defined) e10: ; search free entry: rs. w3 h1. ; save(return); jl. w3 e4. ; get key segment; rs. w0 h5. ; save next key rs. w1 h0. ; save(segment number); al w0 1 ; jl. w3 e8. ; increase(entry count) and prepare update; g1: ; next segment: al w0 -1 ; w0 := free pattern; al w3 x2+f9 ; w3 := top of last entry; g2: ; next entry: ; (w0 = free pattern, w2 = entry, w3 = top) sn w0 (x2) ; if first word of entry <> free pattern then jl. g5. ; begin al w2 x2+f0 ; entry := entry + entrysize; se w2 x3 ; if more entries on same segment then jl. g2. ; goto next entry; zl. w2 v3. ; if key.work = next key then ls w2 -3 ; decrease entry count sn. w2 (h5.) ; else jl. g10. ; get next segment jl. w3 e6. ; rs. w0 h5. ; save next key jl. g1. ; g5: ; end; ds. w2 d3. ; save(cur entry segment, cur entry); am. (h1.) ; jl +2 ; goto ok-return; ; procedure get cur entry segment ; ensures that the catalog buffer contains the appropriate segment ; and that cur entry address is relevant in this buffer ; ; call: jl. w3 e11. ; error return: result 2, in case of io-error ; return: cur entry segment is in catbuffer ; registers as get catalog segment e11: ; get cur entry segment: rl. w2 d29. ; segment := cur entry segment; jl. e5. ; goto get catalog segment; ; procedure set cur entry ; moves the entry in work to the catalog segment, given by cur entry ; ; call: jl. w3 e12. ; error return: result 2, in case of io-error ; return: all regs undef e12: ; set cur entry: rs. w3 h1. ; save(return); jl. w3 e11. ; get cur entry segment; jl. w3 e9. ; prepare update; rl. w1 d3. ; w1 := cur entry; al. w2 d1. ; w2 := work; jl. w3 e33. ; move work to cur entry; jl. (h1.) ; ; procedure delete cur entry ; remove the entry given by cur entry, by setting the first word ; of the entry to -1 ; entry count(namekey.work) is decreased ; ; call: jl. w3 e13. ; error return: result 2, in case of io-error ; return: all regs undef e13: ; delete cur entry: rs. w3 h1. ; save(return); jl. w3 e11. ; get cur entry segment; al w0 -1 ; rs. w0 (d3.) ; first word(cur entry) := -1 jl. w3 e9. ; prepare update; ; (notice: if the entry is not on the key segment ; two segments must be updated) g10: jl. w3 e4. ; get key segment; ; decrease entry count: al w0 -1 ; g15: ; update and return: jl. w3 e8. ; change entry count and prepare update; jl. (h1.) ; return; ; procedure for all key entries do ; ; delivers all entries, one at a time, with the namekey given ; ; call: al w2 <segment> ; jl. w3 e14. ; jl. no more ; (maybe save w2) ; <action for found entry> ; (restore w2, if destroyed) ; jl x3 ; ; error return: result 2, in case of io-errors ; ; return: link+0: no more entries (all regs undef) ; link+2: w0w1 = undef, w2 = entry, w3 = continue search ; (when continuing w2 must remain unchanged) e14: ; for all key entries do: ds. w3 h1. ; save(segment, return); jl. w3 e5. ; get cat segment; rs. w0 h5. ; save next key ; key :=next key sn w0 0 ; if key = 0 then rl. w0 c1. ; key := no. of keys.catalog bs. w0 1 ; current key := key-1 rs. w0 h4. ; save current key al w3 x2+f9 ; w3 := top of last entry; rs. w3 h3. ; rl w3 x2+f9 ; remaining := entry count.key segment; al w2 x2-f0 ; (decrease(entry) ... code trick) g21: ; test remaining: sn w3 0 ; if remaining = 0 then jl. (h1.) ; return; rs. w3 h2. ; g22: ; next entry: al w2 x2+f0 ; increase(entry); sn. w2 (h3.) ; if out of buffer then jl. g24. ; goto next segment; g23: ; test entry: rl w3 x2 ; se w3 -1 ; if entry exists then bz w3 x2+f3 ; key := key.entry; as w3 -3 ; (otherwise key = not possible) se. w3 (h4.) ; if key <> saved key then jl. g22. ; goto next entry; rl. w3 h1. ; jl w3 x3+2 ; call(found action); (w2 = entry) rl. w3 h2. ; al w3 x3-1 ; decrease(remaining entries); jl. g21. ; goto test remaining; g24: ; next segment: rl. w0 h5. ; if next key = key then sn. w0 (h4.) ; jl. g25. ; goto adjust entry count jl. w3 e6. ; else rs. w0 h5. ; get next segment al w3 x2+f9 ; save next key rs. w3 h3. ; and addres of last entry.segment jl. g23. ; g25: ; adjust entry count rl. w2 h0. ; jl. w3 e5. ; get entry segment ac. w0 (h2.) ; decrease entry count by remaining entries jl. g15. ; and return; h0: 0 ; saved segment h1: 0 ; saved return h2: 0 ; remaining entries h3: 0 ; top address of last entry on segment h4: 0 ; key.segment h5: 0 ; next key e. ; ; procedure compute document address ; ; selects either the maincat document or the document ; specified in first slice.work ; ; call: jl. w3 e15. ; return: w2 = doc address, other regs undef e15: ; compute document address for non-area entries: rl w2 b25 ; (prepare for maincat-entry) bz. w1 v4. ; if first slice.work = 0 then sn w1 0 ; w2 := maincat document jl x3 ; and return; am (b22) ; use the last 11 bits of first slice rl w2 x1-2048 ; to select the document; jl x3 ; return; ; procedure first proc (proc addr,new state); ; finds the process given by name.work and checks that it is a child ; of the sender. ; initializes end chain delta and children bits and returns disabled ; with w3 = proc addr and new state = wait stop by parent. ; call: jl. w3 e17. ; return: disabled with ; w1 = sender ; w2 = new state ; w3 = proc addr ; w0 changed ; error: not child: error 3; e17: rs. w3 d12. ; first proc: save return; jl. w3 e47. ; search best process in nametable; b6 ; b7 ; jl. e26. ;+6: not found: goto test found; al w3 x2 ; proc := proc found; rl. w1 (l2.) ; if parent.proc addr <> sender se w1 (x3+a34) ; then enabled goto error 3; jl. j3. ; al w2 0 ; end chain:= children bits:= 0; rs. w2 d21. ; delta := 0; rs. w2 (l15.) ; w3:= proc addr; b. i1 w. rs. w3 d14. ; al w2 a402 ; start of bit array al w0 0 ; i0: rs. w0 x2+d13. ; childrensbits:=0 al w2 x2+2 ; se w2 a402+a403 ; jl. i0. ; e. al w2 f48 ; w2:= new state:= wait stop by parent; jl. (d12.) ; disabled return; e26: jl. w3 e24. ; test found: test format; jl. j3. ; goto error 3; ; procedure chain and add children; ; connects proc addr to the the chain through wait addresses which ; ends in end chain and exits via add children ; call: jl. w3 e18. ; return: w2: delta (stopcount - children) b. g2 ; begin w. ; e18: dl. w2 (l15.) ; chain and add children: rs w2 x1+a40 ; wait addr.proc addr:= end chain; rs. w1 (l15.) ; end chain:= proc addr; ; procedure add children; ; searches through all internal processes and adds to children bits ; the identification bit for all processes with parent = proc addr; ; call: jl. w3 e19. ; return: w2: delta (stopcount - children) e19: rs. w3 d12. ; add children: save return; rl. w1 d14. ; zl w2 x1+a12 ; delta := delta + stopcount; wa. w2 d21. ; rs. w2 d21. ; rl w3 b6 ; w3:=addr(first proc in nametable); g0: rl w2 x3 ; for w3 through nametable do rl. w1 d14. ; w1:=proc addr; se w1 (x2+a34) ; if parent.nametable(w3)= jl. g1. ; procaddr then el w1 x2+a14 ; include identbit.nametable(w3) bz. w0 x1+d13. ; nametable(w3)); lo w0 x2+a14 ; hs. w0 x1+d13. ; rl. w2 d21. ; al w2 x2-1 ; delta := delta - children; rs. w2 d21. ; g1: al w3 x3+2 ; se w3 (b7) ; jl. g0. ; rl. w2 d21. ; jl. (d12.) ; return; e. ; end chain/add children; ; procedure next proc (result: proc addr, new state); ; finds proc addr corresponding to one of the bits in children bits, ; removes the corresponding bit in children bits, and returns disabled ; with new state = wait stop by ancestor and proc addr defined. ; call: jl. w3 e20. ; return: w2 = new state ; w3 = proc addr ; w0,w1 changed. ; return 2: no more children b. g5 ; begin w. ; next proc: e20: rs. w3 d12. ; save(link) ; al w3 -11 ; al w1 a402 ; w1:=first halfword.bit array g0: zl. w0 x1+d13. ; get array(w1) sn w0 0 ; if no users then jl. g3. ; goto next halfword ns w0 1 ; (first internal : -11 second : -12 ...) es w3 1 ; w3:= -11 +no of shifts ls w3 1 ; +12*halfword no(bitarray) am (b6) ; name table index:=w3*2 rl w3 x3 ; w3:=proc zl. w0 x1+d13. ; remove children it from bit array lx w0 x3+a14 ; hs. w0 x1+d13. ; al w2 f50 ; new state:=wait stop by ancestor rs. w3 d14. ; jl. (d12.) ; g3: al w1 x1+1 ; next halfword(bitarray) al w3 x3+12 ; w3:=w3+no of internals pr halfword se w1 a402+a403 ; if index > last index then jl. g0. ; return : no more children rl. w3 d12. ; jl x3+2 ; e. ; end next proc; ; procedure create next wrk-name ; supplies a wrk-name in name.work ; ; a wrk-name has the format: wrk<6 octal digits> ; ; call: jl. w3 e23. ; ; return: name.work defined ; all regs undef b. g10, h10 w. e23: ; test name: dl. w1 h0. ; increase(last wrkname) octal; aa. w1 h3. ; lo. w0 h1. ; (notice: a carry from one character is la. w0 h2. ; propagated to next char and so on, lo. w1 h1. ; by means of the special mask) la. w1 h2. ; ds. w1 h0. ; al. w1 v5. ; move wrk-name jl. w2 e32. ; to name.work; h0=k+4 ; wrk-digits ; <:wrk000000:>,0 ; last wrk-name h1: <:000:> ; mask to convert to digits h2: <:777:> ; mask to eliminate superflouos carries 200<16+200<8+200 ; double-mask to increase octally h3: 200<16+200<8+200+1; (= all ones - <:888888:> + 1) e. ; ; procedure test format ; ; test whether the format of name.work corresponds to ; a legal identifier. ; a legal name consists of a small letter followed by at most ; 10 small letters or digits, filled up with null-chars ; until 4 words. ; f16 <= value of digit <= f17 (initially: digits 0-9) ; f18 <= value of small letter <= f19 (initially: letters a-aa) ; ; call: jl. w3 e24. ; error return: result 6, if nameformat illegal ; return: nameformat ok ; all regs undef b. g10 w. e24: ; test format: rs. w3 d12. ; save(return); al. w2 v5. ; name pointer := addr of name.work; bz w0 x2 ; test start of name: sl w0 f18<4 ; if first char of name < minimum letter then jl. g3. ; goto result 6; jl. j6. ; goto get word; g1: ; test next char: ; w0 = partial word ( <> 0 ) ; (i.e. contains at least one character, ; which must be left justified) ; w1 = current word ; w2 = name pointer: even == before null-char ; odd == after null-char ; w3 = 1 so w2 2.1 ; if before null-char then ld w0 8 ; char := next char from partial word + 1 shift 8; ; (partial word := partial word shift 8); ; (i.e. if after null-char then illegal name) sh w3 f17+1<8; al w3 x3+f18-f16; if neither letter nor digit then sl w3 f18+1<8; sl w3 f19+1+1<8; jl. j6. ; goto result 6; i.e. illegal name g2: ; test rest of partial word: al w3 1 ; (prepare for next char and for making nameptr odd) se w0 0 ; if partial word <> 0 then jl. g1. ; goto test next char; sz w1 255 ; if last char in current word = null then sz w2 2.1 ; after null-char := true; lo w2 6 ; (i.e. make name pointer odd) al w2 x2+2 ; increase(name pointer); g3: ; get word: rl w1 x2 ; current word := name (name pointer); al w0 x1 ; partial word := current word; sh. w2 v15. ; if name pointer < last addr of name.word then jl. g2. ; goto test rest of partial word; sz w2 2.1 ; if after null-char then jl. (d12.) ; return; jl. j6. ; goto result 6; (i.e. more than 11 chars) e. ; ; procedure remove area (intproc,areaproc); ; intproc is removed as user and as reserver of area proc. ; call: w1= intproc, w2=area proc ; disabled call with link in w3 b.g30,h7 w. ; begin ; remove area: h0: 0 ; save w1: init proc h1: 0 ; save w2: area h2: 0 ; save w3: link h3: 0 ; result from check user-reserver 0 ; write access counter h6: 0 ; read access counter 0 ; lower base.proc h7: 0 ; upper base.proc e25: rs. w3 h2. ; save return jl. w3 e64. ; rs. w3 h3. ; so w3 f20 ; if proc not user then jl. (h2.) ; enable return; jl. w3 e56. ; exclude proc as user(and reserver) rl. w3 h3. ; if proc has writeprotected then sz w3 f24 ; jl. w3 e53. ; remove writeprotect(proc, area); al w3 1 ; ba w3 x1+a20 ; increase area claim hs w3 x1+a20 ; rl. w0 h3. ; if other users then sz w0 f22 ; jl. (h2.) ; enable return al w0 0 ; sn w0 (x2+a411) ; w0=0 used below.... se w0 (x2+a412) ; if access counters<>0,0 then jl. g1. ; name(0).area:=0; jl. w3 e67. ; clean area process; jl. (h2.) ; enable return ; save statistical information in auxiliary catalog. g1: ds. w2 h0.+2 ; save init proc, link; dl w1 x2+a49 ; ds. w1 v2. ; base.work:=base.proc ds. w1 h7. ; save base.proc dl w1 x2+a62+2 ; move docname.area to docname.work ds. w1 v30. ; dl w1 x2+a62+6 ; ds. w1 v31. ; dl w1 x2+a11+2 ; move name.area to name.work ds. w1 v13. ; dl w1 x2+a11+6 ; ds. w1 v14. ; jl. w3 e67. ; clean area process rl. w1 h0. ; w1:= initproc dl w0 x2+a412 ; ds. w0 h6. ; access counters:=access counters.area; jl. w3 e45. ; enable, find chain(docname.work) v11 ; jl. g2. ; NOT FOUND: result 3 rs. w2 d4. ; curdoc:= chain; jl. w3 e0. ; set aux cat jl. w3 e46. ; search best entry jl. g2. ; NOT FOUND: enable return sn. w0 (h7.-2) ; if base.entry<> base.proc se. w1 (h7.) ; then enable return jl. g2. ; (area describes a temp entry on curdoc) dl w1 b13+2 ; ld w1 5 ; dl. w2 h6. ; se w1 0 ; if write access counter<>0 then rs. w0 v11. ; last change.work:=short clock; sn w1 0 ; if write access counter<>0 or se w2 0 ; if read access counter<>0 then rs. w0 v8. ; last used.work := short clock wa. w1 v12. ; wa. w2 v32. ; ds. w2 v32. ; update access counters; jl. w3 e12. ; set curr entry; g2: jl. w3 e1. ; maincat: set main catalog; rl. w1 h0. ; w1:=init proc; jl. (h2.) ; exit: enable, return; e. ; ; the following complex of procedures take care of moves ; in general the call must be like this: ; call: al w0 <bytes to move> (must be even) ; al. w1 <to-address> ; al. w2 <from-address> ; jl. w3 move ; return: all regs undef ; ; procedure move entry ; procedure move name ; procedure move ; b. g10, h10 w. e33: am f0-8 ; move entry: bytes = size of catalog entry e32: al w0 8 ; move name: bytes = size of name e31: ; move: rs. w3 h0. ; save(return); gg w3 b100 ; if mp-cpu then sh w3 55 ; begin jl. g0. ; mh w2 (0) ; move halfwords(size, destination, source); jl. (h0.) ; return; ; end; g0: ac w3 (0) ; remaining := - bytes; sz w3 1<1 ; if odd number of words to move then jl. g5. ; goto move single word; g1: ; move double words: rs. w3 h1. ; save(remaining); sl w3 h5 ; if remaining does no exceed size of move-table jl. x3+h4. ; then switch out through table; ; (otherwise move a whole portion) h3: ; start of move-table: dl w0 x2+30 ; ds w0 x1+30 ; dl w0 x2+26 ; ds w0 x1+26 ; dl w0 x2+22 ; ds w0 x1+22 ; dl w0 x2+18 ; ds w0 x1+18 ; dl w0 x2+14 ; ds w0 x1+14 ; dl w0 x2+10 ; ds w0 x1+10 ; dl w0 x2+6 ; ds w0 x1+6 ; dl w0 x2+2 ; ds w0 x1+2 ; h4: ; top of move-table: h5 = h3 - h4 ; size of move-table (notice: negative) al w1 x1-h5 ; increase(to-address); al w2 x2-h5 ; increase(from-address); rl. w3 h1. ; restore(remaining); al w3 x3-h5 ; decrease(remaining); (remember: negative) sh w3 -1 ; if not all moved yet then jl. g1. ; goto move double words; jl. (h0.) ; return; g5: ; move single word: rl w0 x2+0 ; rs w0 x1+0 ; al w1 x1+2 ; increase(to-address); al w2 x2+2 ; increase(from-address); al w3 x3+2 ; decrease(remaining); (remember: negative) jl. g1. ; goto move double words; h0: 0 ; saved return h1: 0 ; remaining bytes (negative, multiplum of 4 bytes) e. ; ; procedure find idle area or pseudo; ; ; reg call return ; w0 0 ; w1 unchanged ; w2 proc ; w3 link proc ; b. h5,g5 w. e40: rs. w3 h3. ; begin al w0 0 ; rl w2 b5 ; al w2 x2-2 ; g0: al w2 x2+2 ; repeat sn w2 (b6) ; if end_of_name_table.area then jl. j1. ; result 1; rl w3 x2 ; proc:=next; sn w0 (x3+a11) ; test idle; se w0 (x3+a50) ; jl. g0. ; until proc is idle; ; rs. w2 d11. ; found: set name table entry; rl w2 x2 ; jl. (h3.) ; h3: 0 ; saved return; e. ; procedure compare names ; ; the names at name.work and name.param are compared ; ; call: w2 = chain addr, w3 = link ; exit: w0w1 = undef, w2w3 = unchanged ; ; return: link+0: not same name ; link+2: the names are equal e41: ; compare names: dl. w1 v13. ; sn w0 (x2+f55+0) ; if first part of name.work <> se w1 (x2+f55+2) ; first part of name.chain then jl x3 ; return not same; dl. w1 v14. ; if second part of name.work <> sn w0 (x2+f55+4) ; se w1 (x2+f55+6) ; second part of name.chain then jl x3 ; return not same; jl x3+2 ; return same; ; procedure for all named entries in cat do ; ; the namekey.work is computed, and the current catalog is searched for ; entries with name = name.work. ; for each such entry the found-action is called ; ; call: jl. w3 e42. ; jl. no more ; <action for found entry> ; w0w1 = base.entry, w2 = entry ; (maybe save w2) ; ... ; (maybe restore w2, if changed) ; jl x3 ; ; error return: result 2, in case of io-error ; ; return: link+0: no more entries (all regs undef) ; link+2: w0w1 = base.entry, w2 = entry, w3 = continue search b. h0 w. e42: ; for all named entries in cat do: rs. w3 h0. ; jl. w3 e3. ; compute namekey.work; rl. w2 d28. ; segment := segment.work jl. w3 e14. ; for all key entries do jl. (h0.) ;+2: no more: goto no-more action; ; for each entry the name must be tested: dl. w1 v13. ; sn w0 (x2+f5+0) ; se w1 (x2+f5+2) ; if name.entry <> name.work then jl x3 ; return; dl. w1 v14. ; sn w0 (x2+f5+4) ; se w1 (x2+f5+6) ; jl x3 ; ; the name.entry was correct, now exit to check the base.entry dl w1 x2+f2 ; w0w1 := base.entry; am. (h0.) ; jl +2 ; call found-action and return; h0: 0 ; saved return; e. ; ; procedure for all named procs in part of nametable do ; ; the specified part of nametable is scanned for processes with ; name.proc = name.work ; for each process the found-action is called ; ; call: jl. w3 e43. ; <first> ; e.g. b5 (=first area process in nametable) ; <top> ; e.g. b6 (=top area process in nametable) ; jl. no more ; <action for found process> ; w2 = nametable address ; (maybe save w2) ; ... ; (maybe restore w2) ; jl x3 ; ; return: link+4: no more processes (all regs undef) ; link+6: w0w1 = base.process, w2 = nametable address, w3 = continue b. g10, h10 w. e43: ; for all processes in part of nametable do: rl w2 (x3+0) ; get first nametable address; rl w0 (x3+2) ; get top nametable address; al w3 x3+6 ; ds. w0 h1. ; save(found-action address, top nametable address); al w2 x2-2 ; g1: ; next process: dl. w1 v13. ; g2: ; al w2 x2+2 ; increase(nametable address); sn. w2 (h1.) ; if nametable address = top name table address then jl. g10. ; goto no-more action; rl w3 x2+0 ; proc := word(nametable address); sn w0 (x3+a11+0) ; se w1 (x3+a11+2) ; if name.proc <> name.work then jl. g2. ; goto next process; dl. w1 v14. ; sn w0 (x3+a11+4) ; se w1 (x3+a11+6) ; jl. g1. ; ; the process-name was correct, now exit to check the base.process dl w1 x3+a49 ; w0w1 := base.process; al. w3 g1. ; return := next process; jl. (h0.) ; call found-action; g10: am. (h0.) ; no-more action: jl -2 ; goto no-more; h0: 0 ; return to found-action h1: 0 ; top name table address e. ; ; procedure find idle process in part of nametable ; ; the specified part of nametable is scanned until an idle process is found ; (notice: it must exist) ; ; call: jl. w3 e44. ; <first> ; e.g. b5 (= first area process in name table) ; ; return: cur proc nametable address is defined ; w0 = 0, w1 = unchanged, w2 = proc, w3 = undef b. g10 w. e44: ; find idle process in part of nametable: al w0 0 ; rl w2 (x3) ; nametable address := param; se w2 (b6) ; (if internal processes then skip procfunc itself) al w2 x2-2 ; g1: ; next process: al w2 x2+2 ; increase(nametable address); am (x2) ; if name.process(nametable address) <> 0 then se w0 (+a11) ; jl. g1. ; goto next process; rs. w2 d11. ; save(cur proc nametable addr); rl w2 x2 ; w2 := proc; jl x3+2 ; return; e. ; ; procedure find chain ; ; searches the chaintables in order to find a chainhead with ; docname.chain = name ; ; call: jl. w3 e45. ; <name address> ; ; error return: result 6, if name(0) = 0 ; ; return: link+2: chain not found (all regs undef) ; link+4: chain found ; w2 = chain ; other regs undef b. g10, h10 w. e45: ; find chain: rl w1 x3 ; w1 := start of name; al w1 x1+2 ; al w2 x1+4 ; ds. w2 h2. ; save (first double, last double); al w3 x3+2 ; rs. w3 h0. ; save (error return address); rl w3 b22 ; entry := first drumchain in name table; al w3 x3-2 ; g1: ; next chain: dl. w1 (h2.) ; w0w1 := last double word of name; g2: ; al w3 x3+2 ; increase (entry); sn w3 (b24) ; if all chains tested then jl. (h0.) ; error return; rl w2 x3 ; chain := name table(entry); sn w0 (x2+f61+4) ; se w1 (x2+f61+6) ; if name.chain <> name then jl. g2. ; goto next chain; dl. w1 (h1.) ; sn w0 (x2+f61+0) ; se w1 (x2+f61+2) ; jl. g1. ; ; a chain was found, with docname.chain = name ; check that the chain is not empty sn w0 0 ; if name(0) = 0 then jl. j6. ; result 6; i.e. nameformat illegal; am. (h0.) ; jl +2 ; return ok; h0: 0 ; return h1: 0 ; address of first double word of name h2: 0 ; address of last double word of name e. ; ; procedure search best entry in catalog ; ; searches the current catalog for an entry with name.entry = name.work ; and with the narrowest interval containing base.work ; the entry is moved to work ; ; call: jl. w3 e46. ; jl. not found ; jl. found ; ; error return: result 2, in case of io-error ; result 6, in case of nameformat illegal ; ; return: link+0: no entry with name.entry = name.work was found ; with an interval containing base.work ; (all regs undef) ; link+2: an entry was found: ; w0w1 = base.entry ; cur entry (and -segment) is defined ; entry is moved to work ; (all regs undef) b. g20, h10 w. e46: ; search best entry in catalog: rs. w3 h0. ; save(return); dl w1 b40 ; best base := system base; ds. w1 h2. ; al w0 0 ; cur entry := 0; rs. w0 d3. ; jl. w3 e42. ; for all named entries in catalog do jl. g5. ;+2: no more: goto test any found; ; w0w1 = base.entry, w2 = entry, w3 = continue search sh. w0 (v1.) ; if base.entry does not contain base.work sh. w0 (h1.) ; or base.entry is not better than best base then jl x3 ; continue search; sl. w1 (v2.) ; sl. w1 (h2.) ; jl x3 ; ; a better entry was found: save new base as best base bs. w0 1 ; (code trick) al w1 x1+1 ; (code trick) ds. w1 h2. ; best base := base.entry; ; procedure save position ; ; call: w2 = entry ; jl. w3 e48. ; exit: w2,w3 = unchanged e48: ; save position: rl. w1 d8.+f36; cur entry segment := current segment; ds. w2 d3. ; cur entry := entry; jl x3 ; return;; g5: ; test any found: rl. w2 d3. ; if cur entry = 0 then sn w2 0 ; goto test format; jl. g10. ; (i.e. no entries was found, maybe illegal name) jl. w3 e11. ; get current entry segment; al. w1 d1. ; rl. w2 d3. ; jl. w3 e33. ; move entry to work; dl. w1 v2. ; w0w1 := base.work; am. (h0.) ; ok return; jl +2 ; g10: ; test format: jl. w3 e24. ; test format; jl. (h0.) ; not-found return; h0: 0 ; saved return h1: 0 ; lower best interval - 1 h2: 0 ; upper best interval + 1 ; procedure search best process in nametable ; ; searches the nametable for a process with name.process = name.work ; and with the narrowest interval containing base.work ; ; call: jl. w3 e47. ; <first> ; e.g. b5 (=first area process in nametable) ; <top> ; e.g. b6 (=top area process in nametable) ; jl. not found ; jl. found ; ; return: link+4: no process with name.process = name.work was found ; (all regs undef) ; link+6: a process was found: ; cur process nametable address is defined ; w0w1 = base.process, w2 = process ; (other regs undef) e47: ; search best process in nametable: rs. w3 h0. ; save(return); dl w1 x3+2 ; get search limits; ds. w1 h5. ; dl w1 b40 ; best base := system base; ds. w1 h2. ; al w0 0 ; cur proc nametable address := 0; rs. w0 d11. ; jl. w3 e43. ; for all named processes in part of nametable do 0 ; e.g. b3 ; (start limit) h5: 0 ; e.g. b7 ; (top limit) jl. g20. ;+6: no more: goto test any found; ; w0w1 = base.process, w2 = nametable address, w3 = continue address sh. w0 (v1.) ; if base.process does not contain base.work sh. w0 (h1.) ; or base.process in not better than best base then jl x3 ; continue search; sl. w1 (v2.) ; sl. w1 (h2.) ; jl x3 ; ; a better process was found, save new base and nametable address bs. w0 1 ; (code trick) al w1 x1+1 ; (code trick) ds. w1 h2. ; best base := base.process; rs. w2 d11. ; cur process nametable address := nametable address jl x3 ; continue search; g20: ; test any found: rl. w2 d11. ; rl. w3 h0. ; sn w2 0 ; if cur proc nametable address = 0 then jl x3+4 ; not-found return; rl w2 x2 ; proc := nametable (name table address); dl w1 x2+a49 ; w0w1 := base.proc; jl x3+6 ; ok-return; e. ; ; insert statinf. ; this procedure moves the contents of the statarea of ; the work area to the current entry (docname area). ; ; call: jl. w3 e49. ; ; return: all registers destroyed e49: rl. w1 d3. ; insert statinf; al w1 x1+f11 ; al. w2 d30. ; jl. e32. ; goto move name; ; get statinf. ; this procedure moves the contents of the statarea in current entry ; to the work area. ; ; call: jl. w3 e50. ; ; return: all registers destroyed e50: al. w1 d30. ; get statinf: rl. w2 d3. ; al w2 x2+f11 ; jl. e32. ; goto move name; ; lock and call monitor subprocedures. ; note: when called the used tabel-element will contain the return address, ; but at return, the original content of the element is restored. b. i4 h. ; monitor call table: <subprocedure address>,<tabel index> i0: b33, k-i0-1 ; remove writeprotect b35, k-i0-1 ; remove element b36, k-i0-1 ; link element b37, k-i0-1 ; remove user b39, k-i0-1 ; insert reserver b46, k-i0-1 ; insert user b48, k-i0-1 ; check user and reserver w. ; table end; i1: 0 ; monitor entry i2: 0 ; tabel index i3: 0 ; saved w3 from monitor call ; e64: am 2 ; check user and reserver e58: am 2 ; insert user e57: am 2 ; insert reserver e56: am 2 ; remove user e55: am 2 ; link element e54: am 2 ; remove element e53: ; remove writeprotect rx. w3 i0. ; begin rs. w3 i1. ; monitor entry, index := monitor call(subroutine); hs. w3 i2.+1 ; tabel index := monitor call; jl. w3 e65. ; lock monitor; zl. w3 i1. ; jl w3 x3 ; call monitor subprocedure(monitor entry); rs. w3 i3. ; save w3 jl. w3 e66. ; unlock monitor; rl. w3 i1. ; monitor call(tabel index):= monitor entry, index; am. (i2.) ; rx. w3 i0. ; rx. w3 i3. ; restore w3 , save return jl. (i3.) ; return ; end; ; ; ; lock and check user ; e59: ; lock and check user rs. w3 i4. ; begin jl. w3 e65. ; lock monitor; jl w3 b47 ; call check user; am -2 ; +0: not user al w3 0 ; +2: user wa. w3 i4. ; al w3 x3+2 ; return addr := return addr + result; jl. e66. ; unlock monitor and return; ; i4: 0 ; e. ; end; ; the following set of procedures handles the conversion of ; logical sender-addresses (in case of rc8000) ; ; they all have a common call- and return-sequence: ; ; call: jl. w2 e<number> ; return: w2 = abs address ; w0, w1, w3 unchanged b. g10, h10 w. e60: ; get w1-abs: rs. w2 h0. ; al w2 a29 ; w2 := rel of save w1; jl. g0. ; goto get abs; e61: ; get w2-abs: rs. w2 h0. ; al w2 a30 ; w2 := rel of save w2; jl. g0. ; goto get abs; e62: ; get w3-abs: rs. w2 h0. ; al w2 a31 ; w2 := rel of save w3; g0: ; get abs: am. (d2.) ; rl w2 x2 ; w2 := saved wreg.sender (logical address); g1: ; convert to abs: c. 8000 ; if rc8000 then am. (d2.) ; wa w2 +a182 ; w2 := logical address + base.sender; z. ; jl. (h0.) ; return; h0: 0 ; saved return ; procedure get abs address ; ; call: al w2 <logical addr> ; jl. w3 e63. ; ; return: w2 = abs address ; w0, w1, w3 unchanged e63: ; get abs address rs. w3 h0. ; jl. g1. ; goto convert to abs; e. ; ; lock monitor ; if mpu the monitor lock is locked else the interrupt disable limit is selected ; b. h1 w. ; lock monitor e65: ; begin am (b9) ; h0=k ; if mpu then jl. 0 ; lock(monitor lock); lk b51 ; c.(:h0+a8-k-1:) ; am 0 ; r.(:h0+a8+2-k:)>1 ; fill up; z. ; jd x3 ; return disabled; e. ; end; ; unlock monitor ; if mpu the monitor is released else the interrupt enable limit is selected b. h1 w. ; unlock monitor e66: ; begin am (b9) ; h0=k ; if mpu then jl. 0 ; unlock(monitor lock); ul b51 ; c.(:h0+a8-k-1:) ; am 0 ; r.(:h0+a8+2-k:)>1 ; fill up; z. ; je x3 ; return enabled; e. ; end; ; procedure clean area process(proc); ; reg call return ; w0 0 ; w1 unchanged ; w2 proc - ; w3 link number of oustanding buffers ; b. h3 w. e67: rs. w3 h3. ; save return al w0 0 ; rs w0 x2+a11 ; name(0).area:=0; zl w3 x2+a57 ; sn w3 0 ; if number of outstanding buffers=0 then rs w0 x2+a50 ; clear main; jl. (h3.) ; h3: 0 ; saved return; e. ; the following set of procedures take care of all moves between ; sender-process and procfunc. ; ; they all have a common call- and return-sequence: ; ; call: jl. w3 e<number> ; return: all regs undef b. h10 w. ; size procfunc addres h1: 8 , v5 ; name.work h2: 8 , v11 ; docname.work h3: f8 , v6 ; tail.work h4: ; (chainhead) h5: f0 , d1 ; entry.work h6: 12 , v6 ; registers to tail.work h7: 18 , v6 ; internal params to tail.work h8: 10 , v5 ; name + nametable addr h9: 4*a110+4 , d16 ; bs-claims to bs-params ; moves from senders w1-area: e76: am h7-h9 ; internal params to tail.work: e75: am h9-h6 ; bs-claims to bs-params: e74: am h6-h5 ; registers to tail.work: e73: am h5-h3 ; complete entry to work: e72: am h3-h2 ; tail to tail.work: e71: am h2-h1 ; name to docname.work: e70: dl. w1 h1.+2 ; name to name.work: jl. w2 e60. ; w2 := abs address of w1-area; jl. e31. ; goto move; ; moves to senders w1-area: e82: am h1-h5 ; name.work to name: e81: am h5-h3 ; work to complete entry: e80: dl. w1 h3.+2 ; tail.work to tail: e83: ; bs-claims.cur.proc to sender area jl. w2 e60. ; w2 := abs address of w1-area; rx w2 2 ; exchange ..to.. and ..from..; jl. e31. ; goto move; ; moves from senders w2-area: e85: dl. w1 h2.+2 ; name to docname.work: jl. w2 e61. ; w2 := abs address of w2-area; jl. e31. ; goto move; ; moves from senders w3-area: e92: am h4-h2 ; chainhead to work: e91: am h2-h1 ; name to docname.work: e90: dl. w1 h1.+2 ; name to name.work: jl. w2 e62. ; w2 := abs address of w3-area; jl. e31. ; goto move; ; moves to senders w3-area: e96: am h8-h1 ; name and nametable addr to name etc.: e95: dl. w1 h1.+2 ; name.work to name: jl. w2 e62. ; w2 := abs address of w3-area; rx w2 2 ; exchange ..to.. and ..from..; jl. e31. ; goto move; e. ; ; the following set of procedures handles the interpretation ; of the function-tables. ; ; most of the entries leave w0 and w2 unchanged b. g20, h10 w. h0 = 1 ; size of instructions (in bytes) h1: 0 ; current instruction pointer ; (points at instruction being interpreted) h2: 0 ; first free in stack h3: 0, r.3 ; stack c.(:a92>22a.1:)-1 m. test buffer pointers (first, last, next) h4: d49 ; first of test buffer h5: d50 ; top of test buffer h6: d49 ; current test address z. n2: am h0 ; skip 2 instructions: n1: am h0 ; skip 1 instruction: n0: al w3 h0 ; next instruction: g0: wa. w3 h1. ; w3 := abs addr of next instruction byte; g1: rs. w3 h1. ; save (cur instruction ptr); ; test start: c.(:a92>22a.1:)-1 rs. w3 (h6.) ; save (cur instr ptr) in test buffer; rl. w3 h6. ; al w3 x3+2 ; increase (test buffer ptr); sl. w3 (h5.) ; (unless outside buffer); rl. w3 h4. ; rs. w3 h6. ; rl. w3 h1. ; (restore (cur instr ptr) ) z. ; test end bz w3 x3 ; w3 := instruction byte (positive integer); ; when the function is entered, w0, w1 and w2 are unchanged from last ; function call. ; w3 = return to next instruction jl. w3 x3+n50. ; goto function (w3); jl. n0. ; (if it was a procedure then goto next instruction) n6: am h0 ; goto-action 2: goto second param; n5: al w3 h0 ; goto-action 1: goto first param; wa. w3 h1. ; w3 := abs address of param byte; ba w3 x3 ; w3 := abs addr of next instruction; jl. g1. ; goto save cur instruction address; ; procedure next param ; ; call: jl. w3 n10. ; return: w0 = next param (signed integer) n10: al w0 h0 ; next param: wa. w0 h1. ; w0 := abs addr of param byte; rs. w0 h1. ; save (cur instruction ptr); bl w0 (0) ; w0 := param (cur instr ptr); jl x3 ; return; ; procedure call table program ; ; call: al w3 <abs address of start of program> ; jl. n20. n20: rl. w1 h1. ; call table program: rs. w1 (h2.) ; stack (cur instr ptr); rl. w1 h2. ; al w1 x1+2 ; increase (stack ptr); g10: rs. w1 h2. ; jl. g1. ; goto save abs instr ptr; n33: am n5-n1 ; return to program and goto: n31: am n1-n0 ; return to program and skip: n30: al. w3 n0. ; return to program: rl. w1 h2. ; al w1 x1-2 ; decrease (stack ptr); rs. w1 h2. ; rl w1 x1 ; unstack (cur instr ptr); rs. w1 h1. ; jl x3 ; goto next or skip or goto-action; ; subroutine call following program and return later to function ; ; call: jl. w3 n25. n25: rl. w1 h2. ; call from function: rs w3 x1 ; stack (return to function); rl. w3 h1. ; rs w3 x1+2 ; stack (cur instr ptr); al w1 x1+4 ; increase (stack ptr); al w3 x3+h0+h0 ; w3 := abs addr of second byte; jl. g10. ; goto save stackptr and cur instr ptr; n35: rl. w1 h2. ; return from program to function: al w1 x1-4 ; rs. w1 h2. ; decrease (stack ptr); rl w3 x1+2 ; unstack (cur instr ptr); rs. w3 h1. ; jl (x1) ; return to unstack (function); n50: ; base of interpretation addresses: ; start interpretation ; ; the previous procfunc call is answerred and the next is awaited ; the differrent pointers are initialized j7: am 7-6 ; result 7: j6: am 6-5 ; result 6: j5: am 5-4 ; result 5: j4: am 4-3 ; result 4: j3: am 3-2 ; result 3: j2: am 2-1 ; result 2: j1: am 1-0 ; result 1: j0: al w0 0 ; result 0: jl. w3 e66. ; unlock(monitor) rl. w1 d2. ; w1 := sender; rs w0 x1+a28 ; w0.sender := result; jl. w3 e1. ; set maincat; jl. w3 e7. ; terminate update; j10: jd 1<11+2 ; waiting instruction: rl w1 (b6) ; w1 := procfunc; rl w1 x1+a15 ; sender := next (messq (procfunc) ) - a16; al w1 x1-a16 ; rs. w1 d2. ; save (sender); rl w3 x1+a176 ; w3 := monitor call number; ws. w3 h9. ; ( = word (ic.sender - 2) - jd 1<11+40 ) ; w1 = sender ; w3 = monitor call number al. w2 h3. ; rs. w2 h2. ; stack ptr := start of stack; ls w3 -1 ; wa. w3 h10. ; cur instruction ptr := start table (monitor call); ba w3 x3 ; jl. g1. ; goto next instruction; h9: 40 ; first procfunc monitor call h10: n49 ; start of table ; redefinition of d-names l2 : d2 l4 : d4 l14: d14 l15: d15 e. ; ▶EOF◀