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

⟦79d4315b1⟧ TextFile

    Length: 95232 (0x17400)
    Types: TextFile
    Names: »cltxt       «

Derivation

└─⟦9ccaf6601⟧ Bits:30008165 Bånd med SW8000 kildetekst/release værktøjer
    └─⟦39138f30b⟧ 
        └─⟦this⟧ »cltxt       « 

TextFile

\f

;  tas 1.0 14.05.87                                   cltxt     ...1...

;********************************************************************
;*********************** Exception rutine ***************************
;*********************** Testoutput rutiner *************************
;*********************** Central logic ******************************
;********************************************************************

;
; Terminal access system for rc8000 - A/S Regnecentralen
; Erik Poulsen 


;  Revisions historie
;
;  87.01.15 release til betatest
;
;  87.05.14 release 1.0
;
;  88.01.08 side 5/6 w1=0 ved kald af e0. i d42, d44, d48, d75
;
;  88.02.25 side 11  nyt format af f21, p39 i stedet for 15
;
;  88.03.17  release 1.2
; 
;  88.25.10  side 3:  sæt pausebit i break message til s
;
;  89.08.21  side 18: c76 defineret, max create link messages
;;



\f

;  tas 1.0 14.05.87        exception routine          cltxt     ...2...

c.a89<0 ; if fp version
k=h55
z.

l0:   0                  ; abs code start addr.
      s3,s4              ; version

      am.     (l1.)      ; +6: entry:
      jl.     l1.        ; goto initialize;
l1:   l2.                ;
      0,r.5

b. i8, j6  w.            ; begin break;

u0 = k - 16              ; internal interrupt addr.

; u0+0  saved w0
; u0+2  saved w1
; u0+4  saved w2
; u0+6  saved w3
; u0+8  saved ex
; u0+10 saved ic
; u0+12 cause
; u0+14 saved sb

                         ; interrupt entry:
      rl. w3  u0.+12     ;   w2:=ic; w3:=cause;
      rs. w3  i2.        ;   set cause in break message
      al  w0  0          ;   
      al. w3  j4.        ;   set interrupt; use another interrupt
      jd      1<11+0     ;          address in this routine
      dl. w3  u0.+12     ;
      bl  w0  x2-2       ;
c.-a88-2
      sn  w3  0          ;   if couse=0 and
 h.   se w0 , ks  w.     ;     instruction= ks <no> then
      jl.     j0.        ;   begin
      bl  w0  x2-1       ;     
      ac  w0  (0)        ;     <no> := - <no>
      rs. w0  u0.+13     ;     cause:=no;
      wa. w0  i4.        ;     length:=8,type:=<no>;
      al. w1  u0.        ;     tail:=registers;
;     am.     (c0.)      ;     
;     rl  w3  f13        ;     if curco.test=1 then
\f

;. tas 1.0 14.05.87        exception routine          cltxt     ...3...

;     sz  w3  1          ;
      jl. w3  e0.        ;       curco testoutput;
      al  w0  0          ;
      al. w3  u0.        ;     set interrupt;
      jd      1<11+0     ;
      dl. w1  u0.+2      ;     reestablish all registers
      dl. w3  u0.+6      ;
      xl.     u0.+9      ;
      jl.     (u0.+10)   ;     return;
z.                       ;
j0:   bl  w1  x2-1       ;   <no> := - <no>
      ac  w1  x1         ;   if instruction=je <no> then
h.    sn  w0  , je  w.   ;   cause:=no;
      rs. w1  i2.        ;   if instruction=je <no> then
h.    sn  w0  , je  w.   ;   cause:=no;
      rs. w1  u0.+12     ;
j1:                      ; send:
c.-a88-2
      al  w2  0          ;
      am.     (c15.)     ;
      bz  w0  26         ;
      sh  w0  0          ;   if buffer claim < 1 then
      jl.     j2.        ;   goto no buffers;
      rl. w0  i6.        ;   length:=14, type:=1023;
      al. w1  u0.        ;   tail:=registers.ex,ic,cause;
      jl. w3  e0.        ;   testout;
      jl. w3  e2.        ;   outblock;
      al. w1  i5.        ;
      se  w2  0          ;   if buf > 0 then
      jd      1<11+18    ;   wait answer(buf,answer,result);
z.
                         ; send_break:
j5:   rl. w2  i2.        ;
      sh  w2  99         ;  if cause>99 then
      jl.     j6.        ;  message:=finis;
      al. w1  i7.        ;
      jl.     4          ;
j6:   al. w1  i1.        ;   send message(parent,mess,buf);
      al. w3  c16.       ;
      jd      1<11+16    ;   if buffer claim exceeded then
      se  w2  0          ;   begin
      jl.     j3.        ;
j2:   jd      1<11+26    ; no buffers: wait envent;
      se  w0  1          ;     if not answer then
\f

;. tas 1.0 14.05.87        exception routine          cltxt     ...4...

      jl.     j2.        ;     goto no buffers;
      jd      1<11+26    ;     get event; goto send;
      jl.     j1.        ;   end;
j3:   jd      1<11+18    ;   wait answer(result,mes,buf);
      jl.     0          ;   wait for ever;

j4:   0,r.8              ; interrupt addr for interrupt in
                         ;    interrupt routinen;
      jl.     j5.        ;   goto send_break;


i1:   4<12 + 1<8 + 1     ; break message to parent;
      <:break :>,0 
i2:   0 
i3:   0,0,0  
i4:   8<12
i6:   14<12+1023
i5:   0,r.8              ; answer
i7:   2<12               ; finis message to parent
      <:finis :>,0
i8:   0,r.4
e.                       ; end break;



b.   d90                 ; begin central logic;
w.

d. c.a90<2 l. z.  ; if list testoutput routines then list on
\f

;  tas 1.0 14.05.87        testoutput routines        cltxt     ...5...

c.-a88-2
b.  i20, j10, n20 w.     ; begin testoutput;

n0:           4<12 + 2
d40:  rs. w1  i1.        ; test start_coroutine:  save w1;
      rs. w3  i3.        ;   save return;
      rl. w0  n0.        ;   lenght:=4, type:=2;
      al  w1  x2         ;   tail:=ic,prio;
      jl. w3  e0.        ;   testout;
      rl. w1  i1.        ;   restore w1;
      jl.     (i3.)      ;   return;

n1:           4<12+3
d41:  rs. w3  i3.        ; test start: save return;
      ds. w1  i1.        ;   save w0,w1;
      rl. w0  n1.        ;   length:=4, type:=3;
      al. w1  i0.        ;   tail:=prio,result;
      jl. w3  e0.        ;   testout;
      dl. w1  i1.        ;   restore w0,w1;
      jl.     (i3.)      ;   return

d42:  am.     (c0.)      ; test wait: fourth:=timer;
      rl  w2  f8         ;
      al  w1  0          ;
      al  w0  4          ;   length:=0, type:=4;
      jl.     e0.        ;   testout and return;

d43:  am      1          ; test inspect: type:=6;
d44:  al  w2  5          ; test pass: type:=5;
      rx  w2  0          ;   length:=0;
      rs. w3  i3.        ;   save return;
      al  w1  0          ;
      jl. w3  e0.        ;   testout;
      al  w0  x2         ;
      jl.     (i3.)      ;   return;

n2:           10<12+7
d45:  rl. w0  n2.        ; test csensmessage: length:=10, type:=7;
      jl.     e0.        ;   testout and return;

n3:           2<12+8
d46:  rs. w0  i0.        ; test cwaitanswer:
      rl. w0  n3.        ;   length:=2, type:=8;
      al. w1  i0.        ;   tail:=timer;
      jl.     e0.        ;   testout and return;

\f

;. tas 1.0 14.05.87        testoutput routines        cltxt     ...6...

n4:           8<12
d47:  ds. w0  i3.        ; test cwaitanswer exit:
      sn  w0  1          ;   if result <> 1 then length:=0;
      am.     (n4.)      ;   else length:=8;
      al  w0  9          ;   type:=9;  tail:=answer;
      jl. w3  e0.        ;   testout;
      rl. w0  i3.        ;
      jl.     (i2.)      ;   return;

d48:  al  w0  10         ; test cregretmassage: length:=0, type:=10;
      al  w1  0          ;
      jl.     e0.        ;   testout and return;

n5:           6<12
d74:  am      1          ; test g_lock: length:=6, type:=34:
d73:  am      21         ; test g_open: length:=6, type:=33;
d50:  am      1          ; test wait_sem: length:=6, type:=12;
d49:  al  w0  11         ; test signal: length:=6, type:=11;
      wa. w0  n5.        ;
      al  w1  x2         ;   tail=semaphore;
      jl.     e0.        ;   testout and return;

d51:  am      -22        ; test wait_semafor_exit; length:=0, type:=13;
d75:  al  w0  35         ; test g_lock exit: length:=0, type:=35:
      am.     (c0.)      ;   fourth:=exit addr;
      rl  w2  f15        ;
      al  w1  0          ;
      jl.     e0.        ;   testout and return;

n6:           10<12+14
d52:  rl. w0  n6.        ; test send_letter: length:=10, type:=14;
      jl.     e0.        ;   testout and return;

n7:           2<12+15
d53:  rs. w1  i1.        ; test inspect mailbox:
      rs. w3  i3.        ;   save mask,return;
      rl. w0  n7.        ;   length:=2, type:=15;
      al. w1  i1.        ;   tail:=mask;
      jl. w3  e0.        ;   testout;
      rl. w1  i1.        ;
      jl.     (i3.)      ;   return;

n8:           2<12+16
d54:  rs. w3  i3.        ; test wait_letter:
      ds. w1  i1.        ;   tail:=mask;
      rl. w0  n8.        ;   length:=2, type:=16;
\f

;. tas 1.0 14.05.87        testoutput routines        cltxt     ...7...

      al. w1  i1.        ;
      jl. w3  e0.        ;   testout;
      rl. w0  i3.        ;
      dl. w1  i1.        ;
      jl.     (i3.)      ;   return;

n9:           12<12
d55:  rl  w2  0          ; test exit_wait_letter:
      rs. w3  i3.        ;   save return;
      se  w2  0          ;   if result=0 then length:=0
      am.     (n9.)      ;   else length:=12;
      al  w0  17         ;   type:=17;  tail:=letter;
      jl. w3  e0.        ;   testout;
      al  w0  x2         ;
      jl.     (i3.)      ;   return;

d56:  ds. w3  i3.        ; test send message: save w2,return;
      rl  w2  0          ;   fourth:=mailbox;
      rl. w0  i15.       ;   length:=18, type:=18;
      jl. w3  e0.        ;   testout;
      rl. w2  i2.        ;   restore w2;
      jl.     (i3.)      ;   return;

n10:          8<12+19
d57:  rl. w0  n10.       ; test wait_buffer: length:=8, type=19;
      jl.     e0.        ;   testout and return;

d58:  rs. w3  i3.        ; test exit wait_buffer: save return;
      ds. w2  i2.        ;   save w1,w2;
      al  w0  20         ;   length:=0, type:=20;
      am.     (c0.)      ;
      rl  w2  f18        ;   fourth:=ic;
      jl. w3  e0.        ;   testout;
      rl. w3  c0.        ;   w3:=current coroutine;
      dl. w2  i2.        ;   restore w1,w2;
      jl.     (i3.)      ;   return;

n11:          2<12+21
d59:  rs. w1  i1.        ; test release buffer: save buffer addr;
      al. w1  i1.        ;   tail:=buffer addr.;
      rl. w0  n11.       ;   length:=2, type:=21;
      jl.     e0.        ;   testout and return;

