|
|
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◀