DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦748c2e06c⟧ TextFile

    Length: 92928 (0x16b00)
    Types: TextFile
    Names: »kkrcmonret«

Derivation

└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ.  Detaljer om "HC8000" projekt.
    └─⟦0364f57e3⟧ 
        └─⟦87223b8a0⟧ »kkrcmonfil« 
└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ.
    └─⟦b2ec5d50f⟧ 
        └─⟦87223b8a0⟧ »kkrcmonfil« 
            └─⟦this⟧ 

TextFile

(
message monchange release 6.2 to 7.0
clear temp mondef moncentral monprocs mondisc monfpaline monhost monfpasub,
montabinit monprocfnc1 monprocfnc2 mons1 mons2 moncatinit,
mdef mcentral mprocs mdisc mfpaline mhost mfpasub,
mtabinit mprocfnc1 mprocfnc2 ms1 ms2 mcatinit
contract entry.kkrcmonfil mondef moncentral monprocs mondisc monfpaline,
monhost monfpasub montabinit monprocfnc1 monprocfnc2 mons1 mons2 moncatinit

skip 36.1
c=copy mess.no 1
mdef=edit mondef

skip 36.1
c=copy mess.no 1
mcentral=edit moncentral 

skip 36.1
c=copy mess.no 1
mprocs=edit monprocs 

skip 36.1
c=copy mess.no 1
mdisc=entry mondisc

skip 36.1
c=copy mess.no 1
mfpaline=entry monfpaline

skip 36.1
c=copy mess.no 1
mhost=edit monhost

skip 36.1
c=copy mess.no 1
mfpasub=edit monfpasub

skip 36.1
c=copy mess.no 1
mtabinit=entry montabinit

skip 36.1
c=copy mess.no 1
mprocfnc1=entry monprocfnc1

skip 36.1
c=copy mess.no 1
mprocfnc2=edit monprocfnc2

skip 36.1
c=copy mess.no 1
ms1=edit mons1

skip 36.1
c=copy mess.no 1
ms2=edit mons2

skip 36.1
c=copy mess.no 1
mcatinit=edit moncatinit

head cpu
end)



$def
;********************
l./b.a450/,d,i/
b.a800,b200 w.
/,
l./a135/,r/=6/=7/
l./a136/, r/=2/=0/
l./i0=/,r/81 03 01/81 08 01/
l./a199=2/,l1,i/
a400=0         ; coroutine monitor inclusion (default no)
  
; **** definition of coroutine monitor formats:
;
; coroutine description;
a694 = -6         ; next in semaphore queue
a696 = -4         ; previous in semaphore queue
a698 = -2         ; priority
a700 =  0         ; save ic (return)
a702 =  2         ; next coroutine
a704 =  4         ; prev coroutine
a706 =  6         ; timer
a708 =  8         ; mask f. waitchained
a710 =  10        ; save w0(for test purposes only) or result
a712 =  12        ; save w1
a714 =  14        ; save w2
a716 =  16        ; testmask
a718 =  18        ; ident
a720 =  20        ; user exit (0 or exit addr)
a722 =  22        ; return address for waitsem,waitchained,cwaitanswer
a724 =  24        ; ref. to operation (waitchained) or buf (cwaitanswer)
  
; operation:
a670 = +0         ; next operation
a672 = +2         ; prev operation
a674 = +4         ; type
  
; chained semaphore:
a650 = +0         ; next coroutine
a652 = +2         ; prev coroutine
a654 = +4         ; next operation
a656 = +6         ; prev operation
  
; simple semaphore:
a660 = +0         ; next coroutine
a662 = +2         ; prev coroutine
a664 = +4         ; count
  
  
; second process extension.
; contains key variables of the coroutine system .
a538 = -12        ; start of testbuffer
a540 = -10        ; start of next record in test buffer
a542 = -8         ; top of test buffer
a544 = -6         ; test output flag (1 = on)
  
a546 = -4         ; next in active queue
a548 = -2         ; prev in active queue
a550 =  0         ; current coroutine
a552 =  2         ; next in timer queue
a554 =  4         ; prev in timer queue
a556 =  6         ; name of the testoutput process 
a566 =  16        ; start of testoutput message
a582 =  32        ; last event pointer
a584 =  34        ; message decriptor pointer(cur)
a586 =  36        ; start of table containing references to user defined procedures
a588 =  38        ; first message buffer extension
a590 =  40        ; start of common message-answer  area
a616 =  56        ; name of 'clock'
a626 =  66        ; start of 'clock'-message
a630 =  70        ; answer descriptor for answer from 'clock'
/,
l./a303=j0/,d,i/
a303= j0            ; top of save area
a305= j0, j0 = j0+2 ; first process extension
a306= j0, j0 = j0+2 ; second process extension
/,
l./format of device/,i/
a60 = 16           ; <mess descr>
/,f


$central
;********************
l./i0=/,r/81 01 12/81 04 06/
l./c103/,r/103/200/,
l./b26=b5/,i/
c.a400-1
b27: 0                ;124: first process extension(cur)
b28: 0                ;126: second process extension(cur)
b141:0                ;128: coroutine testoutput address
; links to cmon procedures:
b140:c100             ;130: address of cmon procedure start
     c101             ;132:        - '' -             wait
     c102             ;134:        - '' -             pass
     c103             ;136:        - '' -             inspect
     c104             ;138:        - '' -             csendmessage
     c105             ;140:        - '' -             cwaitanswer
     c106             ;142:        - '' -             answer_arrived
     c107             ;144:        - '' -             signal_binary
     c108             ;146:        - '' -             signal_sem
     c109             ;148:        - '' -             wait_sem
     c110             ;150:        - '' -             signal_chained
     c111             ;152:        - '' -             inspect_chained
     c112             ;154:        - '' -             wait_chained
     c113             ;156:        - '' -             sem_send_mess
     c114             ;158:        - '' -             sem_answer_proc
     c115             ;160:        - '' -             message_received
     c116             ;162:        - '' -             timer_message
     c117             ;164:        - '' -             timer_scan
     c118             ;166:        - '' -             cregretmessage
     c119             ;168:        - '' -             user testoutput
z.
/,
l./c99:/,l./ds w1 x3+a325/,
l./;if the new current/,i/
  
c.a400-1
; insert process extension addresses in monitor table
     dl  w1  x2+a306   ;
     wa  w0  x2+a182   ;
     wa  w1  x2+a182   ;
     ds  w1  b28       ;
z.
/,


;<* insert date of options and room for machine id.*>
l./b128=/, r/>1/>1-6/,
l1 , i/
a130        ;  date of options
a131        ;  time of options
0, r.4      ;  room for machine id.
/,
f
$procs
;********************
l./i0=/, r/81 01 12/81 04 09/
l./e57/,l1,r/c29/e58/,
r/ not used/set process extensions/,
l./d16:/,l./i14:/,l./jl (i3)/,d,i/
     jl.       (i3.)   ;    return;
/,
l./e19:/, 
l./ds w3 b15+2/, i/
     aa  w3     b15+2  ; clockchange+
/,
l.';procedure start i/o',i/
  
  
; procedure set process extension(first ext,last ext)
;
; save w0: result     (return)
; save w1: first process ext (call)
; save w2: second process ext (call)
; save w3: -
e58:
 
c.a400-1
      rl  w2  x1+a29    ; first:= save w1(cur)
      rl  w0  x1+a30    ; last:= save w2(cur)
      sl  w2  (0)       ; if last < first then
      rx  w2  0         ;    exchange(first,last)
      jl  w3  d112      ; check within(first,last)
      rl  w3  x1+a30    ; w3:= sec. proc. ext.
      rl  w2  x1+a29    ; w2:= first proc. ext.
      ds  w3  x1+a306   ; insert log. addr in process description
      wa  w2  x1+a182   ;
      wa  w3  x1+a182   ;
      ds  w3  b28       ; insert phys. addr in monitor table
      jl      r0        ; goto result 0;
z.
c.a400
      jl      c29       ;
z.
/,
 
l./e.;end of start i/,l1,i#
c.a400-1
\f

m.                coroutine monitor

;************************** c o r o u t i n e   m o n i t o r *************************
  
  
  
; locations in process extension 1 are used by cmonprocedures as described below:
;
;             -2: signalch
;      b27    +0: start
;             +2: check_eventqueue
;             +4: check_eventqueue
;             +6:
;             +8: generate_testoutput
;            +10: inspect_chained
;            +12: inspect_chained
;            +14: timermess
;            +16: timerscan
;            +18: timerscan
;            +20: generate_testoutput
;            +22:       " - "
;            +24:       " - "
\f

  b.h50 w.
  
; procedure remove(elem);
;
; removes a given element from its queue and leaves the element
; linked to itself.
;
;                 call                  return
; w0:             -                     unchanged
; w1:             -                     next(elem)
; w2:             elem                  elem
; w3:             link                  link
  
h0:   rl  w1  x2         ; begin
      rx  w2  x2+2       ;   prev(elem):= elem;
      rs  w1  x2         ;   next(prev(elem)):= next(elem);
      rx  w2  x1+2       ;   prev(next(elem)):= old prev(elem);
      rs  w2  x2         ;   next(elem):= elem;
      jl      x3         ; end;
  
   
   
; procedure link(head,elem);
;
; links the element to the end of the queue;
;
;                 call               return
; w0              -                  destroyed
; w1              head               head
; w2              elem               elem
; w3              link               old last(head)
  
  
h1:   al  w0  x3         ; begin
      rl  w3  x1+2       ;   old prev:= last(head);
      rs  w2  x1+2       ;   prev(head):= elem;
      rs  w2  x3+0       ;   next(old prev):= elem;
      rs  w1  x2+0       ;   next(elem):= head;
      rs  w3  x2+2       ;   prev(elem):= old prev;
      rl  w3  0          ;
      jl      x3         ; end;
\f

  
; procedure get_mess_ext(ref);
;
; returns a reference to the first free message buffer extension
; or 0 if no extensions are available. the extension is removed from the chain.
;
;                 call                return
; w0:             -                   destroyed
; w1:             -                   destroyed
; w2:             -                   ref or 0
; w3:             link                link
 
b.j5 w.
h7:   rl  w1  b28        ; begin
      rl  w2  x1+a588    ;   ref:= cur.ext2.buffer_extension_head;
      sn  w2  0          ;   if ref <> 0 then
      jl.     j0.        ;   begin
      rl  w0  x2         ;     cur.ext2.buffer_extension_head:= next(ref);
      rs  w0  x1+a588    ;     

      al  w2  x2+2       ;     ref:= ref+2;
                         ;   end;
j0:   jl      x3         ; end;
e.
  
\f

; procedure answer arrived(buf,ref);
;
; is called from procedure 'check_event_queue' when an answer appears in
; the event queue and 'ref.open' is true, i. e. when a coroutine has
; called 'cwaitanswer(buf)'. the coroutine is activated and the answer
; descriptor is closed.
;
;                 call                return
; w0:             -                   destroyed
; w1:             ref                 destroyed
; w2:             buf                 buf
; w3:             link                link
  
b.j5 w.
c106: am      (b27)      ; begin
      ds  w3  +6         ;   ext1(4,6):= (buf,link);
      am     (b28)       ;
      rl  w3  +a544      ;
      sn  w3  0          ;   if testoutput active 
      jl.     j0.        ;    then generate testoutput(1<6);
      jl. w3  h4.        ;
              3<22+1<6   ;
j0:   al  w0  0          ;
      hs  w0  x1         ;   ref.open:= false;
      rl  w2  x1+2       ;   corout:= ref.param1;
      al  w1  1          ;   result:= ok;
      rl  w0  x2+a698    ;   priority:= corout.priority;
      jl. w3  c100.      ;   start(corout,priority,ok);
      am      (b27)      ;
      dl  w3  +6         ;   (buf,link):= ext1(4,6);
      jl      x3         ; end;
e.
  
\f

; procedure central wait;
;  
; central waiting point in coroutine system. checks the eventqueue
; and schedules pending events. if the active queue is empty the
; monitor procedure wait event is called otherwise the first co-
; routine is started. if 'corout.user_exit' <> 0 a jump to 'user_exit' is
; made with register contents:
;       w0:   -
;       w1:   -
;       w2:   current_coroutine
;       w3:   link
  
  
b.j5
w.
h2:                      ; begin
                         ;   repeat
j0:   jl. w3  h6.        ;     check event queue;
      rl  w2  b28        ;     if active queue empty then
      rl  w3  x2+a546    ;     begin
      se  w3  x2+a546    ;       buf:= cur.ext2.last event;
      jl.     j1.        ;       wait event(buf,result);
      rl  w2  x2+a582    ;
      jd      1<11+24    ;
      jl.     j0.        ;
                         ;     end;