n12:          6<12+22
\f

;. tas 1.0 14.05.87        testoutput routines        cltxt     ...8...

d60:  rs. w1  i1.        ; test exit: save return;
      rl. w0  n12.       ;   length:=6, type:=22;
      al  w1  x3+f10     ;   tail:=w0 w1 w2;
      rl  w2  x3         ;   fourth:=ic;
      jl. w3  e0.        ;   testout;
      rl. w3  c0.        ;   w3:=current coroutine;
      jl.     (i1.)      ;   return;

n13:         10<12
d68:  am      1          ; test rem_answer: type:=30;
d67:  am      1          ; test tem_message: type:=29;
d66:  am      1          ; test att_answer: type:=28;
d65:  am      1          ; test message arrived: type:=27;
d64:  am      1          ; test timerscan: type:=26;
d63:  am      1          ; test message arrived: type:=25;
d62:  am      1          ; test answer arrived: type:=24;
d61:  al  w0  23         ; test answer: type:=23, length:=8;
      wa. w0  n13.       ;
      rs. w1  i1.        ;   save w1,w3;
      rs. w3  i3.        ;
      al  w1  x2+4       ;   tail=buffer(0:4); 
      jl. w3  e0.        ;   testout;
      rl. w1  i1.        ;   restore w1;
      jl.     (i3.)      ;   return;

d71:  al  w0  31         ; test create_coroutine: length:=0, type:=31;
      al  w2  x1         ;   fourth:=cda;
      jl.     e0.        ;   testout and return;

d72:  al  w0  32         ; test remove_coroutine: length:=0, type:=32;
      jl.     e0.        ;   testout and return;

n14:          4<12+36
d76:  rs. w3  i3.        ; test wait_sem_letter:
      ds. w1  i1.        ;   tail:=mask,sem addr;
      rl. w0  n14.       ;   length:=4, type:=36;
      al. w1  i0.        ;
      jl. w3  e0.        ;   testout;
      rl. w0  i3.        ;
      rl. w1  i1.        ;
      jl.     (i3.)      ;   return;

n15:          12<12
d77:  rl  w2  0          ; test exit_wait_letter:
\f

;. tas 1.0 14.05.87        testoutput routines        cltxt     ...9...

      rs. w3  i3.        ;   save return;
      se  w2  1          ;   if result=1 then length:=0
      am.     (n15.)     ;   else length:=12;
      al  w0  37         ;   type:=37;  tail:=letter;
      jl. w3  e0.        ;   testout;
      al  w0  x2         ;
      jl.     (i3.)      ;   return;

n16:          2<12+38
d78:  rs. w3  i3.        ; test get_buffer:
      rl. w0  n16.       ;   length:=2, type:=38;
      rs. w1  i1.        ;   fourth:=pool;
      al. w1  i1.        ;   tail:=buf addr;
      jl. w3  e0.        ;   testout;
      rl. w1  i1.        ;
      jl.     (i3.)      ;   return;

i0:   0                  ; saved w0
i1:   0                  ; saved w1
i2:   0                  ; saved w2
i3:   0                  ; saved w3


; procedure register_testout
; at call:  w0,w1,w2 registers der skal skrives i testoutput
;           w3 return addt
;
;           at call skal w3 peger på ord med testno<12 + testmask
;                   og w3+2 på ord med gemt værdi af w3
; at return: w0,w2,w2 unchanged, w3 indeholder gemt værdi af w3
;                                   fra return addr+2
;            proceduren returnere til return addr + 4

z.
e1:
c.-a88-2
b.  i10,j10  w.          ;
      ds. w1  j1.        ;
      rs. w2  j2.        ;  save w0,w1,w2 i testrecord;
      rs. w3  j4.        ;  save return addr
      al  w1  x3         ;
      rl  w3  x1+2       ;  hent w3 fra return addr + 2
      rs. w3  j3.        ;  save w3 i testrecord
      rl. w2  c0.        ;  w2 := curco;
\f

;. tas 1.0 14.05.87        testoutput routines        cltxt     ...10...

      rl  w3  x1         ;
      zl  w0  6          ;  sæt testrecord type
      la  w3  x2+f13     ;  if curco.testmask and mask <> 0 then
      sn  w3  0          ;  begin
      jl.     i1.        ;    length:=2, type:=fra kaldstedet
      wa. w0  j5.        ;    tail:= w0,w1,w2,w3
      al. w1  j0.        ;    testout
      jl. w3  e0.        ;  end;
i1:   dl. w1  j1.        ;  restore w0,w1,w2,w3;
      dl. w3  j3.        ;
      am.     (j4.)      ;  return;
      jl      4          ;

j0:   0                  ;  w0  :  testrecord
j1:   0                  ;  w1
j2:   0                  ;  w2
j3:   0                  ;  w3

j4:   0                  ;  saved return;
j5:   8<12 + 0           ;  testrecord længde

e.



; procedure testout;
; at call:  w0 tail length in bytes < 12 + type
;           w1 first addr of words to output
;           w2 first word to output
;           w3 return
; at return: w0 undefined, w1 w2 w3 unchanged

z.
e0:
c.-a88-2
      ds. w3  i8.        ;   save registers
      ds. w1  i6.        ;
      ls  w0  -12        ;
      wa. w0  c17.       ;   w0:=length+word addr.;
      am.     (c20.)     ;
      rl  w3  8          ;
      sl  w0  x3-8       ;   if w0+8 >= last addr then
      jl. w3  j3.        ;   outblock;
      rl. w0  i5.        ;
\f

;. tas 1.0 14.05.87        testoutput routines        cltxt     ...11...

      jl. w3  j2.        ;   outword(length<12+type);
      dl  w0  110        ;   w3,w0 := time;
      ss. w0  c8.        ;   w0,w3:=(time-start time)mod 2**29;
      la. w3  i12.       ;
      wd. w0  i9.        ;   w0:=time:=w0,w3//100;
      jl. w3  j2.        ;   outword(time);
      rl. w1  c0.        ;
      al  w0  p39        ;
      la  w0  x1+f21     ;
      ls  w0  12         ;   outword(curco.state extract 12 shift 12
      wa  w0  x1+f14     ;            + curco.ident);
      jl. w3  j2.        ;
      rl. w0  i7.        ;
      jl. w3  j2.        ;   outword(first);
      rl. w1  i6.        ;
j1:   rl. w2  i5.        ; rep:
      ws. w2  i16.       ;   length:=length-2;
      rs. w2  i5.        ;
      rl  w0  x1         ;   w0:=word to output;
      al  w1  x1+2       ;   w1:=next;
      al. w3  j1.        ;   prepare return to rep;
      sl  w2  0          ;   if length>=0 then
      jl.     j2.        ;   outword and return to rep;
      dl. w1  i6.        ;
      dl. w3  i8.        ;   reestablish w0,w1,w2,w3;
      jl      x3         ;   return;


; procedure outword;
; at call:  w0 word, w3 return
; at return: all registers unchanged

j2:   rx. w1  c17.       ;   save w1, w1:=word addr.
      rs  w0  x1         ;   buffer(word addr):=word to output;
      al  w1  x1+2       ;   word addr.:=word addr. + 2;
      rx. w1  c17.       ;   restore w1;
      jl      x3         ;   return;

; procedure outblock;
; at call:   w3 return;
; at return: all registers undefined

e2:
j3:   rs. w3  i10.       ;   save return;
\f

;. tas 1.0 14.05.87        testoutput routines        cltxt     ...12...

      al  w0  0          ;   
      rs. w0  (c17.)     ;   word(word addr.):=0;
                         ;   PS: may write outside buffer;
      rl. w0  c23.       ;
      se  w0  0          ;   if testoutput inactive then
      jl      x3         ;   return;
j4:   rl. w2  c20.       ;   cur:=current testoutput buffer;
      al  w0  1          ;
      hs  w0  x2         ;   cur.open:=true;
      al  w1  x2+4       ;
      al. w3  c18.       ;   send message(testarea,
      jd      1<11+16    ;      cur.message, buf);
      am.     (c20.)     ;
      rs  w2  2          ;   cur.buf:=buf;
      rs. w2  i14.       ;
c.a89<1                  ;
m.single testoutput buffer
      rl. w2  c20.       ; if single buffer testoutput
      jl.     j5.        ;   goto wait_ans;
z.                       ;
      al. w2  c21.       ;   testbuf:=test buffer 1;
      sn. w2  (c20.)     ;   if cur = testbuf then
      al. w2  c22.       ;    testbuf:=testbuffer 2;
      rs. w2  c20.       ;   cur:=testbuf;
      zl  w3  x2         ;
      sn  w3  0          ;   if cur.open then
      jl.     j6.        ;   begin
j5:   al  w0  0          ; wait_ans:
      hs  w0  x2         ;     cur.open:=false;
      rs. w0  i14.       ;     saved buf := 0;
      rl  w2  x2+2       ;     buf:=cur.buf;
      al. w1  i11.       ;     wait_answer(buf,
      jd      1<11+18    ;        answer,result);
      se  w0  1          ;     if result <> ok then
      jl. w3  j7.        ;     goto set inactive;
      rl. w0  i11.       ;     if status = hard then
      sz. w0  (i13.)     ;     goto set inactive;
      jl. w3  j7.        ;
      rl. w2  c20.       ;   end;
j6:   rl. w1  c24.       ;   s:= segment no;
      al  w1  x1+1       ;   s:=s+1;
      sn. w1  (c19.)     ;   if s = number of test segments then
      al  w1  1          ;     s:=1;
      rs  w1  x2+10      ;   cur.mes.segment:=s;
\f

;. tas 1.0 14.05.87        testoutput routines        cltxt     ...13...

      rs. w1  c24.       ;   segment no:=s;
      rl  w1  x2+6       ;   word addr := cur.mes.first;
      dl  w3  110        ;
      ds  w3  x1+2       ;   word(0,1):=time;
      al  w1  x1+4       ;   word addr:=word addr + 4;
      rs. w1  c17.       ;
      rl. w2  i14.       ;   w2:=buf;
      jl.     (i10.)     ;   return;

j7:   rs. w3  c23.       ; set inactive: call with link to make w3<>0;
      jl.     (i10.)     ;   return;
      
       
i5:   0                  ; saved w0         
i6:   0                  ; saved w1
i7:   0                  ; saved w2
i8:   0                  ; saved w3
i9:  100                 ;
i10:  0                  ; saved return (outblock)
i11:  0,r.8              ; answer area
i12:  31                 ; mask
i13:  -1-1<18            ; hard status bit
i14:  0                  ; saved buf
i15:  18<12 + 18         ;
i16:  2<12               ;  
\f

;  tas 1.0 14.05.87        testoutput routines        cltxt     ...14...



e.                       ; end testoutput;
z.
d. c.a90<3 l. z.  ; if list central logic then list on
\f

;  tas 1.0 14.05.87        utility routines           cltxt     ...15...



; 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:    return                unchanged

e3:
d0:   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     return             unchanged

e4:
d1:   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

;. tas 1.0 14.05.87        utility routines           cltxt     ...16...


; 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:    -               unchanged
; w2:    -               ref or 0
; w3:    return          unchanged

b.j5 w.
e5:
d7:   rl. w2  c4.        ; begin  ref := buffer_extension_head;
      sn  w2  0          ;   if ref <> 0 then
      jl.     j0.        ;   begin
      rl  w0  x2         ;     buffer_extension_head:= next(ref);
      rs. w0  c4.        ;     ref := ref + 2;
      al  w2  x2+2       ;   end;
