|
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: 64512 (0xfc00) Types: TextFile Names: »monprocfnc1«
└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ. Detaljer om "HC8000" projekt. └─⟦0364f57e3⟧ └─⟦80d78256e⟧ »kkmon4filer« └─⟦this⟧ └─⟦667bb35d6⟧ Bits:30007480 RC8000 Dump tape fra HCØ. └─⟦4334b4c0b⟧ └─⟦953993a1e⟧ »kkmon1filer« └─⟦this⟧ └─⟦667bb35d6⟧ Bits:30007480 RC8000 Dump tape fra HCØ. └─⟦4334b4c0b⟧ └─⟦b8ddea98b⟧ »kkmon3filer« └─⟦this⟧
\f m. monprocfnc1 - monitor process functions, part 1 b.i30 w. i0=80 12 10, i1=12 00 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, m280, n50, p65, r7, t40, v40 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 ; record sender. ; the absolute address of the description of the calling process is stored ; in d2. parameters to and from the sender are found in the register dump ; as follows: f20 = a31 ; save w3: name address f21 = a29 ; save w1: tail address f22 = a29 ; or: new name address f23 = a29 ; or: catalog key f24 = a29 ; or: general parameter pointer f25 = a28 ; save w0: result f26 = a40 ; save wait address ; 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 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> 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 ; <first slice of chaintable-chain> f68 = f56+16 ; byte ; <chain state> f69 = f56+17 ; byte ; <cur key> (used as segment number in certain clean-ups) f70 = f56+18 ; word ; <name table address of aux catalog area process> ; 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 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. ; 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 d4. ; w3 := curdoc; al w0 x3-f0 ; first addr := start of head.curdoc; bz w1 x3+f66 ; wa w1 6 ; last addr := start of chain.curdoc al w1 x1+511 ; + last slice.curdoc + 511; (i.e. round up) ds. w1 h2. ; bz w1 x3+f67 ; segment number := wm w1 x3+f64 ; first chaintable slice.curdoc rs. w1 h3. ; * slicelength.curdoc; 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 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 h3: 0 ; segment number e. ; ; procedure compute namekey ; sets namekey.work := namekey function(name.work) ; ; the namekey is a numer ranging from 0 to the number of segments (less one) ; in the catalog. the namekey is computed from the name following the ; algorithm below, and is used to speed-up the search for the name in ; the catalog. ; when an entry is created it is placed in the first free entry in the ; catalog on the segment <namekey>, or the following segments. ; the search for an entry then starts from the segment <namekey> and ; towards higher segment numbers. ; (the successor to the last segment is segment zero) ; ; call: jl. w3 e3. ; return: w2 = namekey.work < 3 + key.work ; other regs undef e3: ; compute namekey: 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. ; namekey := word mod catsize; ls w1 3 ; al w2 -f51-1 ; la. w2 v3. ; namekey.work := namekey; wa w2 2 ; hs. w2 v3. ; jl x3 ; return; ; the following complex of io-procedures all have a common ; return information: ; return: w0 = undef ; 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 ; 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: bz. w2 v3. ; ls w2 -3 ; segment := namekey.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; 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); bz. w0 d8.+f30; sn w0 f15 ; if after update then jd 1<11+10; release process(catalog); ; (i.e. don't exclude other processes too long) al w1 f14 ; catoperation := read; hs. w1 d8.+f30; (only needed after update, but anyway...) al. w1 d16. ; jd 1<11+18; wait answer; 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. 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; jl. w3 e6. ; get next segment; se. w1 (h0.) ; if cur segment <> key segment then jl. g1. ; goto next segment; jl. g10. ; goto decrease entry count; 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) jl. w3 e4. ; get key segment; g10: ; 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 <key> ; 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(key, return); jl. w3 e5. ; get cat segment; 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 (h0.) ; 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: jl. w3 e6. ; get next segment; al w3 x2+f9 ; compute top address of last entry; rs. w3 h3. ; se. w1 (h0.) ; if current segment <> key segment then jl. g23. ; goto test entry; ac. w0 (h2.) ; decrease entry count by remaining entries jl. g15. ; and return; h0: 0 ; saved key h1: 0 ; saved return h2: 0 ; remaining entries h3: 0 ; top address of last entry on segment 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 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: c.(:a92>19a.1:)-1 ; if test call included then ds w3 b34 ; test output (e17); jd. w3 e29. ; z. rs. w3 d12. ; first proc: save return; jl. w3 e47. ; search best process in nametable; b3 ; b7 ; jl. e26. ;+6: not found: goto test found; al w3 x2 ; proc := proc found; rl w0 x3+a10 ; if kind.proc <> internal process then se w0 f37 ; je. j3. ; enabled goto result 3; rl. w1 d2. ; if parent.proc addr <> sender se w1 (x3+a34) ; then enabled goto error 3; je. j3. ; al w2 0 ; end chain:= children bits:= 0; rs. w2 d15. ; w3:= proc addr; b. i1 w. rs. w3 d14. ; al w0 0 ; i0: rs. w0 x2+d13. ; childrensbits:=0 al w2 x2+2 ; sh w2 a403-2 ; jl. i0. ; e. al w2 f48 ; w2:= new state:= wait stop by parent; jd. (d12.) ; disabled return; e26: je. 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: all registers changed b. g3 ; begin w. ; e18: dl. w2 d15. ; chain and add children: rs w2 x1+f26 ; wait addr.proc addr:= end chain; rs. w1 d15. ; 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: all registers changed e19: c.(:a92>19a.1:) -1 ; if test call included then ds w3 b34 ; test output (e19); jd. w3 e29. ; z. rs. w3 d12. ; add children: save return; al w0 0 ; al w1 a403 ; g3: al w1 x1-2 ; lo. w0 x1+d13. ; w0:=id bits se w1 0 ; jl. g3. ; 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 bz w1 x2+a14 ; include identbit.nametable(w3) bz. w0 x1+d13. ; nametable(w3)); lo w0 x2+a14 ; hs. w0 x1+d13. ; g1: al w3 x3+2 ; se w3 (b7) ; jl. g0. ; 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: c.(:a92>19a.1:) -1 ; if test call included then ds w3 b34 ; test output (e20); jd. w3 e29. ; z. rs. w3 d12. ; save(link) ; rl w3 b6 ; w3:=first internal in nametable ; al w1 0 ; g2: bz. w0 x1+d13. ; for all children bits do se w0 0 ; if childrenbits(w1)=0 then jl. g1. ; goto L; al w1 x1+1 ; se w1 a403 ; jl. g2. ; rl. w3 d12. ; jd x3+2 ; return 2; g1: hs w1 0 ; w0:=relative addr<12 ; g0: rl w2 x3 ; w2:=nametable(w3) ; al w3 x3+2 ; w3:=next in nametable ; so w0 (x2+a14) ; if userbit.curr.intproc is not on then jl. g0. ; goto g0 else bz w3 0 ; w3:=relative addr lx w0 x2+a14 ; remove userbits.curr.intproc hs. w0 x3+d13. ; rs. w2 d14. ; proc addr:=w2; al w3 x2 ; al w2 f50 ; new state:=wait stop by ancestor; jd. (d12.) ; 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, w3=area proc ; disabled call with link in w2 b.g30,h7 w. ; begin ; remove area: h0: 0 ; save w1: init proc h1: 0 ; save w2: link h2: 0 ; save w3: area proc 0 ; write access counter h6: 0 ; read access counter 0 ; lower base.proc h7: 0 ; upper base.proc e25: ; remove area process; ds. w2 h1. ; save(link); jl. w2 e53. ; test user and reserver(intproc,extproc); rs. w2 h2. ; h2:=result; so w2 2.1 ; if intproc is not user then je. (h1.) ; enable return else jl. w2 e52. ; exclude intproc as user; rl. w0 h2. ; w0:=result of test user and reserver; al w2 0 ; sz w0 2.10 ; if intproc is reserver then rs w2 x3+a52 ; remove intproc as reserver; al w2 1 ; ba w2 x1+a20 ; areaclaim.intproc:= hs w2 x1+a20 ; areaclaim.intproc+1; sz w0 2.100 ; if other users then je. (h1.) ; enable return al w0 0 ; sn w0 (x3+a411) ; w0=0 used below.... se w0 (x3+a412) ; if access counters<>0,0 then jl. g1. ; name(0).area:=0; rs w0 x3+a11 ; procdesc(doc).area:=0; rs w0 x3+a50 ; je. (h1.) ; enable, return; ; save statistical information in auxiliary catalog. g1: rs. w3 h2. ; save area proc; dl w2 x3+a49 ; ds. w2 v2. ; base.work:=base.proc ds. w2 h7. ; save base.proc dl w2 x3+a62+2 ; move docname.area to docname.work ds. w2 v30. ; dl w2 x3+a62+6 ; ds. w2 v31. ; dl w2 x3+a11+2 ; move name.area to name.work ds. w2 v13. ; dl w2 x3+a11+6 ; ds. w2 v14. ; rs w0 x3+a11 ; name(0).area:=0; rs w0 x3+a50 ; proc desc(doc).area:=0; rl. w1 h0. ; w1:= initproc dl w0 x3+a412 ; ds. w0 h6. ; access counters:=access counters.area; je. 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; 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; ; find all buffers sent to this area process and insert result 2. g3: rl. w3 h2. ; clear bufs: al w0 2 ; w3:=area process; rl w1 b8+4 ; w1:=first message buffer g4: sn w3 (x1+a141) ; for all messages do rs w0 x1+a141 ; if receiver.message:=areaproc then al w1 x1+a6 ; receiver.message:=2 (i.e. result 2); sh w1 (b8+6) ; jl. g4. ; rl. w1 h0. ; w1:=init proc; je. (h1.) ; 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); 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 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; ls w2 -3 ; segment := key; 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; ; procedure include user(intproc,extproc); ; reg call return ; w0 undef ; w1 intproc unchanged ; w2 link - ; w3 extproc - ; the process intproc is included as user of the external process extproc e51: ; ba w3 x1+a14 ; bz w0 x3+a402 ; w0:=userbits.intproc; lo w0 x1+a14 ; include intproc; hs w0 x3+a402 ; bs w3 x1+a14 ; reset w3 jl x2 ; return ; procedure exclude user(intproc,extproc); ; reg call return ; w0 undef ; w1 intproc unchanged ; w2 link - ; w3 extproc - ; the procedure will exclude the process addresed by intproc as user ; of the external process addressed by extproc e52: ba w3 x1+a14 ; bz w0 x3+a402 ; w0:=users.intproc; sz w0 (x1+a14) ; if intproc is user then lx w0 x1+a14 ; exclude intproc as user; hs w0 x3+a402 ; bs w3 x1+a14 ; reset w3 jl x2 ; ; procedure test users and reserver(intproc,extproc); ; reg call return ; w0 undef ; w1 intproc unchanged ; w2 link result ; w3 extproc unchanged ; the procedure set result = 2.0001 if intproc is user ; = 2.0011 if intproc is reserver (and user) ; = 2.0101 if intproc and other ip are users ; = 2.0100 if there only are other users ; = 2.1100 if another ip is reserver (and user) ; of extproc else result is set to zero b. f5,g5 w. e53: ds. w3 g1. ; save(link,w3); rl w0 x3+a52 ; w0:=reserver.extproc; al w2 2.10 ; sn w0 (x1+a14) ; if intproc is reserver then jl. f3. ; goto test other users; al w2 0 ; se w0 0 ; if there is another reserver then al w2 2.1000 ; set other-reserver bit; ba w3 x1+a14 ; w3:=addr(bitpattern.intproc); bz w0 x3+a402 ; w0:=bitpattern.intproc; sz w0 (x1+a14) ; if userbit.intproc is on then f3: al w2 x2+1 ; result:=result add 1; al w3 0 ; f0: am. (g1.) ; bz w0 x3+a402 ; w0:=next pattern.userbittable; sn w0 0 ; if no users then jl. f1. ; goto f1; hs w3 0 ; sn w0 (x1+a14) ; if only intproc is user then jl. f1. ; goto f1 else al w2 x2+2.0100 ; result:=result add 2.0100; jl. f2. ; goto f2 else f1: al w3 x3+1 ; w3:=next rel-addr se w3 a403 ; if not end bittable then jl. f0. ; goto f0; f2: rl. w3 g1. ; jl. (g0.) ; return; g0: 0 g1: 0 e. ; 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. ; ; 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: 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 b1 ; 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 e. ; ▶EOF◀