j1:   al  w2  x3-2       ;   until active queue not empty;
      rs  w2  (b28)      ;   corout:= first in active queue;
      rl  w1  x2+a720    ;   if corout.user_exit <> 0
      se  w1  0          ;      then jump to user_exit;
      jl  w3  x1         ;
      rl  w3  (b28)      ;
      dl  w1  x3+a712    ;
      rl  w2  x3+a714    ;   restart corout;;
      jl      (x3)       ; end;
e.
\f

  
  
; procedure check eventqueue;
;
; inspects the eventqueue starting at 'last event'('last event' = 0
; if the queue must be inspected from the start). pending events
; which have arrived after 'last event' are scheduled if
; 'event descriptor.open' = true. the scheduling is performed by calling
; either a 'cmon'-standard procedure (even procedure number in event
; descriptor) or a user defined procedure (odd procedure number which
; is used as index in the procedure table in process extension 2).
;  
  
; a procedure ('user' or 'cmon') which is used for scheduling answers or messages
; must return with w2=0 if the answer/message is removed from the event queue
; - otherwise with w2='buf' ; i. e. the event queue must be inspected from the
; start when an event is removed by a scheduling procedure.
  
; exit to 'cmon'- or user-procedure with:
; w0:     -
; w1:     ref(event descriptor)
; w2:     buf
; w3:     link
  
b. j10 w.
h6:   am      (b27)       ; begin
      rs  w3  +2          ;   ext1(2):= link;
      rl  w3  b28         ;
      rl  w2  x3+a582     ;   last_buf:= cur.ext2.last_event;
j0:   jd      1<11+66     ;   repeat
      rl  w3  b28         ;
      sh  w0  -1          ;     test_event(last_buf,buf,result);
      jl.     j5.         ;     if result <> empty then
      se  w0  0           ;     begin
      jl.     j2.         ;       if result = message
      rl  w1  x2+4        ;
      ac  w1  x1          ;
      se  w1  (b1)        ;          then ref:= 
      jl.     j1.         ;               if buf.receiver = cur then cur.ext2.messdescr
      rl  w1  x3+a584     ;               else buf.receiver.messdescr <* pseudoprocess *>
      jl.     j2.         ;
j1:   rl  w1  x1+a60      ;          else <* answer *> ref:= buf.ref;
j2:   hl  w0  x1          ;
      sn  w0  0           ;
      jl.     j0.         ;       if ref.open then
      hl  w0  x1+1        ;       begin
      sz  w0  1           ;         if even procedure number
      jl.     j3.         ;             then call cmonproc(buf,ref);
      am      (0)         ;             
      jl  w3  (130)       ;               
      jl.     j0.         ;             else
j3:                       ;             begin <* odd procedure number *>
      rl  w3  x3+a586     ;               <* use procedure number in event *>
      hl  w0  x1+1        ;               <* descriptor as index in proce- *>
      ls  w0  +1          ;               <* dure table in cur.ext2        *>
      wa  w0  x3          ;
      am      (0)         ;
      jl  w3  (0)         ;                call userproc(buf,ref);
      jl.     j0.         ;             end;
                          ;       end;
                          ;     end;
                          ;   until result = empty;
j5:   sn  w2  0           ;   <* if 'last_buf' points at a message , 'last_event'
      jl.     j6.         ;   <* must be reset as the message may be regretted
      rl  w0  x2+4        ;   <* before next scan.
      se  w0  0           ;
      sz  w0  -8          ;   cur.ext2.last_event:= if last_buf points at message
      al  w2  0           ;                            then 0
j6:   rs  w2  x3+a582     ;                            else last_buf;
      am      (b27)       ;   link:= ext1(2);
      jl      (2)         ; end;
e.
\f

  
  
; procedure entry pass(priority);
;
; pending events are scheduled and calling  coroutine is restarted
; with the priority given in call.
;
;             call               return
; w0:         priority           destroyed
; w1:         -                  destroyed
; w2:         -                  destroyed
; w3:         link               current coroutine
  
b.j5 w.
c102:  am      (b28)      ; begin
       rs  w3  (0)        ;   current_coroutine.ic:= link;
       am     (b28)       ;
       rl  w3  +a544      ;
       sn  w3  0          ;   if testoutput active
       jl.     j0.        ;      then generate testoutput(testkind);
       jl. w3  h4.        ;
               3<22+1<2   ;
j0:    rl  w2 (b28)       ;
       rl  w1  x2+a710    ;   result:= current_coroutine.result;
       jl. w3  c100.      ;   start(current_coroutine,priority,result);
       jl.     h2.        ;   central wait;
e.                        ; end;
\f

  
; procedure entry inspect(priority,result);
;
; schedules pending events and checks if the active queue contains
; coroutines with priority higher than the call parameter 'priority'. in
; this case 'result' returns true (1).
;
;               call               return
; w0:           priority           result
; w1:           -                  destroyed
; w2:           -                  destroyed
; w3:           link               current coroutine
  
b.j5 w.
c103:  am      (b28)      ; begin
       rs  w3  (0)        ;   current_coroutine.ic:= link;
       am     (b28)       ;
       rl  w3  +a544      ;
       sn  w3  0          ;   if testoutput is active then
       jl.     j0.        ;   generate testoutput(1<3);
       jl. w3  h4.        ;
               3<22+1<3   ;
j0:    rs  w0  (b27)      ;   ext1(0):= priority;
       jl. w3  h6.        ;   check_event_queue;
       rl  w0  (b27)      ;   priority:= ext1(0);
       rl  w3  b28        ;
       rl  w3  x3+a546    ;   corout:= first in active queue;
       sl  w0  (x3-4)     ;
       am      -1         ;   result:= corout.prio > priority;
       al  w0  1          ;
       rl  w3  (b28)      ;
       jl      (x3)       ; end;
e.
  
\f

; procedure entry start(corout,priority,result);
;
; removes the coroutine from its queue (normally the timer queue) and
; inserts it in active queue according to the call parameter 'priority'.
; the call parameter 'result' is returned in w0 of
; the coroutine which is activated.
;
;                 call               return
; w0:             priority           destroyed
; w1:             result             destroyed
; w2:             corout             corout
; w3:             link               current coroutine
  
b.j5
w.
c100: rs  w3  (b27)      ; begin
      am     (b28)       ;
      rl  w3  +a544      ;
      sn  w3  0          ;   if testoutput is active then
      jl.     j0.        ;      generate testoutput(1<0);
      jl. w3  h4.        ;
              3<22+1<0   ;
j0:   rs  w1  x2+a710    ;   corout.result:= result;
      rs  w0  x2+a698    ;   corout.priority:= priority;
      al  w2  x2+2       ;
      jl. w3  h0.        ;   remove(corout);
      rl  w1  0          ;
      al  w0  x2         ;
      rl  w2  b28        ;   worse:= rear of active queue;
      al  w3  x2+a546    ;   while worse.prio > prio        and
      al  w1  x1+1       ;         worse <> active queue head do
j1:   rl  w3  x3+2       ;   worse:= prev(worse);
      sn  w3  x2+a546    ;
      jl.     j2.        ;   'insert corout in the rear of 
      sh  w1  (x3-4)     ;    other coroutines of the same
      jl.     j1.        ;    priority'
j2:   rl  w1  x3         ;
      rl  w2  0          ;
      jl. w3  h1.        ;   link(worse,corout);
      al  w2  x2-2       ;

      rl  w3  (b28)      ;
      am      (b27)      ;
      jl      (0)        ; end;
e.
 
\f

; procedure entry wait(timer,result);
;
; calling coroutine is suspended for max 'timer' seconds.
; 'timer' = 0 indicates no timeout. the return parameter 'result'
; indicates whether the coroutine was started by timeout or by 
; the arrival of an internal or external event.
;
;                  call                return
; w0:              timer               result
; w1:              -                   destroyed
; w2:              -                   -
; w3               link                current coroutine
  
b.j5
w.
c101: am      (b28)      ; begin
      rs  w3  (0  )      ;   current coroutine.return:= link;
      am     (b28)       ;
      rl  w3  +a544      ;
      sn  w3  0          ;   if testoutput active then
      jl.     j0.        ;   generate testoutput(1<1);
      jl. w3  h4.        ;
              3<22+1<1   ;
j0:   rl  w2  (b28)      ;   current coroutine.timer:= timer;
      rs  w0  x2+a706    ;
      al  w2  x2+2       ;
      jl. w3  h0.        ;   remove(current coroutine);
      rl  w3  b28        ;
      al  w1  x3+a552    ;
      jl. w3  h1.        ;   link(timer queue head,current coroutine);
      jl.     h2.        ;   central wait;
                         ; end;
e.
  
\f

; procedure entry csendmessage(mess,name,buf);
;
; allocates a message buffer extension and prepares it for cwaitanswer.
; then calls sendmessage.
;
; return parameter 'buf': 0        buffer claims exceeded
;                         1        no free extensions
;                        >1        message buffer address
;
;               call               return
; w0:           -                  destroyed
; w1:           mess               destroyed
; w2:           name               buffer address (or 0 or 1)
; w3:           link               current coroutine
 
b.j5,i5 w.
c104:  am      (b28)       ; begin
       rs  w3  (0)         ;   current_coroutine.ic:= link;
       am     (b28)        ;
       rl  w3  +a544       ;
       sn  w3  0           ;
       jl.     j0.         ;   if testoutput active
       jl. w3  h4.         ;      then generate_testoutput(1<4);
               3<22+1<4    ;
j0:    ds  w2  (b27)       ;
       jl. w3  h7.         ;   get_mess_ext(ref);
       sn  w2  0           ;   if ref <> 0 <* extension available *> then
       jl.     j1.         ;   begin
       rl. w0  i0.         ;     <* initialize answer descriptor *>
       rs  w0  x2          ;     ref.open:= false; ref.proc:= 12;
       rl  w3  b27         ;
       rs  w2  x3+2        ;     ext1(2):= ref;
       rl  w1  x3-2        ;
       rl  w3  x3          ;     send message(mess,name,buf,ref);
       jd      1<11+16     ;
       se  w2  0           ;     if buffer claims exceeded
       jl.     j2.         ;        then release message buffer extension;
       am      (b27)       ;
       rl  w1  (+2)        ;
       rl  w3  b28         ;
       al  w0  x1-2        ;
       rx  w0  x3+a588     ;
       rs  w0  x1-2        ;
       jl.     j2.         ;
j1:    al  w2  1           ;   end
j2:    rl  w3  (b28)       ;   else buf:= 1; <* no free extensions *>
       jl      (x3)        ; end;
  
i0:    0<12+12             ; answer descriptor init (open=false,proc='answer_arrived')
e.
  
\f

; procedure entry cwaitanswer(buf,timer,result);
;
; prepares the message buffer extension for receiving the answer. if
; the buffer has been answered, 'last_event' is reset as the buffer
; may have been skipped during an earlier inspection of the event queue.
; the coroutine waits for max. 'timer' seconds for the answer. when the
; coroutine is restarted the action depends on 'result':
;
; result = timeout              : the answer descriptor is closed
;
; result = answer arrived       : the answer is received in the answer
;                                 area in process extension 2 and the message
;                                 buffer extension is released.
;
;               call              return
; w0:           timer             result (timeout:0,wait_answer result:1,2,3,4,5)
; w1:           -                 answer area in ext2 if result <> timeout
; w2:           buf               buf
; w3:           link              current coroutine
  
b.j10 w.
c105:  rs  w3  (b27)       ; begin
       am     (b28)        ;
       rl  w3 +a544        ;
       sn  w3  0           ;
       jl.     j0.         ;   if testoutput active
       jl. w3  h4.         ;      then generate_testoutput(1<5);
               3<22+1<5    ;
j0:    rl  w3  (b28)       ;
       rl  w1  (b27)       ;   current_coroutine.return:= link;
       ds  w2  x3+a724     ;   current_coroutine.buf:= buf;
       rs  w0  (b27)       ;   ext1(0):= timer;
       rl w1  x2-2         ;   with buf.ref do
       al  w0  1           ;   begin
       hs  w0  x1          ;     open:= true;
       rs  w3  x1+2        ;     corout:= current_coroutine;
                           ;   end;
       rl  w0  x2+4        ;
       sz  w0  -8          ;   if buf.state = answer pending
       jl.     j1.         ;     then last_event:= 0; <* inspect from start *>
       al  w0  0           ;
       am      (b28)       ;
       rs  w0  +a582       ;
j1:    rl  w0  (b27)       ;   timer:= ext1(0);
       jl. w3  c101.       ;   wait(timer,result);
       rl  w2  x3+a724     ;   buf:= current_coroutine.buf;
       rl  w1  x2-2        ;   ref:= buf.ref;
       se  w0  0           ;   if result = timeout
       jl.     j2.         ;      then ref.open:= false
       hs  w0  x1          ;
       jl.     j4.         ;      else