j0:   jl      x3         ; end;
e.

\f

;  tas 1.0 14.05.87        CL variables               cltxt     ...17...

m.cl variables

; variable in central logic

c0:       0              ; current coroutine descriptor addr.
c1:       0,0            ; head active queue
c2:       0,0            ; head timer queue
c4:       0              ; head message extention list
c5:       0              ; cdescr pool addr
c7:       0              ; addr på event descr for messages til tas
          0
c8:       0              ; own start time
c10:      0              ; first free core
c11:      0              ; top used core
c12:      1              ; coroutine ident

c13:      0,r.5          ; navn på ps processen tem

c15:      0              ; own process descriptor addr.
c16:      0,r.5          ; parent name

c17:      0              ; word addr. (testoutput buffer)
c18:      <:rcmtest:>,0,0; testoutput doc name
c19:      0              ; number of segment in testoutput area
c20:      0              ; current testoutput descriptor
                         ; testbuffer descriptor 1
c21:      0<12+9         ;   open, proc ( ignore answer )
          0              ;   buf
          5<12           ;   output message
          0,             ;    first
          0,             ;    last
          0,             ;    segment no
c22:      0<12+9         ; testbuffer descriptor 2
          0
          5<12
          0,0,0
c23:      0              ; testoutput active
c24:      0              ; segment count

c25:      0,r.8          ; common answer area
c26:      <:tas:>,0,0,0,0;<:tascat:>
c27:      0,r.5          ; <:tasspool:>
c28:      0,r.3          ; coretable_lock semaphor
c30:      0              ; free_att pool addr
\f

;. tas 1.0 14.05.87        CL variables               cltxt     ...18...

c31:      0,0            ; used_att, head of chain
c32:      0              ; coretabel_base
c33:      0              ; coretable_top
c34:      0              ; coretable_size
c35:      0              ; c_entry
c36:      0              ; curretn_prio
c37:      0              ; free_head
c38:      0              ; corebuffer_base
c39:      0              ; segment_table_base
c40:      0              ; areatable_base
c41:      0              ; top_areatabel
c42:      0              ; ss
c44:      0              ; mcltable_base
c45:      0              ; top_mcltable
c46:      0              ; first_ttda
c47:      0              ; top_ttda
c48:      0              ; free_term
c49:      0              ; first_ph
c50:      0              ; tdescr_pool
c51:      0              ; used_tdescr
c52:      0,r.3          ; lock_sem
c53:      0              ; max_tbuf_size
c54:      0              ; std seg i link spool area
c55:      0              ; addr signon text buffer
          0              ; lower
c56:      0              ; upper name base for terminal ps processer
          0              ; lower
c57:      0              ; upper std name base for mcl programmer
          0              ; lower
c58:      0              ; upper name base for spool/test area
c59:      0              ; pda for tascat processen
c60:      0              ; (antal timeout på term i mcl) shift 12
c61:      0              ; systxt pool adresse
c62:      0              ; antal hw i tekst delen af systext buffer
;c63: se neden for
c64:      0              ; pda for ps processen tem
c75:      0              ; send message til remoter
c76:      0              ; max create link messages

; de næste 8 ord bruges som svar på get stat message fra tascat

c65:      0              ; max pools efter create pool message
c66:      0              ; th efter create link
c67:      0              ; sm coroutiner aktive
c68:      0              ; frie corebuffere
\f

;. tas 1.0 14.05.87        CL variables               cltxt     ...19...

c69:      0              ; frie mcltable indgange
c70:      0              ; frie terminal type beskrivelser
c71:      0              ; antal segmenter i spool området
c43:      0              ; free  ( frie segmenter i spool  området )

; cdescr for cl

c72:      0              ; saved ic
          0              ; prio
c63:      0              ; test maske
          0              ; state
          0              ; ident

m.end cl variable

; procedure table for procedure called from check_event_queue
;              nr
c98:   d10.   ; 0 answer
       d11.   ; 1 answer arrived
       d12.   ; 2 message
       d13.   ; 3 message arrived
       d14.   ; 4 tem message
       d15.   ; 5 timerscan
       d16.   ; 6 att answer
       d17.   ; 7 rem answer
       d18.   ; 8 answer tas
       d19.   ; 9 ignore answer

c99=k

\f

;  tas 1.0 14.05.87        central wait               cltxt     ...20...


; 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.
;
;        call            return
; w0:    -               saved w0 from coru. descr
; w1:    -               saved w1 from coru. descr
; w2:    -               saved w2 from coru. descr
; w3:    -               current coroutine descriptor addr.

b.j5 w.
e70:                     ; entry after init:
d2:                      ; begin
      al. w3  c72.       ;   curco:=cl cdescr;
      rs. w3  c0.        ;
                         ;   repeat
j0:   jl. w3  d6.        ;     check event queue;
      rl. w3  c1.        ;     if active queue empty then
      se. w3  c1.        ;     begin
      jl.     j1.        ;       buf := last buf;
      jd      1<11+24    ;       wait event(buf,result);
      jl.     j0.        ;     end;
j1:   al  w3  x3-f2      ;   until active queue not empty;
      rs. w3  c0.        ;   corout:= first in active queue;
c.a88<1                  ; if testoutput
      rl  w0  x3+f13     ;
      sz  w0  1<1        ;   if CL testout then
      jl. w1  d60.       ;   test exit; ( type 22 )
z.                       ;
      dl  w1  x3+f11     ;   restore w0, w1, w2 from corout;
      rl  w2  x3+f12     ;   restart corout;;
      jl      (x3)       ; end;
e.
\f

;  tas 1.0 14.05.87        check eventqueue           cltxt     ...21...

; procedure check eventqueue;
;
; inspects the eventqueue starting from the start.
; the scheduling is performed by calling a procedure.
;

; a procedure  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 scheduling procedure with:
;                        w0:     -
;                        w1:     ref(event descriptor)
;                        w2:     buf
;                        w3:     return
;                        and return with
;                        w0
;                        w1
;                        w2      buf
;                        w3
;
; check must be called with
;
;        call            return
; w0:    -               destroyed
; w1:    -               destroyed
; w2:    -               last event
; w3:    return          destroyed
  
b. j10, i5 w.
d6:   rs. w3  i0.        ; begin   save return;
      al  w2  0          ;   last_buf := 0;
j0:   jd      1<11+66    ;   repeat
      sh  w0  -1         ;     test_event(last_buf,buf,result);
      jl.     j5.        ;     if result <> empty then
      se  w0  0          ;     begin
      jl.     j2.        ;       if result = message then
      rl  w1  x2+4       ;
      ac  w1  x1         ;         ref :=
      se. w1  (c15.)     ;          if buf.receiver = cur then
      jl.     j1.        ;            messdescr
      rl. w1  c7.        ;          else buf.receiver.pseudoprocess.messdescr
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...22...

      jl.     j2.        ;
j1:   rl  w1  x1+16      ;       else <* answer *> ref:= buf.ref;
j2:   hl  w0  x1         ;
      sn  w0  0          ;
      jl.     j0.        ;       if ref.open then
      hl  w0  x1+1       ;       begin
      ls  w0  1          ;         call cmonproc(buf,ref);
      am      (0)        ;       end;
      jl. w3  (c98.)     ;     end;
      jl.     j0.        ;     last_buf := buf;
                         ;   until result = empty;
j5:   jl.     (i0.)      ; end;

i0:   0                  ; saved return;
e.



; procedure answer(ref,buf);
;
; this procedure is called from procedure 'check_event_queue' when an
; answer to a message, sent by 'sendmessage, has arrived. (proc=0)
; 'ref' contains the address of the answer_descriptor and 'buf' contains the
; message buffer address. the answer is signalled to the mailbox
; given in answer_descriptor.
; 
;        call            return
; w0:    -               destr.
; w1:    ref             destr.
; w2:    buf             buf
; w3:    return          unchanged

b.j5, i5 w.
d10:  ds. w3  i0.        ; begin
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d61.       ;   test answer; ( type 23 )
z.                       ;
      al  w0  0          ;   with ref do
      hs  w0  x1         ;   begin
      al  w0  1<1        ;     open:= false;
      rs  w0  x1+8       ;     type:= answer;
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...23...

      rs  w2  x1+10      ;
      rl  w2  x1+2       ;     mailbox := answer_mailbox;
      al  w1  x1+4       ;     letter := message extention + 4;
      jl. w3  e30.       ;     send_letter(mailbox,letter);
      dl. w3  i0.        ;   end;
      jl      x3         ; end;
      0                  ; saved buf
i0:   0                  ; saved return
e.



; procedure answer arrived(ref,buf);
;
; 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)' (proc=1). The coroutine is activated and 
; the answer descriptor is closed.
;
;        call            return
; w0:    -               destroyed
; w1:    ref             destroyed
; w2:    buf             buf
; w3:    return          unchanged
  
b.j5, i5 w.
d11:  ds. w3  i0.        ; begin  save buf, return;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d62.       ;   test answer arrived;  ( type 24 )
z.                       ;
      al  w0  0          ;
      hs  w0  x1         ;   ref.open:= false;
      rl  w2  x1+2       ;   corout:= ref.param1;
      al  w1  1          ;   result:= ok;
      rl  w0  x2+f1      ;   priority:= corout.priority;
      jl. w3  e10.       ;   start(corout,priority,ok);
      dl. w3  i0.        ;   restore buf, return;
      jl      x3         ; end;

      0                  ; saved buf
i0:   0                  ; saved return
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...24...

e.



; procedure message(buf,ref);
;
; this procedure is called from 'check_event_queue' when a message is
; received and mess_descr.proc = 'message' (proc=2). the message
; descriptor must contain an letter and the address of a mailbox.
;
;       eda +0:  1<12 + 2
;           +2:  open
;           +4:  mailbox addr
; letter -> +6:
;           +8:
;          +10:  1<2
;          +12:  buffer addr
;
;
;        call            return
; w0:    -               destr.
; w1:    eda             destr.
; w2:    buf             0 (the message buffer is removed)
; w3:    return          destr.
                         
b. j5, i5 w.

d12:  rs. w3  i0.        ; begin
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d63.       ;   test message;  ( type 25 )
z.                       ;
      rl  w0  x1+2       ;   if eda.open=0 then
      sn  w0  0          ;   return
      jl.     (i0.)      ;
      jd      1<11+26    ;   getevent(buf);
      al  w0  0          ;   with ref do
      rs  w0  x1+2       ;   begin
      al  w0  1<2        ;     open:= false; <* the message class must be
                         ;                      explicitly opened by a
                         ;                      receiving coroutine  *>
      rs  w0  x1+10      ;     letter.type:= message;
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...25...

      rs  w2  x1+12      ;
      rl  w2  x1+4       ;     letter.buffer:= buf;
      al  w1  x1+6       ;     sem:= message_sem;
      jl. w3  e30.       ;     send_letter(mailbox,letter);
      rl. w3  i0.        ;   end;
      al  w2  0          ;   buf:= 0; <* has been removed *>
      jl      x3         ; end;
i0:   0                  ; saved return;
e.



; procedure message_arrived(buf,ref);
;
; this procedure is called from 'check_event_queue' when a message is
; received and mess_descr.proc = 'message arrived' (proc=3). the message
; descriptor must contain an letter and the address of a mailbox.
;
;       eda +0:  1<12 + 3
;           +2:  open1 < 12 + open2
;           +4:  mailbox addr
; letter -> +6:                      sendes hvis open1<>0 og opcode
;           +8:                      i buffer er >=9 og <=106
;          +10:  1<3
;          +12:  buffer addr
; letter ->+14:                      sendes hvis open2<>0 og opcode 
;          +16:                      i buffer er <9 eller >106
;          +18:  1<4
;          +20:  buffer addr
;
;
;        call            return
; w0:    -               destr.
; w1:    eda             destr.
; w2:    buf             0 (the message buffer is removed)
; w3:    return          destr.
                         