j2:                        ;      begin <* result = answer arrived *>
       rl  w3  b28         ;        release message buffer extension;
       al  w0  x1-2        ;
       rx  w0  x3+a588     ;
       rs  w0  x1-2        ;
       se  w2  (x3+a582)   ;
       jl.     j3.         ;
       al  w0  0           ;        if buf = last_event then last_event:= 0;
       rs  w0  x3+a582     ;
j3:    al  w1  x3+a590     ;
       jd      1<11+18     ;        wait answer(buf,cur.ext2.answer_area);
j4:    rl  w3  (b28)       ;      end;
       jl      (x3+a722)   ;   end;
e.                         ; end;
  
\f

; procedure entry signal binary(sem);
; procedure entry        signal(sem);
;
;                call             return
; w0:            -                destroyed
; w1:            -                destroyed
; w2:            sem              destroyed
; w3:            link             current coroutine
  
b.j5 w.
c107:  am      1           ; signal_binary:
c108:  al  w0  0           ; signal:
       am      (b28)       ; begin
       rs  w3  (0)         ;
       am     (b28)        ;
       rl  w3 +a544        ;
       sn  w3  0           ;   if testoutput active 
       jl.     j0.         ;      then generate_testoutput(1<7);
       jl. w3  h4.         ;
               3<22+1<7    ;
j0:    rl  w1  x2+4        ;   with sem do
       al  w3  x1+1        ;   begin
       se  w0  0           ;     count:= count+1;
       la  w3  0           ;     if binary 
       rs  w3  x2+4        ;        then count:= count and 1;
       sl  w1  0           ;      if count <= 0 then
       jl.     j1.         ;      begin
       rl  w2  x2          ;        corout:= next(sem);
       jl. w3  h0.         ;        remove(corout);
       al  w2  x2+6        ;
       rl  w0  x2+a698     ;        priority:= corout.prio;
       al  w1  1           ;        result:= ok;
       jl. w3  c100.       ;        start(corout,priority,result);
j1:    rl  w3  (b28)       ;     end;
       jl      (x3)        ;   end;
e.                         ; end;
  
\f

; procedure entry wait_semaphore(sem);
;             
;               call               return
; w0:           -                  destroyed
; w1:           -                  destroyed
; w2:           sem                destroyed
; w3:           link               current coroutine
  
b.j5 w.
c109:  am      (b28)      ; begin
       rs  w3  (0)        ;
       am     (b28)       ;
       rl  w3 +a544       ;
       sn  w3  0          ;   if testoutput active
       jl.     j0.        ;      then generate_testoutput(1<8);
       jl. w3  h4.        ;
               3<22+1<8   ;
j0:    rl  w1  x2+4       ;   with sem do
       al  w1  x1-1       ;   begin
       rs  w1  x2+4       ;     count:= count-1;
       rl  w3  (b28)      ;
       sl  w1  0          ;     if count < 0 then
       jl      (x3)       ;     begin
       rl  w1  x3         ;
       rs  w1  x3+a722    ;       current_coroutine.return:= link;
       al  w1  x2         ;       head:= sem.coroutine_queue_head;
       al  w2  x3-6       ;       elem:= current_coroutine.sem_queue_elem;
       jl. w3  h1.        ;       link(head,elem);
       al  w0  0          ;       timer:= 0 <* no timeout *>
       jl. w3  c101.      ;       wait(timer);
       rl  w3  (b28)      ;     end;
       jl      (x3+a722)  ;   end with;
e.                        ; end;
  
\f

; procedure entry signal_chained(sem,oper);
;
; signals an operation to a chained semaphore. if the coroutine queue of
; the semaphore contains a coroutine which is waiting for an operation
; of this type,the coroutine is started. otherwise the operation is
; queued to the semaphore.
;
;    two reserved types exist:
;        1<0: message
;        1<1: answer
;
;                  call               return
; w0:              -                  destroyed
; w1:              operation          destroyed
; w2:              semaphore          destroyed
; w3:              link               current coroutine
  
b.j10 w.
c110:  am      (b27)      ; begin
       rs  w3  -2         ;
       am     (b28)       ;
       rl  w3 +a544       ;
       sn  w3  0          ;
       jl.     j0.        ;   if testoutput active
       jl. w3  h4.        ;      then generate_testoutput(1<9);
               3<22+1<9   ;
j0:    rl  w3  x2         ;   head:= sem.coroutine_queue_head;
j1:    sn  w3  x2         ;   corout:= next(head); found:= false;
       jl.     j4.        ;   while corout <> head and -, found do
       rl  w0  x3-a694+a708;    if logand(corout.mask,oper.type) <> 0 then
       la  w0  x1+4       ;     begin
       se  w0  0          ;       
       jl.     j3.        ;       found:= true;
       rl  w3  x3         ;
       jl.     j1.        ;
j3:    rs  w1  x3-a694+a724;      corout.latop:= operation;
       rl  w0  x1+4       ;       type:= oper.type;
       al  w2  x3         ;
       jl. w3  h0.        ;       remove(corout);
       al  w2  x2-a694    ;
       rl  w1  0          ;       result:= type;
       rl  w0  x2+a698    ;       priority:= corout.prio;
       jl. w3  c100.      ;       start(corout,priority,result);
       jl.     j5.        ;     end
                          ;     else corout:= next(corout);
j4:    rx  w2  2          ;   if -,found
       al  w1  x1+4       ;      then link(sem.operation_queue,oper);
       jl. w3  h1.        ;
j5:    rl  w3  (b28)      ;
       am      (b27)      ;
       jl      (-2)       ; end;
e.
  
\f

; procedure entry inspect_chained(sem,mask,oper,result);
;
; checks if 'sem_operation_queue' contains an operation which matches 'mask'.
; if no matching operation is found,  'oper' returns = 0,
; otherwise 'oper' refers to the first matching operation.
; 'result' returns 'true' (1) if the active queue contains coroutines of
; priorities higher than  the priority of calling coroutine.
;
;                 call               return
; w0:             -                  (result= 0,1)
; w1:             mask               oper or 0
; w2:             sem                sem
; w3:             link               current coroutine
  
b.j10 w.
c111:  am      (b28)       ; begin
       rs  w3  (0)         ;
       am     (b28)        ;
       rl  w3 +a544        ;
       sn  w3  0           ;   if testoutput active
       jl.     j0.         ;      then generate_testoutput(1<10);
       jl. w3  h4.         ;
               3<22+1<10   ;
j0:    am      (b27)       ;
       rs  w2  +12         ;   save(sem);
       al  w0  x1          ;
       rl  w1  x2+4        ;   head:= sem.operation_queue_head;
j1:                        ;   oper:= next(head); found:= false;
       sn  w1  x2+4        ;   while oper <> head and -,found do
       jl.     j3.         ;     if logand(oper.type,mask) <> 0
       rl  w3  x1+4        ;        then found:= true
       la  w3  0           ;        else oper:= next(oper);
       se  w3  0           ;
       jl.     j4.         ;
       rl  w1  x1          ;
       jl.     j1.         ;
j3:    al  w1  0           ;   if -,found then oper:= 0;
j4:    rl  w3  (b28)       ;
       rl  w0  x3+a698     ;   priority:= current_coroutine.prio;
       rl  w2  b28         ;
       rl  w2  x2+a546     ;   corout:= first in active queue;
       sh  w0  (x2-4)      ;
       am      -1          ;
       al  w0  1           ;   result:= corout.prio > priority;
       am      (b27)       ;
       rl  w2  +12         ;
       jl      (x3)        ; end;
e.
  
\f

; procedure entry wait_chained(sem,mask,timer,oper);
;
; if 'sem.operation_queue' contains an operation
; which matches 'mask', the operation is removed from the queue . a 'pass'
; is executed if the active queue contains coroutines of priorities higher
; than the priority of calling coroutine. if no matching operation is found
; pending events are scheduled and the calling coroutine waits for max. 'timer'
; seconds for an operation to arrive.
; 
; if the operation contains a message or an answer ('oper.type' = 1<0 or 1<1 ,
; resp ) , the buffer contents is copied to the common message-answer area in
; process extension 2. a buffer containing an answer is removed from the event
; queue by 'waitanswer'.
; 
;
;                  call                return
; w0:              timer               result ( 0(timeout) or oper.type)
; w1:              mask                oper (undefined if result = timeout)
; w2:              sem                 destr.
; w3:              link                current_coroutine
  
b.j10 w.
c112:  rs  w3  (b27)          ; begin
       am     (b28)           ;
       rl  w3 +a544            ;
       sn  w3  0              ;   if testoutput active
       jl.     j0.            ;      then generate_testoutput(1<11);
       jl. w3  h4.            ;
               3<22+1<11      ;
j0:    rx  w1  (b27)          ;
       rl  w3  (b28)          ;
       rs  w1  x3+a722        ;   current_coroutine.return:= link;
       rx  w1  (b27)          ;   current_coroutine.waitch_mask:= mask;
       ds  w1  x3+a708        ;   current_coroutine.timer:= timer;
       jl. w3  c111.          ;   inspect_chained(sem,mask,oper,result);
       se  w1  0              ;   if oper = 0 then
       jl.     j1.            ;   begin <* wait in semaphore queue *>
       al  w1  x2             ;     head:= sem.coroutine_queue_head;
       al  w2  x3+a694        ;     elem:= current_coroutine.sem_queue_elem;
       jl. w3  h1.            ;     link(head,elem);
       rl  w0  x2-a694+a706   ;     timer:= current_coroutine.timer;
       jl. w3  c101.          ;     wait(timer,result);
       se  w0  0              ;     if result = timeout then
       jl.     j3.            ;     begin
       rs  w0  x3+a710        ;       current_coroutine.result:= timeout;
       al  w2  x3+a694        ;       elem:= current_coroutine.sem_queue_elem;
       jl. w3  h0.            ;       remove(elem);
       jl.     j6.            ;       goto exit;
                              ;     end;
                              ;   end;
j1:    rs  w1  x3+a724        ;   current_coroutine.latop:= oper;
       rl  w2  x1+4           ;
       rs  w2  x3+a710        ;   current_coroutine.result:= oper.type;
       al  w2  x1             ;
       jl. w3  h0.            ;   remove(oper);
       rl  w3  (b28)          ;   if waiting <* coroutines of higher 
       sn  w0  0              ;      priority in active queue *> then
       jl.     j2.            ;   begin
       rl  w0  x3+a698        ;     priority:= current_coroutine.prio;
       jl. w3  c102.          ;     pass(priority);
                              ;   end;
j2:    rl  w0  x3+a710        ;
j3:    sz  w0  -4             ;   if oper.type = message or answer then
       jl.     j6.            ;   begin
       rl  w2  x3+a724        ;     oper:= current_coroutine.latop;
       rl  w3  b28            ;
       rl  w2  x2+8           ;     buf:= oper.buf;
       se  w0  1<1            ;     if oper.type = answer then
       jl.     j5.            ;     begin
       se  w2  (x3+a582)      ;
       jl.     j4.            ;        if buf = last_event
       al  w0  0              ;           then last_event:= 0;
       rs  w0  x3+a582        ;
j4:    al  w1  x3+a590        ;        area:= common message-answer area;
       jd      1<11+18        ;        waitanswer(buf,area);
       jl.     j6.            ;     end
j5:    al  w1  x3+a590        ;     else
       dl  w0  x2+10          ;     begin <* message *>
       ds  w0  x1+2           ;
       dl  w0  x2+14          ;
       ds  w0  x1+6           ;
       dl  w0  x2+18          ;        <* copy to common massage-answer area *>
       ds  w0  x1+10          ;
       dl  w0  x2+22          ;
       ds  w0  x1+14          ;     end;
                              ;   end;
j6:    rl  w3  (b28)          ; exit:
       rl  w0  x3+a710        ;   result:= current_coroutine.result;
       rl  w1  x3+a724        ;   oper:= current_coroutine.latop; <* undef if timeout *>
       jl      (x3+a722)      ;
e.                            ; end;
  
\f

; procedure entry sem_sendmessage(name,message,oper,sem.result);
;
; sends a massage to the process given by 'name'. when the answer arrives
; it is signalled to the chained semaphore 'sem'. the calling coroutine must
; provide the operation 'oper' which is used as:
; 
;       1)  message_buffer_extension     and   2)  answer_operation(sem_answer_proc)
;       -6  (next operation)              oper +0  next operation
;       -4  (prev operation)                   +2  prev operation
;       -2  (type)                             +4  type=answer(1<1)
;  ext. +0  open,'sem_answer_proc'             +6  -
;       +2  answer_sem                         +8  buffer address
;
;
;            call                  return
; w0:        sem                   destr.
; w1:        params                destr.
; w2:        oper                  buffer addres ( or 0 = claims exceeded )
; w3:        link                  current coroutine
;
; 'params' points at a parameter area containing:
; 
;  params  +0: name(1)
;          +2: name(2)
;          +4: name(3)
;          +6: name(4)
;          +8: name table address
;         +10: mess(1)
;         +12: mess(2)
;               etc.
  
b.j5,i5 w.
c113:  am      (b28)        ; begin
       rs  w3  (0)          ;
       am     (b28)         ;
       rl  w3 +a544         ;
       sn  w3  0            ;   if testoutput active
       jl.     j0.          ;      then generate_testoutput(1<12);
       jl. w3  h4.          ;
               3<22+1<12    ;
j0:    rs  w0  (b27)        ;   with oper.answer_descriptor do
       rl. w0  i0.          ;   begin
       rs  w0  x2+6         ;     proc:= sem_answerproc;
       rl  w0  (b27)        ;     open:= true;
       rs  w0  x2+8         ;     answer_sem:= sem;
       al  w3  x1           ;   end;
       al  w1  x1+10        ;   name_address:= params;
                            ;   message_address:= params+10;
       al  w2  x2+6         ;   ref:= oper.answer_descriptor;
       jd      1<11+16      ;   sendmessage(name_addres,message_address,ref,result);
       rl  w3  (b28)        ;
       jl      (x3)         ; end;
  
i0:    1<12+28              ; answer_descriptor init;
  
e.
  
\f

; procedure sem_answer_proc(ref,buf);
;
; this procedure is called from procedure 'check_event_queue' when an
; answer to a message, sent by 'sem_sendmessage, has arrived. 'ref'
; contains the address of the answer_descriptor and 'buf' contains the
; message buffer address. the answer is signalled to the chained semaphore
; given in answer_descriptor.
; 
;                call             return
; w0:            -                destr.
; w1:            ref              destr.
; w2:            buf              buf
; w3:            link             link
  
b.j5 w.
c114:   am      (b27)         ; begin
        ds  w3  +6            ;
        am     (b28)          ;
        rl  w3 +a544          ;
        sn  w3  0             ;   if testoutput active
        jl.     j0.           ;      then generate_testoutput(1<13);
        jl. w3  h4.           ;
                3<22+1<13     ;
j0:     al  w0  0             ;   with ref do
        hs  w0  x1            ;   begin
        al  w0  1<1           ;     open:= false;
        rs  w0  x1-2          ;     type:= answer;
        rx  w2  x1+2          ;     sem:= answer_sem;
        al  w1  x1-6          ;     buffer:= buf;
        jl. w3  c110.         ;     signal_chained(sem,operation);
        am      (b27)         ;   end;
        dl  w3  +6            ;
        jl      x3            ; end;
e.
  
\f

; procedure message_received(buf,ref);
;
; this procedure is called from 'check_event_queue' when a message is
; received and mess_descr.proc = 'message_received'. the message descriptor
; must contain an operation and the address of a chained semaphore.
;
;                  message_descriptor          message_operation
;             -6:  next operation              -
;             -4:  prev operation              -
;             -2:  type                        type = message (1<0)
; mess_descr  +0:  open,'message_received'     -
;             +2:  semaphore address           buffer address
;  
; 
;             call              return
; w0:         -                 destr.
; w1:         ref               destr.
; w2:         buf               0 (the message buffer is removed)
; w3:         link              link
  
b.j5 w.
c115:   am      (b27)         ; begin
        rs  w3  +6            ;
        am     (b28)          ;
        rl  w3 +a544          ;
        sn  w3  0             ;   if testoutput active
        jl.     j0.           ;      then generate_testoutput(1<14);
        jl. w3  h4.           ;
                3<22+1<14     ;
j0:     jd      1<11+26       ;   getevent(buf);
        al  w0  0             ;   with ref do
        hs  w0  x1            ;   begin
        al  w0  1<0           ;     open:= false; <* the message class must be
                              ;                      explicitly opened by a
                              ;                      receiving coroutine  *>
        rs  w0  x1-2          ;     oper.type:= message;
        rx  w2  x1+2          ;     oper.buffer:= buf;
        al  w1  x1-6          ;     sem:= message_sem;
        jl. w3  c110.         ;     signal_chained(sem,oper);
        am      (b27)         ;   end;
        rl  w3  +6            ;
        al  w2  0             ;   buf:= 0; <* has been removed *>
        jl      x3            ; end;
e.
  
\f

; procedure entry timer_message;
; 
; sends a delay-message to 'clock'.
;
;           call             return
; w0:       -                unchanged
; w1:       -                destr.
; w2:       -                buf or 0
; w3:       link             current_coroutine
  
b.j5 w.
c116:    am      (b27)        ; begin
         rs  w3  +14          ;
         am     (b28)         ;
         rl  w3 +a544         ;
         sn  w3  0            ;    if testoutput active
         jl.     j0.          ;       then generate_testoutput(1<15);
         jl. w3  h4.          ;
                 3<22+1<15    ;
j0:      rl  w3  b28          ;
         al  w1  x3+a626      ;    mess:= cur.ext2.delaymess;
         al  w2  x3+a630      ;    ref:= cur.ext2.answer_descr;
         al  w3  x3+a616      ;    name:= <:clock:>;
         jd      1<11+16      ;    sendmessage(name,mess,ref,result);
         rl  w3  (b28)        ;
         am      (b27)        ;
         rl  w1  +14          ;
         jl      x1           ; end;
e.
  
\f

; procedure timerscan(ref,buf);
;
; this procedure is called from 'check_event_queue' when an answer arrives
; from 'clock'. the timer queue is inspected and coroutines which time out
; are started with result = timeout. after the inspection a delay-message is
; sent to 'clock'.
;
;            call              return
; w0:        -                 destr.
; w1:        ref               destr.
; w2:        buf               0 (the message buffer is removed)
; w3:        link              link
  
b.j5,i5 w.
c117:   am     (b27)         ; begin
        rs  w3  +16          ;   ext1(16):= link;
        am     (b28)         ;
        rl  w3 +a544         ;
        sn  w3  0            ;   if testoutput active
        jl.     j0.          ;      then generate_test_output(1<16);
        jl. w3  h4.          ;
                3<22+1<16    ;
j0:     rl  w3  b28          ;
        al  w1  x3+a566      ;   <* release messagebuffer *>
        jd      1<11+18      ;   wait_answer(cur.ext2.test_mess_area,buf);
j4:                          ;
        al  w2  x3+a552      ;   corout:= first in timer queue;
j1:     rl  w2  x2           ;   while corout <> timer queue head do
j3:     sn  w2  x3+a552      ;   begin
        jl.     j2.          ;     corout:= next(corout);
        rl  w1  x2+4         ;     with corout do
        sh  w1  0            ;     begin
        jl.     j1.          ;       if timer > 0 then
        al  w1  x1-1         ;       begin
        rs  w1  x2+4         ;
        se  w1  0            ;         timer:= timer-1;
        jl.     j1.          ;         if timer = 0 
        rl  w0  x2           ;            then start(corout,prio,timeout);
        am      (b27)        ;
        rs  w0  +18          ;
        al  w2  x2-2         ;
        rl  w0  x2+a698      ;       end;
        al  w1  0            ;     end;
        jl. w3  c100.        ;
        am      (b27)        ;
        rl  w2  +18          ;
        rl  w3  b28          ;
        jl.     j3.          ;   end while;
j2:     jl. w3  c116.        ;   timer_message;
        am      (b27)        ;
        rl  w3  +16          ;   link:= ext1(16);
        al  w2  0            ;   buf:= 0; <* has been removed *>
        jl      x3           ; end;
e.
  
\f

; procedure entry cregretmessage(buf);
;
; this procedure is used to regret a message sent by csendmessage, i. e. the
; monitor procedure 'regretmessage' is called and the corresponding message
; buffer extension is released.
;
;            call              return
; w0:        -                 destr.
; w1:        -                 destr.
; w2:        buf               buf
; w3:        link              current_coroutine
  
b.j5 w.
c118:   am      (b28)        ; begin
        rs  w3  (0)          ;
        am     (b28)         ;
        rl  w3 +a544         ;
        sn  w3  0            ;   if testoutput active
        jl.     j0.          ;      then generate test_output(1<17);
        jl. w3  h4.          ;
                3<22+1<17    ;
j0:     jd      1<11+82      ;   regretmessage(buf);
        rl  w1  x2-2         ;   ref:= buf.ref;
        rl  w3  b28          ;   ext:= next(message_buffer_ext_head);
        al  w0  x1-2         ;   next(message_buffer_ext_head):= ref;
        rx  w0  x3+a588      ;   next(ref):= ext;
        rs  w0  x1-2         ;
        rl  w3  (b28)        ;
        jl      (x3)         ; end;
e.
\f

   
   
; procedure entry testout
;
;
; this procedure creates a user test record defined by the registers
; as follows:
;
;             call                       return
; w0:         testrecord ident           unch.
; w1:         start address              unch.
; w2:         no_of_halfwords            unch.
; w3:         link                       current coroutine
  
b.j5 w.
c119:  am    (b28)     ; begin
       rs w3  (0)      ;
       am    (b28)     ;   if test output active then
       rl w3 +a544     ;
       sn w3  0        ;   
       jl.    j0.      ;
       jl. w3 h4.      ;     generate testoutput(1<18)
              3<22+1<18;
j0:    rl  w3  (b28)   ;
       jl     (x3)     ; end;
  
e.
\f

  
  
; procedure generate testoutput(testkind);
;
; this procedure creates a testrecord or initiates the creation of a test
; record as follows:
;
; 1) if word 128 in monitor table is set ( <> 0 ) a message defining the
;    test record is sent to the coroutine test output process.
;
; 2) otherwise a test record is written in the cyclical test output buffer.
;    formats in the cyclical buffer:
;
;              user test record            coroutine function (signal etc.)
;         +0   testkind                    testkind
;         +2   time1                       time1
;         +4   time2                       time2
;         +6   user_ident,length           w0
;         +8   test information            w1
;         +10      - " -                   w2
;         +12      - " -                   coroutine ident
;         +14      etc.                    address of current coroutine

;
; testkind values:
;                      1<0       : start
;                      1<1       : wait
;                      1<2       : pass
;                      1<3       ; inspect
;                      1<4       : csendmessage
;                      1<5       : cwaitanswer
;                      1<6       : answer_arrived
;                      1<7       : signal_sem-signal_binary
;                      1<8       : wait_semaphore
;                      1<9       : signal_chained
;                     1<10       : inspect_chained
;                     1<11       : wait_chained
;                     1<12       : sem_sendmessage
;                     1<13       : sem_answer_proc
;                     1<14       : message_received
;                     1<15       : timer_message
;                     1<16       : timer_scan
;                     1<17       : cregretmessage
;                     1<18       : user defined testrecord
;
;              call             return
; w0:          -                unchanged
; w1:          -                unchanged
; w2:          -                unchanged
; w3:          link             current coroutine
  
  
b.j10,i5
w.
h4:   am      (b27)      ; begin
      rs  w3  +8         ;   ext1(8):= link;
      rl  w3  b27        ;
      ds  w1  x3+22      ;   save working registers
      rs  w2  x3+24      ;
      rl  w1  x3+8       ;   
      rl  w3  (b28)      ;
      rl  w0  x3+a716    ;   if testkind is included in curr.corout.testm then
      la  w0  x1         ;   begin
      sn  w0  0          ;
      jl.     j6.        ;
      rl  w3  b141       ;   if core(128) <> 0 then
      sn  w3  0          ;   begin
      jl.     j1.        ;
      rl  w3  b28        ;
      al  w1  x3+a566    ;
      rs  w0  x1         ;     cur.ext2.testmess(1):= testkind;
      al  w3  x3+a556    ;
      jd      1<11+16    ;     send message(testmes,cmontest);
      jd      1<11+18    ;     wait answer;
      jl.     j6.        ;   else
j1:   rl  w3  b28        ;   begin ! create record in cyclical buffer !
      am      (b27)      ;      if testkind = user record
      rl  w1  +24        ;
      se. w0  (i0.)      ;         then length:= length(user record)
      al  w1  8          ;         else length:= 8;
      rl  w2  x3+a540    ;      if (start(next record)+length+8) >
      wa  w1  x3+a540    ;          top(test buffer) then
      al  w1  x1+8       ;      begin
      sh  w1  (x3+a542)  ;
      jl.     j2.        ;
      al  w1  0          ;        insert dummy end record
      rs  w1  x2         ;
      rl  w2  x3+a538    ;        start(next record):= start(test buffer);
                         ;      end;