b. j5, i5 w.

d13:  rs. w3  j0.        ;  save return
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<0        ;   if CL testout then
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...26...

      jl. w3  d65.       ;   message arrived; ( type 27 )
z.                       ;
      zl  w0  x2+8       ;  w0:=buf.opcode;
      sh  w0  106        ;  
      sh  w0  8          ;  if w0<=106 or w0>=9 then begin
      jl.     i1.        ;
      zl  w0  x1+2       ;    if eda.open1<>0 then begin
      sn  w0  0          ;
      jl.     i3.        ;      get_event(buf);
      jd      1<11+26    ;
      al  w0  0          ;      eda.open1:=0;
      hs  w0  x1+2       ;      let:=eda+6;
      al  w0  1<3        ;      let.type:=1<3;
      rs  w0  x1+10      ;      let.buf:=buf;
      rs  w2  x1+12      ;      mbx:=eda.mbx;
      rl  w2  x1+4       ;      goto S;
      al  w1  x1+6       ;    end else goto exit;
      jl.     i2.        ;  end;
i1:   zl  w0  x1+3       ;  /* w0>106 eller w0<9 */
      sn  w0  0          ;  if eda.open2<>0 then
      jl.     i3.        ;    goto exit;
      jd      1<11+26    ;  get_event(buf);
      al  w0  0          ;
      hs  w0  x1+3       ;  eda.open2:=0;
      al  w0  1<4        ;  let:=eda+14;
      rs  w0  x1+18      ;  let.type:=1<4;
      rs  w2  x1+20      ;  let.buf:=buf;
      rl  w2  x1+4       ;  mbx:=eda.mbx;
      al  w1  x1+14      ;
i2:   jl. w3  e30.       ; S: send_letter(mbx,let);
      al  w2  0          ;  buf:=0;
i3:   jl.     (j0.)      ; exit: return;

j0:   0                  ;  saved return;

e.



; procedure tem_message(buf,ref);
;
; this procedure is called from 'check_event_queue' when a message is
; received and mess_descr.proc = 'tem message' (proc=4). the message
; descriptor must contain an letter and the address of a mailbox.
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...27...

;
;           -4:  next         hoved til sender kæde
;           -2:  prev
;       eda +0:  1<12 + 4
;           +2:  open
;           +4:  mailbox addr
; letter -> +6:                      sendes hvis open<>0 og opcode
;           +8:                      i buffer er >=90 eller <=99
;          +10:  1<3                 eller =106
;          +12:  buffer addr
;
;
;        call            return
; w0:    -               destr.
; w1:    eda             destr.
; w2:    buf             0 (the message buffer is removed)
; w3:    return          destr.

b.  i5,j5  w.

d14:  rs. w3  j0.        ;  save return;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<0        ;   if CL testout then
      jl. w3  d67.       ;   test tem message; ( type 29 )
z.                       ;
      zl  w0  x2+8       ;  w0:=buf.opcode;
      sh  w0  99         ;
      sh  w0  89         ;  if (w0>99 or w0<90 )
      jl.     4          ;     or w0<>106 then begin
      jl.     i2.        ;    
      sn  w0  106        ;
      jl.     i2.        ;
      rl  w0  x2+6       ;    sender:=buf.sender;
      al  w3  x1-4       ;    w3:=addr eda.next;
      rs. w3  j1.        ;    start:=w3;
i1:   rl  w3  x3         ;    while w3.next<>start do begin
      sn. w3  (j1.)      ;      if w3.sender=sender then
      jl.     i5.        ;        goto found;
      se  w0  (x3+4)     ;    goto not_found;
      jl.     i1.        ;
      al  w1  x3+4       ; found:  message_arrived(eda,buf);
      rl. w3  j0.        ;    prepare return;
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...28...

      jl.     d13.       ;  end;

i2:   rl  w0  x1+2       ;  /* w0<=99 and w0>=90 or w0=106 */
      sn  w0  0          ;  if eda.open<>0 then begin
      jl.     i4.        ;  
      jd      1<11+26    ;    get_event(buf);
      al  w0  0          ;    eda.open:=0;
      rs  w0  x1+2       ;    let:=eda+6;
      al  w0  1<3        ;    let.type:=1<4;
      rs  w0  x1+10      ;    let.buf:=buf;
      rs  w2  x1+12      ;    mbx:=eda.mbx;
      rl  w2  x1+4       ;    send_letter(mbx,let);
      al  w1  x1+6       ;  end;
      jl. w3  e30.       ;
      al  w2  0          ;  buf:=0;
i4:   jl.     (j0.)      ;  return;

i5:   jd      1<11+26    ; not_found: get_event(buf);
      al  w0  1          ;  result:=1;
      al. w1  j2.        ;  answer:=(status=p48); /* pool findes ikke */
      jd      1<11+22    ;  send_answer(result,answer,buf);
      al  w2  0          ;  buf:=0;
      jl.     (j0.)      ;  return;

j0:   0                  ; saved return;
j1:   0                  ; sender
j2:   p48                ; answer (pool findes ikke)

e.



; procedure timerscan(ref,buf);
;
; this procedure is called from 'check_event_queue' when an answer arrives
; from 'clock'(proc=5). 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:        return            unchanged
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...29...


b.j5,i5 w.
d15:  rs. w3  i0.        ; begin
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d64.       ;   test timerscan: ( type 26 )
z.                       ;
      al. w1  i2.        ;   <* release messagebuffer *>
      jd      1<11+18    ;   wait_answer(clock_mess_area,buf);
j4:                      ;
      al. w2  c2.        ;   corout:= first in timer queue;
j1:   rl  w2  x2         ;   while corout <> timer queue head do
j3:   sn. w2  c2.        ;   begin
      jl.     j2.        ;     corout:= next(corout);
      rl  w1  x2-f2+f8   ;     with corout do
      sh  w1  0          ;     begin
      jl.     j1.        ;       if timer > 0 then
      al  w1  x1-a3      ;       begin
      sh  w1  0          ;         timer:=timer-a3;
      al  w1  0          ;         if timer <=0 then
      rs  w1  x2-f2+f8   ;         timer:=0;
      se  w1  0          ;
      jl.     j1.        ;         if timer = 0 
      rl  w0  x2         ;            then start(corout,prio,timeout);
      rs. w0  i1.        ;
      al  w2  x2-f2      ;
      rl  w0  x2+f1      ;       end;
      al  w1  0          ;     end;
      jl. w3  e10.       ;
      rl. w2  i1.        ;
      jl.     j3.        ;   end while;
j2:   jl. w3  e40.       ;   timer_message;
      rl. w3  i0.        ;   link:= ext1(16);
      al  w2  0          ;   buf:= 0; <* has been removed *>
      jl      x3         ; end;
i0:   0                  ; saved return
i1:   0                  ; saved next coroutine;
i2:   0,r.8              ; answer area
e.



\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...30...

; procedure att_answer(ref,buf);
;
; Proceduren kalds fra 'check_event_queue' når proc=6 i eda.
; Proceduren behandler svar på attention message sendt fra en pool handler
; til ejer af poolen. Event descriptor skal indeholde
;
;    eda + 0:  1<12 + 6
;        + 2:  mbuf       message buffer addr
;        + 4:  avar       var addr
;        + 6:  next       kædefelt
;
; Proceduren henter svaret med wait_answer og hægter eda ud af used_att
; kæden, og sætter eda tilbage til poolen free_att. Variablen hvis
; adresse står i avar nulstilles.
;
;            call              return
; w0:        -                 destr.
; w1:        ref               destr.
; w2:        buf               0 (the message buffer is removed)
; w3:        return            unchanged

b.j5,i5 w.

d16:  rs. w3  j0.        ;  save return;
      rs. w1  j1.        ;  save eda;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d66.       ;   test att answer; ( type 28 )
z.                       ;
      al. w1  c25.       ;
      jd      1<11+18    ;  wait_answer(buf,ans,r);
      rl. w1  j1.        ;
      al  w0  0          ;
      rs  w0  (x1+4)     ;  word(ref.avar):=0;
      rl. w1  c31.       ;  buf:=next(used_att);
      al  w2  0          ;  prev:=0;
i1:   sn  w1  0          ;  while buf<>0 do
      jl.     i3.        ;  begin
      sn. w1  (j1.)      ;    if buf=eda then
      jl.     i2.        ;     goto F;
      al  w2  x1         ;    prev:=next(buf);
      rl  w1  x1+6       ;    buf:=next(buf);
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...31...

      jl.     i1.        ;  end;
                         ;  goto NF;
i2:   rl  w0  x1+6       ; F: p:=next(buf);
      se  w2  0          ;  if prev<>0 then
      rs  w0  x2+6       ;    next(prev):=p;
      sn  w2  0          ;  if prev=0 then
      rs. w0  c31.       ;    used_att:=p;
      sn  w0  0          ;  if p=0 then
      rs. w2  c31.+2     ;   used_att.last:=p;
      rl. w2  c30.       ;  w2:=addr free_att;
      jl. w3  e57.       ;  release_bufffer(buf,free_att);
i3:   al  w2  0          ; NF: w2:=0;
      jl.     (j0.)      ;  return

j0:   0                  ; saved return
j1:   0                  ; saved eda

e.



; procedure rem_answer(ref,buf);
;
; Proceduren kaldes fra 'check_event_queue' når proc=7 i eda.
; Proceduren behandler svar på remove message sendt fra en pool handler
; til ejer af poolen. Event descriptor skal indeholde
;
;        eda + 0:  open<12 + 6
;            + 2:  mbx          mailbox addr
;(letter->)  + 4:
;            + 6:
;            + 8:  1<6          type
;            +10:  0
;            +12:  2            opcode
;
; Proceduren sætter open=0 og sender eda+4 og fremsom et letter til
; den mailbox hvis adresse der står i eda+2.
;
;            call              return
; w0:        -                 destr.
; w1:        ref               destr.
; w2:        buf               0 (the message buffer is removed)
; w3:        return            unchanged

\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...32...

b.j5,i5 w.

d17:  rs. w3  j0.        ;  save return;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d68.       ;   test rem answer; ( type 30 )
z.                       ;
      al  w0  0          ;
      hs  w0  x1         ;  eda.open:=0;
      rl  w2  x1+2       ;  send_letter
      al  w1  x1+4       ;    (eda.mbx,eda+4);
      jl. w3  e30.       ;
      al  w2  0          ;  w2:=0;
      jl.     (j0.)      ;  return

j0:   0                  ; saved return

e.


; procedure answer_tas(ref,buf);
;
; Proceduren kalds fra 'check_event_queue' når proc=8 i eda.
; Proceduren behandler svar på en message hvor svaret skal ignoreres.
; og samtidigt sendes svar på den message hvis buffer addr står i
; eda+2
;
;    eda + 0:  1<12 + 8
;        + 2:  mbuf
;
;            call              return
; w0:        -                 destr.
; w1:        ref               destr.
; w2:        buf               0 (the message buffer is removed)
; w3:        return            unchanged

b.j5,i5 w.

d18:  rs. w3  j0.        ;   save return
      al  w3  x2         ;   gem buf i w3
      rl  w2  x1+2       ;   w2:=mbuf
      al  w0  x1-2       ;   sæt buf ext tilbage i pool
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...33...

      rx. w0  c4.        ;
      rs  w0  x1-2       ;