j2:   rs  w0  x2         ;      insert testkind in record
      rl  w3  0          ;
      jd      1<11+36    ;      get clock
      ds  w1  x2+4       ;      insert time in test record
      sn. w3  (i0.)      ;      if testkind = coroutine function then
      jl.     j3.        ;      begin
      rl  w3  (b28)      ;
      am      (b27)      ;
      dl  w1  +22        ;
      ds  w1  x2+8       ;         insert w0,w1
      am      (b27)      ;
      rl  w0  +24        ;
      rs  w0  x2+10      ;         insert w2
      rl  w0  x3+a718    ;
      ds  w0  x2+14      ;         insert coroutine_ident, addr. of curr,corout.
      al  w2  x2+14      ;
      jl.     j5.        ;      end
j3:   rl  w3  b27        ;      else
      dl  w1  x3+22      ;      begin <* user defined test record *>
      rl  w3  x3+24      ;
      hs  w0  x2+6       ;        insert user identification
      hs  w3  x2+7       ;        insert length
      al  w2  x2+8       ;
j4:   rl  w0  x1         ;        transfer test information
      rs  w0  x2         ;
      al  w3  x3-2       ;
      sh  w3  0          ;
      jl.     j5.        ;
      al  w2  x2+2       ;
      al  w1  x1+2       ;
      jl.     j4.        ;      end;
                         ;   end;
j5:   rl  w3  b28        ;
      al  w2  x2+2       ;   update start(next record) in procees ext2
      rs  w2  x3+a540    ;
j6:   rl  w3  b27        ;
      dl  w1  x3+22      ;   load working registers
      rl  w2  x3+24      ;
      rl  w3  x3+8       ;   return:=ext1(8);
      jl      x3+2       ; end;
  
i0:        +1<18         ; testkind f. user test record
 
e.
e.
z.
#,
  
  
;<*rettelse til errorlog *>

l./g66:/, l./j1:/,
l./rlw1x1+a141/, l1,i/
     sh  w1  (b3)     ; if receiver defined then
     jl.     j2.      ;
/,
l./al w3 32/, r/     /j2:  /,
l./h4:/,
l./dlw0/, i/
      rs. w2     i8.    ; save received buffer
      rl  w1     b19    ; check for clockchange c.w1=cur receiver
      jl. w3     j24.   ; 
      rl. w2     i8.    ; restore buffer
/,
l./c35:/, l./rx w0/,
i/
      al. w3     j38.   ; set continue adr
/,
l./j22:/, r/j22 :/     /, i/
j22 : al. w3     j38.   ; prepare continue adr
/,

l./j24:/, i/
; called when a message or an interrupt is received
; called with w1=cur receiver  and w3 holding the return adr
/,

l./jl.j38./, r/./ /, r/j38./x3  /,
l1, i/
      rs. w3     i9.    ; save return adr
/,
l./j36:/, l./b19/, l1, i/
      jl.      (i9.)    ;
/,
l./i6:/, l 1, i/
i8  : 0                 ; saved buffer from message received
i9  : 0                 ; return adr for j24
/,
f


$disc
;********************

$fpaline
;********************


$host
;********************
l./i0=/, r/01 12/04 27/
l./n4:/, l./n5:/, l./j1/, r/j1/j0/,

l./n11:/, l./+p99/, r/rl/zl/,

l./n22:/, l./p93/, r/p93 /p323/,
l./p91/, r/p91 /p321/,

f


$fpasub
;********************
l./i0=/, r/810112/81 03 25/
;<* ret fejl i mt driver: set state=regretted hvis sender er stoppet*>
l./h118:/, l./q1:/, l./j1:/,
l./u2/, r/u2/u3/, r/testmore/no block/,
f


$tabinit
;********************


$procfnc1
;********************
  
$procfnc2
;********************
l./i0=/,r/81 01 09/81 04 06/
l./m158:/,l./x2+a50/,i/
     rl  w0  x1+a30    ;
     rs  w0  x2+a60    ;     mref.pseudo:= save w2(cur)
/,f


$s1
;********************

l./i0=/,
   r/810126/81 05 20/

l./c4=/, i/
c16= 2       ; stack depth ( of nested 'reads' )
/,
l./c82=/, r/1760/0760/,



l./c16:c82/, d,



l./; definition of core table entry format:/,
l./c19/, d 2,i/
c22=c18+2    ; segment no in susercat or -1
c19=c22+2    ; kind , name of alternative primary input
c93=c19+10   ; kind , name of alternative primary output
c11=c93+10+2 ; size of coretable entry
/,


l./; definition of a console descr/,
l./c44=/, r/c43+4/c96+10/, i/
c95=c43+4    ; primin : kind , name
c96=c95+10   ; primout: kind , name
/,


l./; meaning of command mask:/,
l./; bit 2:/, r/print/print,date/,
l./; bit 3:/, r/load/load,read,unstack,i,o/,



l./; definition of work area format:/,
l./c90=/, i/
; *** start of part to be saved-restored
/,
l./c65=c57+2/, r/c57/c71/, i/
; *** end of part to be saved-restored
c58=c57+2    ; input stack pointer
c59=c58+2    ; first stack element
  ; subformat of stack entry:
  ; name + nta of area
  c60=10       ; segment no
  c61=c60+2    ; saved last addr
  c62=c61+2    ; saved char shift
  c63=c62+2    ; saved char addr
  c64=c63+2    ; (size of entry)
c71=c16*c64+c59; (top of stack)
c72=c71-c64  ; last stack entry start
c73=c59-c64  ; base of stack
/,





l./d0:/,
l./rl w0 b4;/, d./rl w0 x1;/, i/
    am        (b4)    ;
    rl  w0     a199<1 ;
/,
l./jl. f1./, d, i/
     jl.       (i4.)   ;   goto end line;
/,
l./i3:/, l1, i/
i4:  g30               ;
/,



l./; procedure next char/, i/

b. i20, j20 w.

i0:  0                 ; saved link
i1:  0                 ; saved w3
i2:  0                 ; saved w1

i5:  h20               ; first of buffer

j0:  g3                ; end line: not allowed
j1:  g12               ; end line: area unknown
j2:  g15               ; end line: area error

j5:  e24               ; pointer to: work
j6:  e26               ; pointer to: last addr
j7:  e28               ; pointer to: char addr
 j8: e27               ; pointer to: char shift

j10: e47               ; pointer to: area input mess
j11: e49               ; pointer to: last of buffer
j12: e50               ; pointer to: segment number
j13: e32               ; pointer to: answer
; procedure stack input
;   stacks the input pointers and selects the given area for input
;
; call: w2=name, w3=link
; exit: all regs undef

d79:                   ; stack input:
     rs. w3     i0.    ;   save return;
     rl. w1    (j5.)   ;   w1 := work;
     rl  w3  x1+c58    ;   w3 := stack pointer;
     sn  w3  x1+c72    ;   if stack pointer = last stack entry then
     jl.       (j0.)   ;     goto not allowed; (* i.e. stack overflow *)

     al  w3  x3+c64    ;   increase (stack pointer);
     rs  w3  x1+c58    ;

     rl. w1    (j6.)   ;
     rs  w1  x3+c61    ;   save last addr in stack entry;
     dl. w1    (j7.)   ;
     ds  w1  x3+c63    ;   save char shift and char addr in stack entry;

     dl  w1  x2+2      ;   move name to stack entry;
     ds  w1  x3+2      ;
     dl  w1  x2+6      ;
     ds  w1  x3+6      ;

; prepare variables for immediately buffer change
     al  w0    -1      ;
     rs  w0  x3+c60    ;   segment.stack entry := -1;

     rl. w2     i0.    ;   w2 := return;
     jl.        d82.   ;   goto next segment;



; procedure unstack input
;   restores the char pointers from the stack, and maybe also the buffer
;
; call: w2=link
; exit: all regs undef

d80:                   ; unstack input:
     rl. w1    (j5.)   ;   w1 := work;
     rl  w3  x1+c58    ;   w3 := stack pointer;
     sn  w3  x1+c73    ;   if stack pointer = stack base then
     jl      x2        ;     return;

     al  w0  x3-c64    ;
     rs  w0  x1+c58    ;   decrease (stack pointer);

     dl  w1  x3+c63    ;
     ds. w1    (j7.)   ;   restore char shift and char addr from stack entry;
     rl  w1  x3+c61    ;
     rs. w1    (j6.)   ;   restore last addr from stack entry;

     jl.        d81.   ;   goto get segment;



; procedure get segment
; 
; call: w2 = link
; exit: w1,w2,w3=unch, w0=undef

d81:                   ; get segment:
     am         0-1    ;   increment := 0;

; procedure get next segment
;
; call: w2 = link
; exit: w1,w2,w3=unch, w0=undef

d82:                   ; next segment:
     al  w0     1      ;   increment := 1;

; procedure read segment
;
; call: w0 = increment, w2 = link
; exit: w1,w2,w3=unch, w0=undef

d83:                   ; read segment:
     ds. w3     i1.    ;   save return, w3;
     rs. w1     i2.    ;   save w1;

     rl. w1    (j5.)   ;   w1 := work;
     rl  w3  x1+c58    ;   w3 := stack pointer;
     sn  w3  x1+c73    ;   if stack pointer = stack base then
     jl.        i10.   ;     goto return;

     rl. w1     i5.    ;   w1 := first of buffer;
     al  w2  x1+510    ;   w2 := last of buffer;
     ds. w2    (j11.)  ;

     sn  w0     0      ;   if increment <> 0 then
     jl.        i8.    ;     begin
     rs. w2    (j6.)   ;     last addr := last of buffer;
     rs. w1    (j7.)   ;     char addr := first of buffer;
     al  w1    -16     ;
     rs. w1    (j8.)   ;     char shift := -16;
i8:                    ;     end;

     wa  w0  x3+c60    ;   segment := segment + increment;
     rs  w0  x3+c60    ;
     rs. w0    (j12.)  ;
     jd         1<11+92;   create entry lock process(area name);
     se  w0     0      ;   if result <> ok then
     jl.       (j1.)   ;     goto area unknown;

     al. w1    (j10.)  ;
     jd         1<11+16;   send message (area input, area name);
     al. w1    (j13.)  ;
     jd         1<11+18;   wait answer(answer area);
     rl  w1  x1        ;
     lo  w1     0      ;   w1 := status 'or' result;
     jd         1<11+64;   remove process (area name);
     se  w1     1      ;   if any arror then
     jl.       (j2.)   ;     goto area error;

i10:                   ; return:
     rl. w1     i2.    ;   restore regs;
     dl. w3     i1.    ;
     jl      x2        ;   return;

e.                     ;
/,

l./d1:/,
l./al w0 10;/, d./al w2 x2+2;/,
i/
     al  w1    -16     ;   char shift := -16;
     al  w2  x2+2      ;   char addr := char addr + 2;
     sh. w2    (e26.)  ;   if char addr > last addr then
     jl.        i0.    ;     begin
     al  w0     10     ;     char := newline;
     rl. w1     e24.   ;
     rl  w2  x1+c58    ;
     sn  w2  x1+c73    ;     if stack pointer = stack base then
     jl.        i1.    ;       goto classify char;  (* i.e. not end of area-read-buffer *)
     jl. w2     d82.   ;     get next segm;
     jl.        d1.    ;     goto next char;
                       ;     end;
/,
l./i1:/, d, i/
     ds. w2     e28.   ;
i1:                    ; classify char:
/,
l./se w1 5;/, d./z. jl x3+0;/, i/
     jl      x3        ;   end;
/,






l./d2:/,
l./al w0 0;/, d1, i/
     al  w1     0      ;
     se. w1    (e87.)  ;   if areabuf undef then
     jl. w2     d81.   ;     get segment;
     rs. w1     e87.   ;   areabuf := defined;

     al  w0     0      ;   param type := 0;
/,

l./d3:/,
l./ld w2 -2;/, i/
     al  w2     0      ;
/,

l./d7:/, d, i/

d11:                   ; newline or semicolon:
     sn  w0     10     ;
     jl.        d8.    ;   while char <> newline do
     jl. w3     d1.    ;     next char;
     jl.        d11.   ;   goto delimiter;

d7:                    ; unknown:
     sn  w0     25     ;   if char = em then
     jl. w2     d80.   ;     unstack input;
     al  w2     3      ;
/,




l./d22:/,
l./; procedure typeline(buf)/,
l./b.i24/, i/

; procedure send buf (mess, buf)
; (as typeline, but at call: w1=mess)
/,
l./d23:/, d, i/
w.
d23:                   ; type line:
     al. w1     e44.   ;   mess := output message;
d26:                   ; send buf:
     rs. w3     e60.   ;
/,
l./dl w1 x2+a11+2;/, g3/w1/w0/,
l./al. w1 e44./, d,
l./d31:/, l./+12/, r/+12/c22/,
l./d35:/, l./i25:/, l./jl. w3 d30./,
r/;/; reserve core/, l1, 
d 2, i/
     al  w3  x1+c95     ; move kind,name of primin
     al  w2  x2+c19     ; and primout to coretable
j0 : rl  w0  x3         ; (set by i and o commands )
     rs  w0  x2         ;
     al  w3  x3+2       ;
     al  w2  x2+2       ;
     se  w3  x1+c44     ;
     jl.     j0.        ;
/,
l./i10:/, d,
l./i8:/, d./i23:/, i/

; transfer claims to child,
; the claimlist in the console-description

i8:                    ; not 'all' bs (console):
     rl. w3     e25.   ;   w3 := claimbase := console;
i13:                   ; next chaintable:
     rs. w3     i22.   ;   save claimbase;

     dl  w1  x3+c44+6  ;   perm claim := claimlist(claimbase);
     ds. w1     i24.   ;
     wa  w0  x3+c44+0  ;   temp entries := temp+perm entry claim;
     wa  w1  x3+c44+2  ;   temp segms   := temp+perm segm  claim;
     rs. w0     i23.   ;   main entries := temp entries;
     al  w0     0      ;   temp entries := 0;

     ws. w3     e25.   ;   w3 := index in claimlist;
     ls  w3    -2      ;
     wa  w3     b22    ;   w3 := chain table number;
     sl  w3    (b24)   ;   if all chains handled then
     jl.       (i2.)   ;     return;
     rl  w3  x3        ;   w3 := chain table addr;

     al. w2     g20.   ;   error addr := claims exceeded;

i14:                   ; transfer claim:
; w0=temp entries, w1=temp segments
; w2=error address
; w3=chaintable address
     rs. w2     i20.   ;   save(error addr);
     al  w2     0      ;   key := 0;
i15:                   ; next key:
     ds. w1  x2+e52.   ;   claim(key) := entries,segments;
     al  w2  x2+4      ;   increase(key);
     sn  w2     a109*4 ;   if key = min aux key then
     dl. w1     i24.   ;     entries,segments := perm claim;
     sh  w2     a110*4 ;   if key <= max cat key then
     jl.        i15.   ;     goto next key;

     dl  w1  x3-a88+18 ;   name := docname.chaintable;
     ds. w1     e21.   ;
     dl  w1  x3-a88+22 ;
     ds. w1     e23.   ;

     rl. w3     e25.   ;   w3 := proc name;
     al  w3  x3+c29    ;
     al. w2     e20.   ;   w2 := docname;
     al. w1     e51.   ;   w1 := claim;
     jd         1<11+78;   set bs claim;
     sn  w0     0      ;   if result = ok then
     jl.        i16.   ;     goto maincat entries;
     se  w0     1      ;   if result <> claims exceeded then
     jl.        i17.   ;     goto next entry;
     al  w0     1      ;
     hs. w0     e81.   ;   fiddle with remove indicator...
     jl. w3     d40.   ;   remove child;
     jl.       (i20.)  ;   goto error;

i16:                   ; maincat entries:
     ld  w1    -100    ;   perm claim := 0,0;
     ds. w1     i24.   ;
     rx. w0     i23.   ;   w0 := main entries; main entries := 0;
     rl  w3     b25    ;   w3 := main catalog chain table;
     al. w2     g25.   ;   w2 := error addr := no maincat entries;
     se  w0     0      ;   if main entries <> 0 then
     jl.        i14.   ;     goto transfer claim;

i17:                   ; next entry:
     rl. w3     i22.   ;   increase (claimbase);
     al  w3  x3+8      ;
     jl.        i13.   ;   goto next chaintable;

i20: 0                 ; error addr
i22: 0                 ; claimbase
i23: 0                 ; main entries;
i24=k+2, 0,0           ; perm claim (entries, segments)
/,




l./d36:/,
l./jl. w3 d25./, r/ole,/ole,coretableelement,/,
l./al. w1 e61./, i/
; override these default w0 and w2 assignments,
; in case of user-defined primary input (or -output) names
     al  w1  x3+c19    ;   w1 := addr of primary input descr;
     rl  w0  x1+2      ;
     se  w0     0      ;   if name defined then
     rs. w1     e61.   ;     child w0 := primary input descr;
     al  w1  x3+c93    ;   w1 := addr of primary output descr;
     rl  w0  x1+2      ;
     se  w0     0      ;   if name defined then
     rs. w1     e63.   ;     child w2 := primary output descr;

/,



l./d37:/,
l1 ,i/
     rl. w1      e29.    ; if state.process <> wait start 
     zl  w1  x1+a13      ; then goto error
     so  w1  2.100000    ; 
     jl.         g3.     ;
/,

l./1<11+52/, l1, i/
     al. w3      i1.     ; prevent remove of process
/,

l./e51./, i/
     al. w3      e40.    ; 
/,

l./1<11+16/, l-1, d, 
l./w3/, r/w3/w1/,
l./rs. w3 (i19.)/, r/i19/e12/,
r/w3/w1/,

l./i12:/, i/
 i9:  am      2          ; 
i10:  am      2          ;
i11:  am      2          ;
/,

l./i14:/, g 1/w3/w2/,
l./al.w3 e40/, d,
l./;dont/, d./jl. i15./,

l./i19:/, d, i/
 i3 : 2.100000            ; state bit : wait for stop or start
/,


l./d41:/, d./jl. i0./, i/
w.
d41:                   ; find work:
     rl. w1     e13.   ;   work := first work;
i0:                    ; loop:
     rs. w1     e24.   ;
     sn  w2 (x1+c50)   ;   if state(work) = state then
     jl      x3        ;     return;
     al  w1  x1+c2     ;   increase(work);
     sh. w1    (e14.)  ;   if work <= last work then
     jl.        i0.    ;     goto loop;
     jl.        g31.   ;   goto exam next; <* not expecting this answer *>
/,






l./d42:/,
l./ds w3 x1+c51/, l1, i/
     rs. w2     e88.   ;   expected answer := state;
/,
l./; procedure restore work/,
l./; w0 destroyed/, r/destroyed/logical status/,
l./; w1 work/, r/work/    /,
l./d43:/,
  r/rs./rl./,
l./i0:/, i/
     rs. w2     e87.   ;   areabuf := undef;
/,
l./rl. w3 e59./, g1/w3/w0/,






l./d45:/,
l./;procedure set_zero/, d./i3:/, i/

; procedure clear claimlist
; comment sets zeroes in whole claimlist of console descr
;
; call: w3 = link
; exit: all regs undef

b. i10 w.
d46:                   ; clear claimlist:
     rl. w1     e25.   ;   w1 := console;
     al  w2  x1+c48-c44+2;   w2 := rel top of claimlist;
     al  w0     0      ;
i0:                    ; rep:
     al  w2  x2-2      ;   decrease(pointer);
     sl  w1  x2        ;   if pointer <= start of console then
     jl      x3        ;     return;
     rs  w0  x2+c44    ;   claimlist(pointer) := 0;
     jl.        i0.    ;   goto rep;

/,





l./d61:/,
l./j1:/, g2/w1/w3/, l-1, r/x1/x3/,
l2, r/rl/wa/,
l1, d,
    r/al w3 x3/          /,





l./d71:/,
l./e.z.jl. g18/, r/ jl.g18.//,




l./d78:/,
l./i1:/, l./shw1/, r/h/l/, r/1/3/, r/x3/x1/,
l./; parameter table:/,
l./i6=/, l1, i/
i9=(:d11-d2:)<2+0
/,

l./h1:/,
l./i6,i7/, r/i7/i9/, r/delimit0/endline/,
l./i7,i7/, r/,i7/, i9/, r/,delimit0/, endline/,
l./i7,i7/, r/,i7/, i9/, r/,delimit0/, endline/,


l./d25=k-2/, l1, i/
     jl.        d26.   ;
d26=k-2
/,
l./d35=k-2/, l1, i/
     jl.        d36.
d36=k-2
     jl.        d38.
d38=k-2
/,

l./f1: jl. g30./, d,
i/
     jl.        d79.     ;
d79=k-2
/,

f


$s2
;********************

l./i0=/,
   r/810112/81 05 05/


l./e8:/, i/
e12:h3    ; <top command table>
/,

l./e24:h8/, r/>/>  ( initially: first work )/,
l1, i/
; *** the following variables must match part of work-area
/,
l./e25:/, r/0  /h21/, r/>/>  ( initially: first console )/,
l./e27:/, r/0/8/, r/>/>  (initially: prepared for empty char buf)/,
l./e30:/, l1, i/
; *** end of work-area match
/,


l./e39:/, i/

e88:0      ; expected answer
e89:0      ; executing reentrant code: 0=false, -1=true (initially = false)
/,
l./e50:/, l1, i/
e87: 0                  ; areabuf state: 0=defined, else undef (initially defined)
/,
l./g1:/, l1, d, i/
g48=k+4
<:ready  **date not initialized <0>:>   ; text until date initialized  
/,


l./g2:/,
l./<:syntax error/, r/error/error:/,

l./g27:/, l1, r/<:ille/<:ille/,

l./g28:/, i/
g47: jl. w1     g28.   ;
<:input aborted<0>:>
/,


l./g28:/,
l./g2./, i/
     se  w3  (b13)      ; if clock initialized then
     rs. w3  g48.       ; remove warning
/,
l./al w3 -1;/, l1, i/
     rs. w3     e89.   ;   executing reentrant code := true;
/,
l./al w0 58;/, d1,


l./g46:/,

l./al w1 0; reset remove list/,
d./rs. w1 e33./,
l./g30:/, l1, i/
     rs. w2     e81.   ;   reset remove list indicator
/,

l./g32:/,
l./sn w0 0;/, i/
     sz. w2    (e89.)  ;   if executing non-reentrant code
     jl.        g41.   ;     and
     se. w2    (e88.)  ;     event <> expected answer then
     jl.        g32.   ;     goto exam next;
g41:                   ;
/,
l./al. w1 e51./, i/
     jl. w3     d41.   ;   find work(event,old work);
/,
l1, l./jl. w3 d41./, d1,


l./g34:/,
l./dl w0 x1+4/, d3,
l./rs. w1 e24./, d, i/
     al  w0  x1+c73    ;   input stack pointer := stack base;
     rs  w0  x1+c58    ;
g39:                   ;     end;
/,
l./al w2 x2-2/, d./al. w3 e40./,
l./jd 1<11+16/, d, i/
     jl. w3     d26.   ;   send buf (input mess, buf);
/,
l./jl. g2./, r/g2. /g47./,
l./rl. w2 e52./, d./ds. w3 e27./, i/
     al  w2  x1+c66-2  ;   char shift := > 0; (* i.e. change word *)
     ds. w2     e28.   ;   char addr := work + linebuf - 2;
     wa. w2     e52.   ;
     rs. w2     e26.   ;   last addr := char addr + bytes;
/,




l./g36:/,
l1, r/g1/g98/,
l./rl. w3 e7./, i/

     jl. w3     d19.   ;   init write;
     al  w3    -1      ;
     rs. w3     e89.   ;   executing reentrant code := true;
/,
l./g45:/, d, i/
; init write has been called
/,

l./g38:/,
l./jl. g2./, l1, i/

; all commands, not contained in primary part of command table, are
; considered non-reentrant

     al  w3     0      ;
     rs. w3     e89.   ;   executing reentrant code := false;

/,
l./g50:/, i/

g98: rl. w1     e24.      ; if stack=stackbase then
     rl  w2  x1+c58       ; goto endline else
     sn  w2  x1+c73       ; goto next command
     jl.         g1.      ;
     jl.        g35.      ;


/,
l./jl. w3 d41./, l1, d,


l./g42:/,
l./jl.w3 d42./, d./jl.g30./ ,  i/
     rs. w2     e23.+2   ; clear function
     zl. w1     e32.+1   ; if stop bit on then
     so  w1     8.200    ; begin
     jl.        g97.     ;
     zl. w1     e32.     ; save function
     rs. w1     e23.+2   ;
     se  w1     10       ; if function = replace then
     jl.        g97.     ;  save areaname
     rl. w3     e24.     ; save name in input buffer
     al  w3  x3+c66      ;
     dl. w1     e32.+10  ;
     ds  w1  x3+2        ;
     dl. w1     e32.+14  ;
     ds  w1  x3+6        ; end
     dl. w1     e26.     ; simulate empty input string
     ds. w1     e28.     ; ( after unstack command)
g97: jl. w3     d42.     ; save work
     am          0       ; +2 error (dont care)
     rl. w3     e23.+2   ; if function =finis or replace then
     se  w3     10       ;
     sn  w3      2       ; 
     sz                  ;
     jl.        g30.     ;
     jl. w3     d76.     ; adjust bs claim
     jl. w3     d40.     ; remove process
     rl. w3     e23.+2   ; if function =replace then
     se  w3     10       ;
     jl.        g30.     ;
     rl. w2     e24.     ; stack input and
     al  w2  x2+c66      ;
     jl. w3     d79.     ; goto next command
     jl.        g35.     ;