c.a88<1
      rs. w3  6          ;   testout registers
      jl. w3  e1.        ;
      h. 39  , 1<1 w.    ;   type:=39, mask:=1<1
      0                  ;
z.
      al. w1  c25.       ;   answer.status:=0;
      al  w0  0          ;
      rs  w0  x1         ;
      al  w0  1          ;   result:=normal
      jd      1<11+22    ;   send answer  /* til tascat */
      al  w2  x3         ;   /* hent svar på output message */
      al. w1  c25.       ;   wait_answer(ans,buf,res);
      jd      1<11+18    ;
      al  w2  0          ;   buf:=0;
      rl. w3  j0.        ;
      jl      x3         ;   return;

j0:   0                  ;
e.



; procedure ignore_answer(ref,buf);
;
; Proceduren kalds fra 'check_event_queue' når proc=9 i eda.
; Proceduren behandler svar på en message hvor svaret skal ignoreres.
;
;    eda + 0:  1<12 + 9
;
;            call              return
; w0:        -                 destr.
; w1:        ref               destr.
; w2:        buf               0 (the message buffer is removed)
; w3:        return            unchanged

b.j5,i5 w.

d19:  al  w0  0          ;
      hs  w0  x1         ;   open:=false;
      al. w1  c25.       ;   wait_answer(ans,buf,res);
      jd      1<11+18    ;
      al  w2  0          ;   buf:=0;
      jl      x3         ;   return;
\f

;. tas 1.0 14.05.87        check eventqueue           cltxt     ...34...


e.



\f

;  tas 1.0 14.05.87        start coroutine            cltxt     ...35...


; procedure start_coroutine(priority,ic,corout)
; initialze coroutine descriptor and put it in
; active queue
;
;                 call               return
; w0:             priority           destroyed
; w1:             ic                 destroyed
; w2:             corout             corout
; w3:             return             current coroutine


; procedure 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:             return             current coroutine
  
b.j5, i5 w.
e51:  rs. w3  i0.        ; start coroutine: begin  save return;
      rs  w1  x2         ;   corout.ic := ic;
      rl. w1  c12.       ;   coroutine.ident := ident;
      rs  w1  x2+f14     ;   ident := next ident;
      al  w1  x1+1       ;
      rs. w1  c12.       ;
      rs  w0  x2+f1      ;   coroutine.prio := priority;
      rl. w0  c63.       ;   coroutine.test mask := testmask;
      rs  w0  x2+f13     ;
c.a88<1                  ; if testoutput
      rl  w0  x2+f13     ;
      sz  w0  1<0        ;   if CL testout then
      jl. w3  d40.       ;   test start_coroutine; ( type  2 )
z.                       ;  
      al  w2  x2+f2      ;  
      jl.     j3.        ;   goto com;
      
e10:  rs. w3  i0.        ; start:   save return;
\f

;. tas 1.0 14.05.87        start coroutine            cltxt     ...36...

c.a88<1                  ; if testoutput
      rl  w3  x2+f13     ;
      sz  w3  1<1        ;   if CL testout then
      jl. w3  d41.       ;   test start; ( type  3 )
z.                       ;
      rs  w1  x2+f10     ;   corout.result:= result;
      rs  w0  x2+f1      ;   corout.priority:= priority;
      al  w2  x2+f2      ;
      jl. w3  d0.        ;   remove(corout);
      rl  w1  0          ;
j3:   al  w0  x2         ; com:   worse:= rear of active queue;
      al. w3  c1.        ;   while worse.prio > prio        and
      al  w1  x1+1       ;         worse <> active queue head do
j1:   rl  w3  x3+2       ;   worse:= prev(worse);
      sn. w3  c1.        ;
      jl.     j2.        ;   'insert corout in the rear of 
      sh  w1  (x3-f2+f1) ;    other coroutines of the same
      jl.     j1.        ;    priority'
j2:   rl  w1  x3         ;
      rl  w2  0          ;
      jl. w3  d1.        ;   link(worse,corout);
      al  w2  x2-f2      ;
      rl. w3  c0.        ;
      jl.     (i0.)      ; end;

i0:   0                  ; saved returne.
e.
\f

;  tas 1.0 14.05.87        wait                       cltxt     ...37...


; procedure 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:                                  unchanged
; w2:                                  unchanged
; w3               return              current coroutine
  
b.j5 w.

e11:  rs. w3  (c0.)      ; begin  curco.return:= return;
      rl. w3  c0.        ;
      rs  w0  x3+f8      ;   curco.timer:= timer;
      ds  w2  x3+f12     ;   curco.w1:=w1; curco.w2:=w2;
c.a88<1                  ; if testoutput
      rl  w0  x3+f13     ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d42.       ;   test wait; ( type  4 )
      rl. w3  c0.        ;
z.                       ;
      al  w2  x3+f2      ;
      jl. w3  d0.        ;   remove(current coroutine);
      al. w1  c2.        ;
      jl. w3  d1.        ;   link(timer queue head,current coroutine);
      jl.     d2.        ;   central wait;
                         ; end;
e.
\f

;  tas 1.0 14.05.87        pass                       cltxt     ...38...


; procedure 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:         return             current coroutine
  
b.j5 w.
e12:  rs. w3  (c0.)      ; begin current coroutine.ic = return;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w3  f13        ;
      sz  w3  1<0        ;   if CL testout then
      jl. w3  d44.       ;   test pass; ( type  5 )
z.                       ;
      rl. w2  c0.        ;
      rl  w1  x2+f10     ;   result:= current_coroutine.result;
      jl. w3  e10.       ;   start(current_coroutine,priority,result);
      jl.     d2.        ;   central wait;
e.                       ; end;
\f

;  tas 1.0 14.05.87        inspect                    cltxt     ...39...


; procedure 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:    return          current coroutine

b.j5, i5 w.

e13:  ds. w3  i1.        ; begin save return, priority;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<0        ;   if CL testout then
      jl. w3  d43.       ;   test inspect; ( type  6 )
z.                       ;
      jl. w3  d6.        ;   check_event_queue;
      rl. w0  i1.        ;   restore priority;
      rl. w3  c1.        ;   corout:= first in active queue;
      sl  w0  (x3+f1)    ;
      am      -1         ;   result:= corout.prio > priority;
      al  w0  1          ;
      rl. w3  c0.        ;
      jl.     (i0.)      ; end;
i0:   0                  ; saved return
i1:   0                  ; saved priority
e.


; procedure create_coroutine(cda);
;
; Henter en coroutine beskrivelse fra puljen af frie, og initialisere
; den til 0. I coroutine beskrivelsen initialiseres, main_mbx,
; stop_sem og next,prev til aktivkæden.
;
;        call            return
; w0:                    unch
; w1:                    cda eller 0
\f

;. tas 1.0 14.05.87        inspect                    cltxt     ...40...

; w2:                    unch
; w3:    return          current coroutine

b. i5,j5  w.

e14:  rs. w0  j0.        ;  save w0,w2, return;
      ds. w3  j2.        ;
      rl. w2  c5.        ;  
      jl. w3  e55.       ;  get_buffer(cdescr,cda);
      sn  w1  0          ;  if cda<>0 then 
      jl.     i2.        ;  begin
      al  w2  x1+q200-2  ;
      al  w0  0          ;    for all words in coroutine descriptor do
i1:   rs  w0  x2         ;     word:=0;
      al  w2  x2-2       ;
      se  w2  x1         ;  end;
      jl.     i1.        ;
      al  w2  x1+f2      ;  q:=addr cda.active_next;
      rs  w2  x1+f2      ;  cda.active_next:=q;
      rs  w2  x1+f3      ;  cda.active_prev:=q;
      al  w2  x1+f22     ;
      jl. w3  e53.       ;  init_mailbox(cda.main_mbx);
      al  w0  0          ;
      al  w2  x1+f26     ;
      jl. w3  e52.       ;  init_semaphor(cda.stop_sem,0);
i2:
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w3  f13        ;
      sz  w3  1<0        ;   if CL testout then
      jl. w3  d71.       ;   test create coroutine; ( type 31 )
z.                       ;
      rl. w0  j0.        ;
      rl. w2  j1.        ;  restore w0,w2;
      rl. w3  c0.        ;  w3:=curco;
      jl.     (j2.)      ;  return

j0:   0                  ; saved lock_count
j1:   0                  ; saved w2
j2:   0                  ; saved return

e.


\f

;. tas 1.0 14.05.87        inspect                    cltxt     ...41...


; procedure remove_coroutine(cda);
;
; hægter en coroutine ud af aktiv/timer køen og sætter coroutine
; beskrivelsen tilbage til puljen af frie. Hvis lock_count i coroutinen
; er større end nul åbnes lock_sem tilsvarende.
;
;        call            return
; w0:                    undef
; w1:                    undef
; w2:    cda             undef
; w3:    return          current coroutine

b. i5  w.

e15:  rs. w3  (c0.)      ; curco.return:=return;
      rs. w2  i0.        ;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<0        ;   if CL testout then
      jl. w3  d72.       ;   test remove coroutine; ( type 32 )
z.                       ;
      al  w2  x2+f2      ;
      jl. w3  d0.        ;  remove(cda);
      al  w1  x2-f2      ;
      rl  w0  x1+f25     ;
      al. w2  c52.       ;
      se  w0  0          ;  if cda.lock_count>0 then
      jl. w3  e23.       ;    g_open(lock_sem,cda.lock_count);
      rl. w2  c5.        ;
      jl. w3  e57.       ;  release_buffer(cda,cdescr);
      jl.     d2.        ;  central wait;
i0:   0                  ; saved cda

e.



\f

;  tas 1.0 14.05.87        csendmessage               cltxt     ...42...

; procedure csendpseudomessage(pda,mes,name,buf);
;
; allocates a message buffer extension and prepares it for cwaitanswer.
; then calls sendpseudomessage.
;
; return parameter 'buf': 0        buffer claims exceeded
;                         1        no free extensions
;                        >1        message buffer address
;
;               call               return
; w0:           pda                destroyed
; w1:           mess               destroyed
; w2:           name               buffer address (or 0 or 1)
; w3:           return             current coroutine