/,
l./b.i30w.;new:/, i/

g45: ; base for command-relatives

; define pseudo-entries for conditinally-assembled commands
g70: ; break
g72: ; include
g73: ; exclude
g74: ; call
g75: ; list
g76: ; max
g77: ; replace
g83: ; all
g89: ; job
g90: ; print
g91: ; modify
     jl.        g18.   ;   goto not implemented;



; command syntax:  read <area name>
g57:                   ; read:
     jl. w3     d15.   ;   next name;
     al. w2     e20.   ;
     am        -2048   ;
     jl. w3     d79.+2048;   stack input (name);
     jl.        g35.   ;   goto next command;


; command syntax:  unstack
g58:                   ; unstack:
     am        -2048   ;
     jl. w2     d80.+2048;   unstack input;
     jl.        g35.   ;   goto next command;


; command syntax:  date <year> <month> <date> <hour> <min> <sec>

b. i20, j30 w.         ;
j0:                    ; minimum values:
     81  ,  1  ,  1  ,  0  ,  0  ,  0
j1:                    ; top values:
     99+1, 12+1, 31+1, 23+1, 59+1, 59+1
j2:                    ; year,month,day,hour,min,sec
      0  ,  0  ,  0  ,  0  ,  0  ,  0
j5:                    ; month table: jan, ..., dec
h. 365, 396, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
w.
j11: 4                 ; minutes per four minutes
j13: 24                ; hours per day
j14: 60                ; minutes per hour
j17: 365*3+366         ; days per four years (inclusive leap year)
j18: 10000             ; units per second
j20: 60*4 * 10000      ; units per four minutes

j30: <:oldcat:>        ; name of successor-command

g49:                   ; date:
     al  w1     0      ;   for i := 0 step 2 until 10 do
i0:                    ;     begin
     jl. w3     d16.   ;     next integer;
     sl. w0 (x1+j0.)   ;     if number < min value
     sl. w0 (x1+j1.)   ;     or number >= top value then
     jl.        g2.    ;       goto syntax error; (* i.e. illegal date *)
     rs. w0  x1+j2.    ;     save number;
     al  w1  x1+2      ;
     se  w1     12     ;
     jl.        i0.    ;     end;

     dl. w2     j2.+2  ;   w1 := year; w2 := month;
     sh  w2     2      ;   if month > february then
     al  w1  x1-1      ;     year := year - 1;

     al  w1  x1-68     ;   days := (year - 68)
     wm. w1     j17.   ;     * days in four years
     as  w1    -2      ;     æ47æ 4
     ba. w1  x2+j5.-1  ;     + month table (month)
     wa. w1     j2.+4  ;     + day;

     wm. w1     j13.   ;   w1 := hours := days * 24
     wa. w1     j2.+6  ;     + hour;

     al  w2     0      ;   w2w3 := min;
     rl. w3     j2.+8  ;

     wm. w1     j14.   ;   w0w1 := minutes := hours * 60
     aa  w1     6      ;     + min;

     wd. w1     j11.   ;   w1 := fourmin := minutes æ47æ 4;
     wm. w0     j14.   ;   seconds := minutes mod 4 * 60
     wa. w0     j2.+10 ;     + sec;

     wm. w0     j18.   ;   msec := seconds * 10000;
     rl  w3     0      ;   (w2=0) w3 := msec;

     wm. w1     j20.   ;   clock := fourmin * 2400000
     aa  w1     6      ;     + msec;
     jd         1<11+38;   set clock (clock);

     dl. w1     j30.+2 ;   name := successor command name;
     ds. w1     e21.   ;
     al  w0     1      ;   type := 1;  <* i.e. pretend that 'oldcat' has been read *>
     sl  w0    (b25)   ;   if maincat not defined yet then
     jl.        g36.   ;     goto next command; <* i.e. interpret 'oldcat' *>

     jl.        g35.   ;   goto next command;

e.                     ;

/,



l./g51:/,
 l./rl. w3 e25.;/, d./al w2 x3+c1-2/, r/;/;   clear claimlist;/,
l./jl. g16.;sorry goto end line/,
l./rl. w3 e25.;/, d./al w1 x1+4;/, d./ds w0 x1 ;/, i/
     wa. w2     e25.   ;
     dl. w0     i6.    ;   perm claim(work device) :=
     ds  w0  x2+c44+6  ;     standard segment,entries;
/,
l./jl. g52./, i/
     al  w0     0      ;
     rs  w0  x1+c95+2  ;   clear primary input name;
     rs  w0  x1+c96+2  ;   clear primary output name;
/,
l./i11:0/, d-1,

l./g83:/, d, l1, i/

g83 = k                ; all:
/,
l./c.-4000/,
l./hs w0 x1+c26;/,
l./rl.w1 e25.;/, d./al w1 x1+c44;/, r/;/;   clear claimlist;/,
l./e. jl. g18.; goto endline/, d, i/
e.
/,
l./g52:/, i/
b. j5 w.
g94: am  c95-c96        ; i:
g95: al  w1  x1+c96+2   ; o:
     jl. w3  d16.       ; get kind
     rs  w0  x1-2       ;
     jl.     j1.        ; continue with get name
/,
l./jl. w3 d15./, r/     / j1: /,
l./j2:/, l1, i/
e.
/,





l./g70:/, d, l1, i/
g70 = k                ; break:
/,
l1, r/w./ /,
l./jl. g18./, d, i/
z.
/,




l./g72:/, d1, l1, i/
g72 = k                ; include:
     am         2      ;
g73 = k                ; exclude:
/,
l./al w0 0; dummy instr/, d,
l1, d1,



l./g74:/, d, l1, i/
g74 = k                ; call:
/,
l./jl. g18./, d, i/
e.
z.
/,




l./g75:/, d, l./b.i24/, r/24   /24 w./, l1, i/
i7:  <: error <0>:>
i8:  <: stop  <0>:>
i9:  <: run   <0>:>
i10: <: wait  <0>:>
g75 = k                ; list:
/,
l./w. rl w2 b6/, r/w./  /,
l./al w1 x1 -12;/, r/al/ac/,
l1, d,
l./zl w1 x2+a13;/, d./i11:/, i/
     bl  w0  x2+a13    ;   w0 := process state;
     al. w1     i7.    ;
     sz  w0     2.10000000;
     al. w1     i10.   ;
     sz  w0     2.00100000;
     al. w1     i8.    ;
     sz  w0     2.01000000;
     al. w1     i9.    ;
     jl. w3     d21.   ;   writetext(process state);
     rl  w1  x2+a34    ;
/,
l./jl. g2.;/, r/g2. /g47./,
l1, d,
l./jl. g35./, d./<: wait /,
l./jl. g18./, d, i/
e.
z.
/,



l./g76:/, d, l1, i/
g76 = k                ; max:
/,
l./w.jl.w3 d19./, d, i/
w.
/,
l./i0:/,
l./jl. g2.;/, r/g2. /g47./,
l./jl. g18./, d, i/
e.
z.
/,



l./g77:/, d, i/



/,
l./b.i24/, i/
g77 = k                ; replace:
/,
l./rl w3 66/, r/66/b1/,


l./i13:;/, d./i4:/, i/

i2:  am         g13-g11;
i3:  am         g11-g12;
i4:  am         g12-g14;
/,
l./i21:/, d,
l./i23:/, d1, i/
e.
z.


/,



l./; stepping stone/,
l./jl.d16./, i/
jl. d15., d15=k-2
/,
l./d34./, i/
jl. g27., g27=k-2 
/,
l./jl. d61./, i/
jl. d46., d46=k-2
/,
l./d78=k-2/, l1, i/
/,




l./g79:/,
l./jd 1<11+52/, l1, i/
     al. w3     i1.    ;   (prevent remove process(name))
/,
l./jd 1<11+8;/, i/
     al. w3     e20.   ;
/,


l./g86:/, d3, i/
; command syntax:  user <lower> <upper>
; command syntax:  login <lower> <upper>
; command syntax:  project <lower> <upper>
g86: am         c43-c42; user: update userbase;
g82: am         c42-c41; login: update loginbase;
g80: al  w2  x1+c41    ; project: update projectbase;
/,
l./rs. w0 i3./, d, i/
     rs  w0  x2+0      ; lower := integer;
/,
l./i0:/, d-1, i/
     rs  w0  x2+2      ; upper := integer;
/,
l./i1:/, d2,
l./i3:/, d,




l./g81:/,
l./al.w1e66.-2/, r/e66.-2;/e51.+a110*4;/,
l./g84:/, d, i/

; command syntax:  temp <docname> <segments> <entries>
g84:                   ; temp:
     am         c45-c47;   (update temp claims)

; command syntax:  perm <docname> <segments> <entries>
g85:                   ; perm:
     al  w3     c47    ;   (update perm claims)
     wa. w3     e25.   ;
     rs. w3     i6.    ;   save abs addr of claim;

/,
l./rl. w3 e25./, d2, i/
     am.       (i6.)   ; update segments and entries;
     ds  w1  x2        ;
/,
l./g85:/, d./jl.g35./,
l./i5:0/, l1, i/
i6:  0                 ; abs addr of claim (in console descr)
/,



l./g89:/, d, i/
w.
/,
l./rl. w1 e25./, i/
g96 = k                ; get:
          am -1        ;
g89 = k                ; job:
     al  w0  0         ; set startflag
     rs. w0  i16.      ;
     al  w3  0         ;
     rs  w3  x1+c95+2  ; clear primin and primout
     rs  w3  x1+c96+2  ;
/,
l./rl. w1 e25./, d./jl. w3 d46./, i/
     jl. w3     d46.   ;   clear claimlist;
/,

l./rs. w1 i16./, d,
l./al w3 510;/, d1, i/
     al  w3  x2-510    ;   w3 := last used in segment;
/,
l./j8:/,
r/e21. /(i6.)/,
l1, r/e23. /(i7.)/,
l./sh w1 -1/, d1,

l./e79./, g 9/e79. /(i5.)/,


l./j4:/, l./e25/, r/e25. /(i3.)/,

l./j5:/, l./c44/, r/c44/c95/, r/;/; (until i and o are defined in susercat)/,
l./j2:/, d 1, i/
j2:                    ;
     rl. w1    (i3.)   ; restore console
     al  w2    -1      ;   areabuf := undef;
     rs. w2     (i4.)  ;
     sn. w2  (i16.)    ; if only load then
     jl.        g35.   ;   goto next command;
/,
l./i10:/, i/
 i3: e25
 i4: e87
 i5: e79
 i6: e21
 i7: e23
/,
l./i16:/, r/entry0/job/, r/getentry0/job command/,
l./jl. g18./, d,




l./g87:/,
d./i1:/, i/
w.
g87: am         1<8    ; lock:  lock := true;
g88: al  w0     0      ; unlock:lock := false;
     rs. w0     (i0.)  ;
     jl.        g35.   ;   goto next command;
 i0: e80               ; lock indicator
/,






l./;print:/, r/;print:/;/, i/



c. (:c23>15a.1:)-1/,

l./g91:/, d1, i/

g91 = k                ; modify:
/,
l./g90:/, d-1,d, i/

g90 = k                ; print:
/,

l./i26:/,
l./am -2046/, d1, i/
z.
e.


/,


l./g93:/,
l./sl w0 -1/, d1, i/
     sz. w0    (i1.)   ;   if prio < 0 or prio >= 4096 then
/,
l./jl. g35.;/, l./i1:1<12/, r/1<12/-1<12/, l1, i/
e.


/,



l./d76:/,
l./rl.w1 e25/, r/e25/e29/, r/console/child/,
l 1, r/c29/a11/,

l./j6:/,
l./jl. (i10.)/, i/
     am        -2048    ;
     rs. w3     e87.+2048;   areabuf := undef;
/,


l./h0:/,
l./; can em sub/, r/8.77/8.76/,




l./w.h2=/,
l./:dump:/, i/
<:date:>    , 1<21+1<14+g49-g45
/,
l./:functi:/, i/
<:i:>,0     , 1<20+g94-g45
/,
l./list/, i/
<:get<0>:>  , 1<20+g96-g45
/,
l./:perm:/, i/
<:o:>,0     , 1<20+g95-g45
/,
l./:remove:/, i/
<:read:>    , 1<20+1<14+g57-g45
/,
l./:user:/, i/
<:unstac:>  , 1<20+1<14+g58-g45
/,





l./b110 = g45/, d./g77=g18/, i/

b110 = g45   ; command base
b112 = d2    ; call next param
b113 = d15   ; call next name
b114 = d16   ; call next integer
b115 = g2    ; goto syntax error
b116 = g35   ; goto next command
b117 = g36   ; goto exam command
b118 = e19   ; integer just read
b119 = e20   ; name just read
b120 = e8    ; pointer to: last of init code
b121 = d19   ; call init write
b122 = d20   ; call write char
b123 = d21   ; call write text
b124 = d23   ; call type line
b125 = d42   ; call save work
b126 = g47   ; goto input aborted
b129 = g11   ; goto catalog error
b130 = d79   ; call stack input
/,


l./h10:;/, d, i/
h10 = k - c11 ; base of core table:
/,

l./i0:/, r/h10    /h10+c11/,
l./i1:/, r/h10.    /h10.+c11/,
l./se. w2 i0./, r/i0. /h11./,


l./g39 ; addr of after initcat/, d1,
i/


/,


l./h12:/,

l./i10:/, l1, i/

; initialize work table
b. j1 w.
     al. w3     h8.    ;
j0:                    ; rep:
     al  w1  x3+c73    ;   for all work table entries do
     rs  w1  x3+c58    ;     stack pointer := stack base;
     al  w3  x3+c2     ;
     sh. w3     h9.    ;
     jl.        j0.    ;
e.                     ;
/,

l./b.j1/, r/j1/j3/,
l./h21/, r/h21. /(j2.)/,
l./j0:/, r/c18/c25/, l./c18/, r/c18/c25/,

l./h5/, r/h5. /(j3.)/,
l./e./, i/
     jl.        i9.

j2: h21
j3: h5
/,

l./rl w1 (b6)/, r/     / i9: /,

l./rs w0 x1+a18; top address(s) :=/, i/

     rs. w0    (4)     ;   top core :=
     jl.        4      ;
         e17           ;/,

f

$catinit
;********************

l./i0=/,
   r/801124/81 04 06/
l./s.k=k/, r/f40/f50/,
l./e5:/, g 2/:>/<0>:>/,
l./initialize date/, r/::/using the date command <10> :/,





l./;procedure typechar(char)/,
d./f0:/,
d./f1:/,
d./f2:/,
d./f4:/,
d./i1:/,
d./e.;end/,
i/


; procedure type newline
;   outputs a newline char on the console
;
; call: w3 = link
; exit: w0 = undef, w1,w2,w3 = unch

f3:                    ; type newline:
     al  w0     10     ;   char := newline;
                       ;   continue with type char;


; procedure type char
;   outputs the given char on the console
;   (if the char is <newline>, the buffer is sent)
;   ***** note: return inf etc are not saved for reentrant use of this code!!!
;
; call: w0 = char, w3 = link;
; exit: all regs unch

f0:                    ; type char:
b. i24 w.
     ds. w2     i0.    ;   save regs;
     ds. w0     i1.    ;
     rl  w2     0      ;
i10:                   ; put char: (w0 = w2 = char)
     jl. w3     f42.   ;   write char (char);
     se  w2     10     ;   if char = newline then
     jl.        i15.   ;     begin
     jl. w3     f44.   ;     type line (buf);
     jl. w3     f45.   ;     save work (buf);
     am                ;+2:    error: (continue)
                       ;     (maybe status-errors ougth to repeat a couple of times ???)
     jl. w3     f41.   ;     init write;
i15:                   ;     end;
     dl. w2     i0.    ;   restore regs;
     dl. w0     i1.    ;
     jl     x3         ;   return;


; procedure typetextline (text);
;   outputs the text on the console, terminated by a newline char
; call: w1=text addr, w3=link
; exit: w0,w1,w3=unch, w2 = undef

f2:                    ; typetextline:
     am         10-32  ;   char := newline;
                       ;   continue with typeout;

; procedure typetext (text);
;   outputs the text on the console, terminated by a space
; call: w1=text addr, w3=link
; exit: w0,w1,w3=unch, w2=undef

f1:                    ; typetext:
     al  w2     32     ;   char := space;
     ds. w2     i0.    ;   save regs;
     ds. w0     i1.    ;
     jl. w3     f43.   ;   writetext (text);
     al  w0  x2        ;
     jl.        i10.   ;   goto put char

i0=k+2, 0, 0           ; saved w1,w2
i1=k+2, 0, 0           ; saved w3,w0
e.                     ;
/,



l./f5:/,
l./al w2 x1+6;/, d,
l./al. w2 e6./, d,
l./i0:/, d1, i/
i0:                    ; end with newline:
     jl. w3     f3.    ;   type newline;
/,




l./f6:/,
l./al w2 x1+6/, d,
l./al. w2 e8./, d,
l./jl. i0./, r/;/;   goto end with newline;/,




l./f8:/,
l./i2:/,
l./al. w2 e10./, d./jl.w3 f0./, i/
     jl. w3  f2.       ;   type textline (<:input sumerror:>);
/,





l./f22:/,
l./i20:/,
l./al w2 x1-2;/, d./jl. i21.;/,






l./; procedure insert all entries/,
l./j7=k-2/, d,
l./j9=k-2/, d,
l./j11=k-2/, d,
g-3/:>/<0>:>/,


l./i20: ; error at output catsegment:/,
l./al. w2 j7./, d./jl.w3 f0./, i/
     jl. w3     f2.    ;   type textline (<:repair not possible:>);
/,

l./i21:/,
l./al. w2 j9./, d./jl. w3 f0./, i/
     jl. w3     f2.    ;   type textline (<:update of entry count not possible:>);
/,

l./i25:/,
l./al. w2 j11./, d1, i/
     jl. w3     f1.    ;   typetext (<:insert entry:>);
/,







l./d38:/, i/
d49: 0, r.4 ; initcat switches: automatic startup area name
/,


l./e0:/, d, i/


/,
l./e9:/, r/,e10=k-2//,
l./e11:/, r/,e12=k-2//,
l./e13:/, r/,e14=k-2//,
l./e15:/, d,
l./e17:/, d,
g-3/:>/<0>:>/,



l./jl.f4.,f4=k-2/, d,
i/
jl. f2.  , f2  = k-2
/,







l./; procedure dismount kit/,
l./j6=k-2/, d,
l./j8=k-2/, d,
g-2/:>/<0>:>/,
l./i10:/,
l./al. w1 j5./, d./jl. i15./, i/
     am         j5-j7  ;   text := <:delete bs:>
/,
l./al. w1 j7./, d, r/w2 j8./w1     j7./,





l./; procedure mount main catalog/,
l./j4=k-2/, d,
l./j6=k-2/, d,
l./j8=k-2/, d,
l./j10=k-2/, d,
l./j12=k-2/, d,
g-5/:>/<0>:>/,


l./i15:/,
l./al. w1 j3./, d1, i/
     am         j3-j5  ;   text := <:remove aux entry:>;
i17:                   ; error at connect main catalog:
     am         j5-j9  ;   text := <:connect main catalog:>;
i19:                   ; error at create main catalog:
     al. w1     j9.    ;   text := <:create aux entry:>;
/,
l./i17:/, d./jl.i16.;/,
l./i18:/,
l./al. w1 j7./, d, r/w2 j8./w1     j7./,
  r/out/ textline/,
l./jl. w3 f1./, d./i19:/, d./jl. i16./, i/
     jl. w3     f2.    ;
/,

l./i20:/,
l./al. w1 j11./, d, r/w2 j12/w1     j11/, r/out/ textline/,
l1, r/f1./f2./,
l./al w0 10/, d1,





l./f35:/, l1, i/
f41: jl.       (2),b121; call init write;
f42: jl.       (2),b122; call write char;
f43: jl.       (2),b123; call write text;
f44: jl.       (2),b124; call type line;
f45: jl.       (2),b125; call save work;
f46: jl.       (2),b126; goto command aborted;
f47: jl.       (2),b129; goto catalog error;
f48: jl.       (2),b130; call stack input;
/,





l./f40:/,
l./rs. w3 j0./, d./j2=k-2/, i/

     jl. w1     f2.    ;   type textline... and return;
     <:auxcat to be repaired<0>:>
/,




l./; error in init/,
d./e. ;end of scatinit;/, i/
æ12æ

; *********************************************
; *********************************************
; **                                         **
; **  main control of monitor initialization **
; **                                         **
; *********************************************
; *********************************************

b. i10 w.
i0:  f19               ; autoload device controllers
i1:  f20               ; start up device controllers

g0:                    ; init catalog:
     jl. w3     f41.   ;   init write;

     rl. w0     d36.   ;
     se  w0     0      ;   if discload then
     jl. w3    (i0.)   ;     autoload device controllers;

     jl. w3    (i1.)   ;   start up device controller;

     rl. w0     d36.   ;   w0 := discload flag;
     rl. w1     d49.   ;   w1 := first word of startup area name;
     se  w0     0      ;   if not discload
     sn  w1     0      ;   or area name <> 0 then
     jl.        i2.    ;     goto write start header;

; automatic startup is demanded
     jl. w3     g11.   ;   call (automatic oldcat);

     al. w2     d49.   ;   name := startup area name;
     jl. w3     f48.   ;   stack input (name);

     jl.        f31.   ;   goto next command;
 i2:    am   (b4)      ; get name of console 2
     rl  w2  +a199<1   ;
     dl  w1  x2+4      ;
     ds. w1  e1.+2     ;
     dl  w1  x2+8      ;
     ds. w1  e1.+6     ;
     al. w3  e1.       ; send output message
     al. w1  i3.       ;
     jd  1<11+16       ;
     jd  1<11+18       ; wait answer dont care about the answer and dont check
     jl.     f31.      ;

i3:  5<12, e19 , e20
      0, r.5           ; eight words for answer

e.                     ;

; ************************************************
; ************************************************
æ12æ
/,



l./g43:/,
l./i5:/,
l./dl w1 x3+d61+2/, r/text/textline/,
l./al. w2 j5./, d,
  r/f1/f2/,
l./al w0 10/, d1,
l./jl. g10./, r/g10/f47/,
l./i8:/,
l./jl. w3 f5./,
l1, r/:>/<0>:>/,
l./j5=k-2/, r/j5=k-2/   0  /,




l./g49:/,
l./i3:/,
l./al. w2 j6./, d,
l./jl. w3 i3./, r/w3/  /,
l./j6=k-2/, d,
g-1/:>/<0>:>/,





l./g46:/,
l-2, r/:>/<0>:>/,
l./j9=k-2/, d, i/
j10:   0,0             ; current command name
       0               ;   (end of name)
j6:  0, 0              ; saved w3,w0
/,
l./i5:/,
l./al. w1 j8./, d, r/w2 j9/w1     j8/, r/out/ textline/,
l1, r/f1/f2/,
l1, d1,
l./jl. f31. ; goto next command;/, l1, d,







l./g54:/,
l./g2:/,
l./al. w2 e12./, d./al w0 10/, i/
                       ; type textline (<:input sizeerror:>);
/,
l./jl. w3 f0./, r/f0/f2/,
l./g3:/,


l./g5:/,
l./rl w0 x1+0;/, d, i/
     dl  w1  x1+2      ;   w0 := first word of command;
     ds. w1     j10.+2 ;   save command;
                       ;   cur action := action table;
/,

l./al. w2 e14./, d,
r/f1/f2/, r/out/ textline/,

l./ ; create:/, i/

; local procedure type command;
;
; call: w2=link
; exit: w0,w2,w3=unch, w1=undef
f4:                    ; type command:
     ds. w0     j6.+2  ;   save regs;
     al. w1     j10.   ;
     jl. w3     f1.    ;   typetext (command name);
     dl. w0     j6.+2  ;   restore regs;
     jl      x2        ;   return;
/,

l./g35:/,
l./jl. g54.;/, l1, i/

e.                     ; end binin-command
/,



l./procedure initialize date./,
d./i30: 60 ; sec/, d,










l./f19:/,
l./s24=s22/,
l./w.i0:rs.w3 i2./, d./i2:/, i/
w.
i0:                    ; initialize segment:
     rl. w0     i3.    ;   initialize (top of initcat code);
     rs. w0    (i4.)   ;

     rl. w2     i5.    ;

     dl  w1  x3-2      ;   move initcat switches;
     ds  w1  x2+d37-d36;

     dl  w1  x3-10     ;   move startup area name;
     ds  w1  x2+d49+2-d36;
     dl  w1  x3-6      ;
     ds  w1  x2+d49+6-d36;

     jl        (10)    ;   goto system start;

i3:  h13               ; top of initcat code
i4:  b120              ; pointer to ...
i5:  d36               ; pointer to initcat switches

/,



l./; segment 10/,
l./j0:/, r/;/;x3-4: /,
i/
j9:              0, r.4 ;x3-12:  init cat switch: startup area name 
/,
l./j1:/, r/;/;x3-2: /,



l./i3:/,
l./rs. w2 j2./, l1, i/

; ************* note: uses special knowledge to format of autoboot-program
     dl  w1     30     ;   get startup area name from fixed part of autoboot!!!
     ds. w1     j9.+2  ;
     dl  w1     34     ;
     ds. w1     j9.+6  ;
/,


f
▶EOF◀