; procedure csendmessage(mes,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:           return             current coroutine
 
b.j5,i5 w.

e16:  al  w0  0          ; begin csendpseudomessage:
                         ;   pda:=0;
e17:  rs. w3  i4.        ; begin csendpseudomessage;
      rs. w0  i5.        ;   save pda;
      ds. w2  i2.        ;   save mess, buf;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<0        ;   if CL testout then
      jl. w3  d45.       ;   test csendmessage; ( type  7 )
z.                       ;
\f

;. tas 1.0 14.05.87        csendmessage               cltxt     ...43...

      jl. w3  d7.        ;   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;
      rs. w2  i3.        ;     save ref buf ext;
      rl. w1  i1.        ;
      rl. w3  i2.        ;
      rl. w0  i5.        ;     if pda=0 then
      se  w0  0          ;       send message(mess,name,buf,ref)
      am      108        ;     else
      jd      1<11+16    ;       send pseudo message(pda,mess,name,buf,ref);
      se  w2  0          ;     if buffer claims exceeded
      jl.     j2.        ;        then release message buffer extension;
      rl. w1  i3.        ;
      al  w0  x1-2       ;
      rx. w0  c4.        ;
      rs  w0  x1-2       ;
      jl.     j2.        ;
j1:   al  w2  1          ;   end
j2:   rl. w3  c0.        ;   else buf:= 1; <* no free extensions *>
      jl.     (i4.)      ; end;

i0:   0<12+1             ; answer descriptor init (open=false,proc='answer_arived')
i1:   0                  ; saved mess
i2:   0                  ; saved name addr
i3:   0                  ; saved ref buf ext
i4:   0                  ; saved return
i5:   0                  ; saved pda
e.
\f

;  tas 1.0 14.05.87        cwaitanswer                cltxt     ...44...

; procedure cwaitanswer(buf,timer,result);
;
; prepares the message buffer extension for receiving the answer.
; 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 central logic 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       unch
; w2:           buf               buf
; w3:           return            current coroutine
  
b.j10,i5 w.
e18:  ds. w0  i1.        ; begin
      rs. w1  i2.        ;
      rl. w1  i0.        ;   current_coroutine.return:= return;
      rl. w3  c0.        ;
      ds  w2  x3+f16     ;   current_coroutine.buf:= buf;
c.a88<1                  ; if testoutput
      rl  w3  x3+f13     ;
      sz  w3  1<0        ;   if CL testout then
      jl. w3  d46.       ;   test cwaitanswer; ( type  8 )
      rl. w3  c0.        ;
z.                       ;
      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  i1.        ;   restore timer;
      rl. w1  i2.        ;
      jl. w3  e11.       ;   wait(timer,result);
      rs. w1  i2.        ;
      rl  w2  x3+f16     ;   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         ;
\f

;. tas 1.0 14.05.87        cwaitanswer                cltxt     ...45...

      jl.     j4.        ;      else
j2:                      ;      begin <* result = answer arrived *>
      al  w0  x1-2       ;        release message buffer extension;
      rx. w0  c4.        ;
      rs  w0  x1-2       ;
      rl. w1  i2.        ;
      jd      1<11+18    ;        wait answer(buf,answer_area);
j4:   rl. w3  c0.        ;      end;
c.a88<1                  ; if testoutput
      rl  w3  x3+f13     ;
      sz  w3  1<0        ;   if CL testout then
      jl. w3  d47.       ;   test exit cwaitanswer; ( type  9 )
      rl. w3  c0.        ;
z.                       ;
      jl      (x3+f15)   ;   end;
                         ; end;
i0:   0                  ; saved return
i1:   0                  ; saved timer
i2:   0                  ; saved answer area addr
e.
\f

;  tas 1.0 14.05.87        cregretmessage             cltxt     ...46...


; procedure 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:        return            current_coroutine
  
b.j5, i5 w.
e19:  rs. w3  i0.        ; begin
c.a88<1                  ; if testoutput
      rl  w0  x3+f13     ;
      sz  w0  1<0        ;   if CL testout then
      jl. w3  d48.       ;   test cregretmessage; ( type 10 )
z.                       ;
      jd      1<11+82    ;   regretmessage(buf);
      rl  w1  x2-2       ;   ref:= buf.ref;
                         ;   ext:= next(message_buffer_ext_head);
      al  w0  x1-2       ;   next(message_buffer_ext_head):= ref;
      rx. w0  c4.        ;   next(ref):= ext;
      rs  w0  x1-2       ;
      rl. w3  c0.        ;
      jl.     (i0.)      ; end;
i0:   0                  ; saved return
e.
\f

;  tas 1.0 14.05.87        signal                     cltxt     ...47...


; procedure signal(sem);
;
;                call             return
; w0:            -                destroyed
; w1:            -                destroyed
; w2:            sem              destroyed
; w3:            return           current coroutine

b.j5, i5 w.
e20:  rs. w3  i0.        ; begin
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<0        ;   if CL testout then
      jl. w3  d49.       ;   test signal; ( type 11 )
z.                       ;
      rl  w1  x2+4       ;   with sem do
      al  w3  x1+1       ;   begin
      rs  w3  x2+4       ;      count:= count + 1;
      sl  w1  0          ;      if count <= 0 then
      jl.     j1.        ;      begin
      rl  w2  x2         ;        corout:= next(sem);
      al  w0  0          ;
      rs  w0  x2+f28-f4  ;        wait_sem_addr:=0;
      jl. w3  d0.        ;        remove(corout); /* ud af sem kæden */
      al  w2  x2-f4+f6   ;
      jl. w3  d0.        ;        remove(corout); /* ud af mbx kæden */
      al  w2  x2-f6      ;
      rl  w0  x2+f1      ;        priority:= corout.prio;
      al  w1  1          ;        result:= ok;
      jl. w3  e10.       ;        start(corout,priority,result);
j1:   rl. w3  c0.        ;     end;
      jl.     (i0.)      ;   end;
                         ; end;
i0:   0                  ; saved return
e.
\f

;  tas 1.0 14.05.87        wait_semaphore             cltxt     ...48...


; procedure wait_semaphor(sem);
;             
;               call               return
; w0:           -                  destroyed
; w1:           -                  destroyed
; w2:           sem                destroyed
; w3:           return             current coroutine
  
b.j5, i5 w.
e22:  rs. w3  i0.        ; begin
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<0        ;   if CL testout then
      jl. w3  d50.       ;   test wait_semaphore; ( type 12 )
z.                       ;
      rl  w1  x2+4       ;   with sem do
      al  w1  x1-1       ;   begin
      rs  w1  x2+4       ;     count:= count-1;
      rl. w3  c0.        ;
      sl  w1  0          ;     if count < 0 then
      jl.     (i0.)      ;     begin
      rl. w1  i0.        ;
      rs  w1  x3+f15     ;       current_coroutine.return:= return;
      rs  w2  x3+f28     ;       wait_sem_addr:=sem;
      al  w1  x2         ;       head:= sem.coroutine_queue_head;
      al  w2  x3+f4      ;       elem:= current_coroutine.sem_queue_elem;
      jl. w3  d1.        ;       link(head,elem); /* ind i sem kæden */
      al  w2  x2-f4+f6   ;
      rs  w2  x2         ;       /* hægt mbx kæden til sig selv */
      rs  w2  x2+2       ;
      al  w0  0          ;       timer:= 0 <* no timeout *>
      jl. w3  e11.       ;       wait(timer);
c.a88<1                  ; if testoutput
      rl  w0  x3+f13     ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d51.       ;   test wait_semaphore_exit; ( type 13 )
      rl. w3  c0.        ;
z.                       ;
      jl      (x3+f15)   ;     end;
                         ;   end with;
                         ; end;
i0:   0                  ; saved return
\f

;. tas 1.0 14.05.87        wait_semaphore             cltxt     ...49...

e.

\f

;  tas 1.0 14.05.87        g_open, g_lock             cltxt     ...50...


; procedure procedure g_open(sem,n);
;
; tæller semafor value op med n, og for hver ventende coroutine
; undersøges om værdien er blevet stor nok til at starte coroutinen
;
;       call        return
; w0:   n           undef.
; w1:               unch.
; w2:   sem         undef.
; w3:   return      curco

b. i5,j5  w.

e23:  rs. w3  i0.        ;  begin  save return;
      rs. w1  i2.        ;  save w1;
c.a88<1                  ; if testoutput
      rs. w0  i1.        ;
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d73.       ;   test g_open; ( type 33 )
      rl. w0  i1.        ;
z.
      wa  w0  x2+4       ;  sem.value:=
      rs  w0  x2+4       ;    sem.value + n;
      al  w1  0          ;
      am.     (c0.)      ;
      rs  w1  f25        ;  lock_count:=0;
      sh  w0  0          ;  if sem.value>0 then
      jl.     j2.        ;  begin
      rs. w2  i3.        ;   
      al  w1  x2         ;    cda:=sem;
j1:   rl  w1  x1         ;    
      sn  w1  x2         ;    while (cda:=cda.next) <> sem do
      jl.     j2.        ;    begin
      rl  w0  x2+4       ;
      sl  w0  (x1-f4+f25);      if sem.value >= cda.lock_count then
      jl.     4          ;
      jl.     j1.        ;      begin
      ws  w0  x1-f4+f25  ;
      rs  w0  x2+4       ;        sem.value:=
      rs. w2  i1.        ;          sem.value-cda.lock_count;
      al  w2  x1         ;        remove(cda); /* ud af semaphor kæde */
\f

;. tas 1.0 14.05.87        g_open, g_lock             cltxt     ...51...

      jl. w3  d0.        ;        prio:=cda.prio;        
      al  w2  x2-f4      ;        result:=ok;            
      rl  w0  x2+f1      ;        start(cda,prio,result);
      al  w1  0          ;        cda:=sem;
      jl. w3  e10.       ;      end;
      rl. w1  i1.        ;    end;
      rl. w2  i3.        ;
      jl.     j1.        ;  end;
j2:   rl. w3  c0.        ;
      rl. w1  i2.        ;
      jl.     (i0.)      ;  end;
i0:   0                  ; saved return
i1:   0                  ; saved cda
i2:   0                  ; saved w1
i3:   0                  ; sem

e.



; procedure g_lock(sem,n);
;
; under søger om en semafors værdie er større end n, hvis det er
; tilfældet tælles den n ned og retur fra proceduren, eller sættes
; coroutinen i kø til semaforen indtil semafor værdien er talt op med
; g_open af en anden coroutine
;
;       call        return
; w0:   n           undef.
; w1:               undef.
; w2:   sem         undef.
; w3:   return      curco

b. i5,j5  w.

e24:  rs. w3  i0.        ;  begin  save return;
      rs. w0  i1.        ;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d74.       ;   test g_lock; ( type 34 )
      rl. w0  i1.        ;
z.                       ;
\f

;. tas 1.0 14.05.87        g_open, g_lock             cltxt     ...52...

      rl. w3  c0.        ;
      rs  w0  x3+f25     ;  lock_count:=n;
      ac  w0  (0)        ;  v:=sem.value - n;
      wa  w0  x2+4       ;
      sh  w0  -1         ;  if v>=0 then begin
      jl.     j1.        ;    sem.value:=v;
      rs  w0  x2+4       ;    return;
      jl.     (i0.)      ;  end;
j1:   rl. w0  i0.        ;
      rs  w0  x3+f15     ;  curco.sav_ret:=return;
      al  w1  x2         ;  head:=sem;
      al  w2  x3+f4      ;  elem:=curco.sem_queue;
      jl. w3  d1.        ;  link(head,elem);
      al  w0  0          ;  timer:=0;  /* no timeout */
      jl. w3  e11.       ;  wait(timer);
c.a88<1                  ; if testoutput
      rl  w0  x3+f13     ;
      sz  w0  1<1        ;   if CL testout then
      jl. w3  d75.       ;   test g_lock exit; ( type 35 )
      rl. w3  c0.        ;
z.                       ;
      jl      (x3+f15)   ;  end;
i0:   0                  ; saved return;
i1:   0                  ; n

e.


\f

;  tas 1.0 14.05.87        send_letter                cltxt     ...53...


; procedure send_letter(mailbox,letter);
;
; signals an letter to a mailbox. if the coroutine queue of
; the mailbox contains a coroutine which is waiting for an letter
; of this type,the coroutine is started. otherwise the letter is
; queued to the mailbox.
;
;                  call               return
; w0:              -                  destroyed
; w1:              letter             destroyed
; w2:              mailbox            destroyed
; w3:              return             current coroutine
  
b.j10, i5  w.
e30:  rs. w3  i0.        ; begin
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      sz  w0  1<0        ;   if CL testout then
      jl. w3  d52.       ;   test send_letter; ( type 14 )
z.                       ;
      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-f6+f9   ;    if logand(corout.mask,letter.type) <> 0 then
      la  w0  x1+4       ;     begin
      se  w0  0          ;       
      jl.     j3.        ;       found:= true;
      rl  w3  x3         ;
      jl.     j1.        ;
j3:   rs  w1  x3-f6+f16  ;       corout.latop:= letter;
      rl  w0  x1+4       ;       type:= letter.type;
      rs. w0  i1.        ;
      al  w2  x3         ;
      jl. w3  d0.        ;       remove(corout);  /* ud af mbx kæden */
      al  w1  0          ;       sem:=wait_sem_addr;
      rx  w1  x2-f6+f28  ;       wait_sem_addr:=0;
      sh  w1  0          ;       if sem>0 then 
      jl.     j2.        ;         /* coroutine venter på semaphor */
      rl  w0  x1+f32     ;         sem.value:=sem.value+1;
      ba. w0  1          ;
      rs  w0  x1+f32     ;
j2:   al  w2  x2-f6+f4   ;
\f

;. tas 1.0 14.05.87        send_letter                cltxt     ...54...

      jl. w3  d0.        ;       remove(corout);  /* ud af sem kæden */
      al  w2  x2-f4      ;
      rl. w1  i1.        ;       result:= type;
      rl  w0  x2+f1      ;       priority:= corout.prio;
      jl. w3  e10.       ;       start(corout,priority,result);
      jl.     j5.        ;     end
                         ;     else corout:= next(corout);
j4:   rx  w2  2          ;   if -,found
      al  w1  x1+4       ;      then link(sem.letter_queue,letter);
      jl. w3  d1.        ;
j5:   rl. w3  c0.        ;
      jl.     (i0.)      ; end;
i0:   0
i1:   0
e.  
\f

;  tas 1.0 14.05.87        inspect_mailbox            cltxt     ...55...

; procedure inspect_mailbox(mailbox,mask,letter,result);
;
; checks if 'mailbox_letter_queue' contains an letter which matches 'mask'.
; if no matching letter is found,  'letter' returns = 0,
; otherwise 'letter' refers to the first matching letter.
; '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               letter or 0
; w2:             mailbox            mailbox
; w3:             return             current coroutine
  
b.j10, i5 w.
e31:  rs. w3  i0.        ; begin
      rs. w2  i1.        ;   save mailbox;
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w0  f13        ;
      so  w0  1<1        ;   if CL testout then
      jl.     6
      am      -1000      ;
      jl. w3  d53.+1000  ;   test inspect_mailbox; ( type 15 )
z.                       ;
      al  w0  x1         ;
      rl  w1  x2+4       ;   head:= sem.letter_queue_head;
j1:                      ;   letter:= next(head); found:= false;
      sn  w1  x2+4       ;   while letter <> head and -,found do
      jl.     j3.        ;     if logand(letter.type,mask) <> 0
      rl  w3  x1+4       ;        then found:= true
      la  w3  0          ;        else letter:= next(letter);
      se  w3  0          ;
      jl.     j4.        ;
      rl  w1  x1         ;
      jl.     j1.        ;
j3:   al  w1  0          ;   if -,found then letter:= 0;
j4:   rl. w3  c0.        ;
      rl  w0  x3+f1      ;   priority:= current_coroutine.prio;
      rl. w2  c1.        ;   corout:= first in active queue;
      sh  w0  (x2+f1)    ;
      am      -1         ;
      al  w0  1          ;   result:= corout.prio > priority;
      rl. w2  i1.        ;
\f

;. tas 1.0 14.05.87        inspect_mailbox            cltxt     ...56...

      jl.     (i0.)      ; end;
i0:   0                  ; saved return
i1:   0                  ; saved mailbox
e. 

\f

;  tas 1.0 14.05.87        wait_letter                cltxt     ...57...



; procedure wait_letter(mailbox,mask,timer,letter)
;
; if 'mailbox.letter_queue' contains an letter
; which matches 'mask', the letter 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 letter is found
; pending events are scheduled and the calling coroutine waits for max. 'timer'
; seconds for an letter to arrive.
; 
; if the letter contains a message or an answer ('letter.type' = 1<0 or 1<1 ,
; resp ) , the buffer contents is copied to the common message-answer area in
; central logic, a buffer containing an answer is removed from the event
; queue by 'waitanswer'.
; 
;
;                  call                return
; w0:              timer               result ( 0(timeout) or letter.type)
; w1:              mask                letter (undefined if result = timeout)
; w2:              mailbox             destr.
; w3:              return              current_coroutine
  
b.j10, i5 w.
e32:  rs. w3  i0.        ; begin
      rx. w1  i0.        ;
      rl. w3  c0.        ;
      rs  w1  x3+f15     ;   current_coroutine.return:= return;
      rx. w1  i0.        ;   current_coroutine.waitch_mask:= mask;
      ds  w1  x3+f9      ;   current_coroutine.timer:= timer;
c.a88<1                  ; if testoutput
      rl  w0  x3+f13     ;
      so  w0  1<0        ;   if CL testout then
      jl.     6          ;
      am      -1000      ;
      jl. w3  d54.+1000  ;   test wait_letter; ( type 16 )
z.                       ;
      jl. w3  e31.       ;   inspect_mailbox(mailbox,mask,letter,result);
      se  w1  0          ;   if letter = 0 then
      jl.     j1.        ;   begin <* wait in mailbox queue *>
      al  w1  x2         ;     head:= mailbox.coroutine_queue_head;
      al  w2  x3+f6      ;     elem:= current_coroutine.mailbox_queue_elem;
      jl. w3  d1.        ;     link(head,elem);
      al  w0  0          ;
\f

;. tas 1.0 14.05.87        wait_letter                cltxt     ...58...

      rs  w0  x2+f28-f6  ;     sem_wait_addr:=0;
      al  w2  x2-f6+f4   ;     
      rs  w2  x2         ;     /* hægt sem kæden til sig selv */
      rs  w2  x2+2       ;
      rl  w0  x2-f4+f8   ;     timer:= current_coroutine.timer;
      jl. w3  e11.       ;     wait(timer,result);
      se  w0  0          ;     if result = timeout then
      jl.     j6.        ;     begin
      rs  w0  x3+f10     ;       current_coroutine.result:= timeout;
      al  w2  x3+f6      ;       elem:= current_coroutine.mailbox_queue_elem;
      jl. w3  d0.        ;       remove(elem);
      jl.     j6.        ;     end;
                         ;     goto exit;
                         ;   end;
j1:   rs  w1  x3+f16     ;   current_coroutine.latop:= letter;
      rl  w2  x1+4       ;
      rs  w2  x3+f10     ;   current_coroutine.result:= letter.type;
      al  w2  x1         ;
      jl. w3  d0.        ;   remove(letter);
      rl. w3  c0.        ;   if waiting <* coroutines of higher 
      sn  w0  0          ;      priority in active queue *> then
      jl.     j2.        ;   begin
      rl  w0  x3+f1      ;     priority:= current_coroutine.prio;
      jl. w3  e12.       ;     pass(priority);
                         ;   end;
j2:   rl  w0  x3+f10     ;
j6:   rl. w3  c0.        ; exit:
c.a88<1                  ; if testoutput
      rl  w1  x3+f16     ;
      rl  w3  x3+f13     ;
      so  w3  1<0        ;   if CL testout then
      jl.     6          ;
      am      -1000      ;
      jl. w3  d55.+1000  ;   test wait_letter_exit; ( type 17 )
      rl. w3  c0.        ;
z.                       ;
      rl  w0  x3+f10     ;   result:= current_coroutine.result;
      rl  w1  x3+f16     ;   letter:= current_coroutine.latop; <* undef if timeout *>
      jl      (x3+f15)   ; end;
i0:   0                  ; saved return
e.
\f

;  tas 1.0 14.05.87        sendmessage                cltxt     ...59...


; procedure sendmessage(name,message,letter,mailbox,result);
;
; sends a massage to the process given by 'name'. when the answer arrives
; it is signalled to the mailbox. the calling coroutine must
; provide the eda which is used as a message buffer extention and a letter
; 
;          eda + 0:  open<12 + 0
;              + 2:  mailbox addr
;  letter ->   + 4:  
;              + 6:  
;              + 8:  1<1
;              +10:  buffer address
;
;            call                  return
; w0:        mailbox               destr.
; w1:        params                destr.
; w2:        eda                   buffer addres ( or 0 = claims exceeded )
; w3:        return                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.
e33:  rs. w3  i2.        ; begin
      rs. w0  i1.        ;   with letter.answer_descriptor do
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w3  f13        ;
      so  w3  1<0        ;   if CL testout then
      jl.     6          ;
      am      -1000      ;
      jl. w3  d56.+1000  ;   test sendmessage ( type 18 )
z.                       ;
      rl. w0  i0.        ;
      rs  w0  x2         ;   proc:= answer;
\f

;. tas 1.0 14.05.87        sendmessage                cltxt     ...60...

      rl. w0  i1.        ;   open:= true;
      rs  w0  x2+2       ;   answer_mailbox := mailbox;
      al  w3  x1         ;  
      al  w1  x1+10      ;   name_address:= params;
                         ;   message_address:= params+10;
      jd      1<11+16    ;   sendmessage(name_addres,message_address,eda,result);
      rl. w3  c0.        ;
      jl.     (i2.)      ; end;
  
i0:   1<12+0             ; answer_descriptor init;
i1:   0                  ; saved mailbox
i2:   0                  ; saved return
e.



; procedure wait_sem_letter(mailbox,semaphor,mask,letter);
;
; Venter på et letter med en given type, på en given mailbox, eller på at
; en semaphor skal blive åbnet. Mask angiver hvilke typer letter der
; skal ventes på. Bit 23 i maks er bruges til at angive om der skal
; ventes på  semaphor.
;
;            call                  return
; w0:        semaphor              result (1=sem, ellers letter.type)
; w1:        mask                  letter (undef hvis result=1)
; w2:        mailbox addr          undef
; w3:        return                curco

b.j5,i6 w.

e34:  sz  w1  1          ;  if mask and 1 = 0 then
      jl.     i1.        ;   wait_letter(mailbox,mask,0,letter);
      al  w0  0          ;
      jl.     e32.       ;

i1:   rs. w3  j0.        ;  save return;
      rl. w3  c0.        ;  w3:=curco;
      rs  w1  x3+f9      ;  curco.mask:=mask;
      rs  w0  x3+f11     ;  curso.w0:=sem;
      rl. w0  j0.        ;
      rs  w0  x3+f15     ;  curso.return:=return;
c.a88<1                  ; if testoutput
      rl  w0  x3+f11     ;
\f

;. tas 1.0 14.05.87        sendmessage                cltxt     ...61...

      rl  w3  x3+f13     ;
      so  w3  1<0        ;   if CL testout then
      jl.     6          ;
      am      -1000      ;
      jl. w3  d76.+1000  ;   test wait sem letter; ( type 36 )
z.                       ;
      jl. w3  e31.       ;  inspect_mailbox(mailbox,mask,letter,result);
      se  w1  0          ;  if letter=0 then
      jl.     i3.        ;  begin  /* ingen letter på mailbox */
      rs. w2  j1.        ;
      rl  w1  x3+f11     ;
      rl  w2  x1+f32     ;    sem.value:=sem.value-1;
      al  w2  x2-1       ;
      rs  w2  x1+f32     ;    if sem.value>=0 then
      sl  w2  0          ;      goto exit;
      jl.     i5.        ;    /* hægt curco til semaphor */
      rs  w1  x3+f28     ;    sem_wait_addr:=sem;
      al  w2  x3+f4      ;    elem:=curco.sem_queue;
      jl. w3  d1.        ;    link(sem,elem); 
      rl. w3  c0.        ;
      rl. w1  j1.        ;    /* hægt curco til mailbox */
      al  w2  x3+f6      ;    elem:=curco.mbx_queue;
      jl. w3  d1.        ;    link(mbx,elem);
      al  w0  0          ;
      am.     (c0.)      ;
      rl  w1  f11        ;
      jl. w3  e11.       ;    wait(0,result);
      se  w0  1          ;    if result=semaphor then 
      jl.     i2.        ;    begin
      al  w2  x3+f6      ;      remove(curco.mbx_queue);
      jl. w3  d0.        ;      w3:=curco;
      rl. w3  c0.        ;      goto exit;
      jl.     i5.        ;    end;
i2:   rl. w3  c0.        ;    /* result = letter.type */ goto exit1;
      jl.     i6.        ;  end;
i3:   rs  w1  x3+f16     ;  /* fundet letter med rigtig type */
      rl  w2  x1+4       ;
      rs  w2  x3+f10     ;  result:=letter;
      al  w2  x1         ;
      jl. w3  d0.        ;  remove(letter);
      rl. w3  c0.        ;  w3:=curco;
      sn  w0  0          ;  if waiting coroutine with higher
      jl.     i4.        ;     priority then
      rl  w0  x3+f1      ;    pass(curco.prio);
\f

;. tas 1.0 14.05.87        sendmessage                cltxt     ...62...

      jl. w0  e12.       ;
i4:   rl  w0  x3+f10     ;
      jl.     4          ;
i5:   al  w0  1          ; exit: result:=1;
i6:   rl  w1  x3+f16     ; exit1:
                                 
c.a88<1                  ; if testoutput
      am.     (c0.)      ;
      rl  w3  f13        ;
      so  w3  1<1        ;   if CL testout then
      jl.     6          ;
      am      -1000      ;
      jl. w3  d77.+1000  ;   test wait sem letter exit; ( type 37 )
      rl. w3  c0.        ;
z.                       ;
      jl      (x3+f15)   ;  return;


j0:   0                  ; saved w0
j1:   0                  ; saved w2
j2:   0                  ; saved return

e.







\f

;  tas 1.0 14.05.87        timer_message              cltxt     ...63...


; procedure timer_message;
; 
; sends a delay-message to 'clock'.
;
;           call             return
; w0:       -                unchanged
; w1:       -                destr.
; w2:       -                buf or 0
; w3:       return           current_coroutine
  
b.j5, i5 w.
e40:  rs. w3  i0.        ; begin
      al. w1  i1.        ;    mess:= delaymess;
      al. w2  i3.        ;    ref:= answer_descr;
      al. w3  i2.        ;    name:= <:clock:>;
      jd      1<11+16    ;    sendmessage(name,mess,ref,result);
      rl. w3  c0.        ;
      jl.     (i0.)      ; end;
i0:   0                  ; saved return
i1:   0,a3               ; timer delay message
i2:   <:clock:>,0,0,0    ;
i3:   1<12+5             ; timer message eda
e.
\f

;  tas 1.0 14.05.87        reserve_buffer             cltxt     ...64...

; procedure reserve_buffer(bytes,first,last);
;
; reserve some bytes from free core
;
;         call           return
; w0:                    unchanged
; w1:     bytes          first buffer addr.
; w2:                    last buffer addr.
; w3:     return         unchanged

b. j5  w.
e50:  sz  w1  1          ; begin
      al  w1  x1+1       ;   if odd then bytes:=bytes+1;
      ac  w1  x1         ; 
      rl. w2  c11.       ;   
      wa  w1  4          ;   top used := top used - bytes;
      rs. w1  c11.       ;   w1 := first buffer addr.
      al  w2  x2-2       ;   w2 := last buffer addr.
      sl. w1  (c10.)     ;   if top used >= first free core then
      jl      x3         ;   return;
      je      -11        ;   rcm fault;
e.                       ; end;
\f

;  tas 1.0 14.05.87        init semaphore and mailbox cltxt     ...65...

; procedure init_semaphore(sem,value);
;
; initialize an semaphore to empty
;
;         call           return
; w0:     value          unchanged
; w1:                    unchanged
; w2:     sem            unchanged
; w3:     return         unchanged

b. j5  w.
e52:  rs  w2  x2+f30     ; begin
      rs  w2  x2+f31     ;   sem.prev:=sem.next:=sem;
      rs  w0  x2+f32     ;   sem.value:=value;
      jl      x3         ;   return;
e.                       ; end;


; procedure init_mailbox(mailbox);
;
; initialize an mailbox to empty
;
;         call           return
; w0:                    destroyed
; w1:                    unchanged
; w2:     mailbox        unchanged
; w3:     return         unchanged

b.  j5  w.
e53:  rs  w2  x2+f40     ; begin mailbox.next_co := mailbox;
      rs  w2  x2+f41     ;   mailbox.prev_co := mailbox;
      al  w0  x2+f42     ;   mailbox.next_let := mailbox;
      rs  w0  x2+f42     ;   mailbox.next_le := mailbox;
      rs  w0  x2+f43     ;
      jl      x3         ;   return;
e.                       ; end;
\f

;  tas 1.0 14.05.87        create_pool                cltxt     ...66...


; procedure create_pool(elements,bufsize,pool);
;
; reserve memory for a pool, and initialize the pool
;
;
;         call           return
; w0:     elements       destroyed
; w1:     bufsize        destroyed
; w2:                    pool     
; w3:     return         destroyed

b.  j5, i5  w.
e54:  ds. w0  i0.        ; begin  save return, elements;
      rs. w1  i2.        ;   save bufsize;
      wm. w1  i0.        ;   size:=bufsize*elements;
      al  w1  x1+f54     ;   size:=size+pool head size;
      sn  w0  0          ;   if size>2**23 then
      sh  w1  0          ;   rcm fault;
      je      -20        ;
      jl. w3  e50.       ;   reserve_buffer(size,first,last);
      rs. w1  i3.        ;   pool:=first;
      rs  w1  x1+f50     ;   pool.next:=pool;
      rs  w1  x1+f51     ;   pool.prev:=pool;
      rl. w0  i0.        ;   pool.elem:=elements;
      rs  w0  x1+f52     ;
      al  w3  x1+f54     ;   first:=first+pool head size;
      rs  w3  x1+f53     ;   pool.first_free:=first;
      al  w1  x3         ;
j0:   wa. w3  i2.        ; rep: next:=first+bufsize;
      sl  w3  x2         ;   if next <= last then
      jl.     j1.        ;   begin
      rs  w3  x1         ;     elem(next):=next;
      al  w1  x3         ;     first:=next;
      jl.     j0.        ;     goto rep;
j1:   al  w0  0          ;   end;
      rs  w0  x1         ;   elem(next):=0;
      rl. w2  i3.        ;
      jl.     (i1.)      ;   return;
                         ; end;
i1:   0       ; saved return
i0:   0       ; elements
i2:   0       ; bufsize
i3:   0       ; pool
\f

;. tas 1.0 14.05.87        create_pool                cltxt     ...67...

e.



; procedure get_buffer(pool,buff_addr);
;
; henter en buffer fra en pool, hvis der er tom returneres 0
;
;         call           return
; w0:                    undef
; w1:                    buffer addr eller 0
; w2:     pool           unch.
; w3:     return         curco

b.  j5, i5  w.

e55:  rs. w3  j0.        ;  save return;
      rl  w3  x2+f52     ;  w3:=pool.sem.value;
      al  w1  0          ;  buf addr := 0;
      sh  w3  0          ;  if w3 > 0 then
      jl.     i1.        ;  begin
      al  w3  x3-1       ;    pool.sem.value:=w3-1;
      rs  w3  x2+f52     ;
      rl  w1  x2+f53     ;    buf_addr:=pool.first_free;
      rl  w0  x1         ;    pool.first_free:=
      rs  w0  x2+f53     ;      word(buf_addr);
i1:                      ;  end;
c.a88<1                  ; if testoutput
      am      -1000      ;
      am.     (c0.+1000) ;
      rl  w0  f13        ;
      so  w0  1<1        ;   if CL testout then
      jl.     6          ;
      am      -1000      ;
      jl. w3  d78.+1000  ;   test get_buffer; ( type 38 )
z.                       ;
      am       -1000     ;
      rl. w3  c0.+1000   ;      
      jl.     (j0.)      ;  w3:=curco; return;

j0:   0                  ; saved return;

e.

\f

;. tas 1.0 14.05.87        create_pool                cltxt     ...68...



\f

;  tas 1.0 14.05.87        wait_buffer                cltxt     ...69...

; procedure wait_buffer(pool,buffer);
;
; get the address of a free buffer in a pool
;
;
;         call           return
; w0:                    destroyed
; w1:                    buffer addr
; w2:     pool           unch.
; w3:     return         current coroutine

b. j5  w.
e56:
      am      -1000      ;
      rl. w1  c0.+1000   ; begin
      ds  w3  x1+f18     ;   save pool, return;
c.a88<1                  ; if testoutput
      am      -1000      ;
      am.     (c0.+1000) ;
      rl  w0  f13        ;
      so  w0  1<1        ;   if CL testout then
      jl.     6          ;
      am      -1000
      jl. w3  d57.+1000  ;   test wait_buffer; ( type 19 )
z.                       ;
      jl. w3  e22.       ;   wait_semaphore(pool);
      rl  w2  x3+f17     ;   ref:=pool.first_free;
      rl  w1  x2+f53     ;   pool.first_free:=next(ref);
      rl  w0  x1         ;
      rs  w0  x2+f53     ;   
c.a88<1                  ; if testoutput
      rl  w0  x3+f13     ;
      so  w0  1<1        ;   if CL testout then
      jl.     6          ;
      am      -1000
      jl. w3  d58.+1000  ;   test wait_buffer_exit; ( type 20 )
z.                       ;
      jl      (x3+f18)   ; end;
e.
\f

;  tas 1.0 14.05.87        release buffer             cltxt     ...70...

; procedure release_buffer(buffer,pool);
;
; put a buffer back in a pool
;
;
;         call           return
; w0:                    destroyed
; w1:     buffer addr.   destroyed
; w2:     pool           unchanged
; w3:     return         current coroutine

b. j5, i5   w.
e57:  rs. w3  i0.        ; begin  save return;
      ds. w2  i2.        ;   save buffer,pool;
c.a88<1                  ; if testoutput
      am      -1000      ;
      am.     (c0.+1000) ;
      rl  w0  f13        ;
      so  w0  1<1        ;   if CL testout then
      jl.     6          ;
      am      -1000
      jl. w3  d59.+1000  ;   test release_buffer; ( type 21 )
z.                       ;
      jl. w3  e20.       ;   signal(pool);
      dl. w2  i2.        ;
      al  w0  x1         ;   w0:=buffer;
      rx  w0  x2+f53     ;   pool.first_free:=buffer, w0:=first;
      rs  w0  x1         ;   next(buffer):=first;
      jl.     (i0.)      ;   return;
                         ; end;
i0:   0       ; saved return;
i1:   0       ; buffer addr.
i2:   0       ; pool
e.

; coroutine beskrivelse til receive message coroutine

u9:       0,a20,-1,p36,1,0,r.27
          1<12+4, 0,r.4, 1<3, 0, 1<12+2,
          0,r.4, 1<2, 0, 0, 0, 1<12,
          h. 0,r.(:q38-94:) w.



\f

;. tas 1.0 14.05.87        release buffer             cltxt     ...71...


e.                       ; end CL

 
▶EOF◀