|
|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 97536 (0x17d00)
Types: TextFile
Names: »cltxt «
└─⟦9ccaf6601⟧ Bits:30008165 Bånd med SW8000 kildetekst/release værktøjer
└─⟦40b1eb8cd⟧
└─⟦this⟧ »cltxt «
\f
; tas 1.0 14.05.87 cltxt ...1...
; @(#)cltxt 1.6 (RC International) 9/17/90
;
;********************************************************************
;*********************** Exception rutine ***************************
;*********************** Testoutput rutiner *************************
;*********************** Central logic ******************************
;********************************************************************
m.central logic cltxt 1.6
;
; 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
;
; 89.11.03 side 10: test på testoutput inactive i testout,
; kan give break 0 hvis output filen ikke findes
; da pointerne og testoutput bufferene ikke er sat op
;
; 90.03.28 side 66: testpunkt 40 i init pool, giver antal cdescr o.l.
;
; 90.03.28 side 20: testpunkt 41, alle cl variable efter start
;
; 90.03.30 side 64: reserve_buffer giver ikke break, men returnere
; med w3<0 hvis der ikke er plads
;
; side 66: create_pool returnere w3<0 hvis ikke plads til pool
;
; side 3: 1<11+26 rettet til 1<11+24
;
; 90.08.24 side 12: returværdi fra outblock rettet.
;
; 90.09.17 side 21: check_event() rettet så den ikke altil returnerer
; w2=0;
;
;;
; temp testpunkter i CL (400 -499)
; brugte
;
;;
\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+24 ; 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. ;
rl. w3 c23. ; if testout inactive then
sn w3 0 ; return;
jl. j8. ;
rl. w3 i8. ;
jl x3 ;
j8: 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: w2 buf or 0; w0, w1, w3 undefined
e2:
j3: rs. w3 i10. ; save return;
\f
;. tas 1.0 14.05.87 testoutput routines cltxt ...12...
al w2 0 ;
rs. w2 (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:
c.a88<1 ; if testoutput
al. w1 c0. ;
al. w2 c72. ;
ws w2 2 ; testout cl variable
ls w2 12 ; w0=length <12 + 41
al w2 x2+41 ;
al w0 x2 ;
al w2 x1 ; fourth:=addr c0
jl. w3 e0. ; testout
z.
d2: ; begin
al. w3 c72. ; curco:=cl cdescr;
rs. w3 c0. ;
; repeat
j0: jl. w3 d6. ; check event queue(prev_buffer);
rl. w3 c1. ; if active queue empty then
se. w3 c1. ; begin
jl. j1. ; buf := prev_buffer;
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(prev_buffer);
;
; 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: - prev_buffer
; w3: return destroyed
b. j10, i5 w.
d6: rs. w3 i0. ; begin save return;
al w2 0 ; prev_buffer := 0;
j0: rs. w2 i1. ; repeat
jd 1<11+66 ;
sh w0 -1 ; test_event(prev_buffer,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. ; prev_buffer := buf;
; until result = empty;
j5: rl. w2 i1. ;
jl. (i0.) ; end;
i0: 0 ; saved return;
i1: 0 ; prev_buffer
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<1 ; 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<1 ; 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<1 ; 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<1 ; 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<1 ; 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<1 ; 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<1 ; 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<1 ; 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 ;
so w0 1<1 ; if CL testout then
jl. 6 ;
am -1000 ;
jl. w3 d74.+1000 ; 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 ;
so w0 1<1 ; if CL testout then
jl. 6 ;
am -1000 ;
jl. w3 d75.+1000 ; 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 ;
so w0 1<1 ; if CL testout then
jl. 6 ;
am -1000 ;
jl. w3 d52.+1000 ; 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<1 ; 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<1 ; 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<1 ; 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<1 ; 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 bytes left
b. j5 w.
e50: rs. w3 j1. ; save return;
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.
rl. w3 c11. ;
ws. w3 c10. ; w3=top_used - first_free;
jl. (j1.) ; return;
j1: 0
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 bytes left
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);
sh w3 -1 ; ikke mer plads retur
jl. (i1.) ;
rs. w3 i4. ; bytes_left=w3;
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;
dl. w1 i2. ;
rl. w2 i3. ;
rl. w3 i4. ;
ks -40
jl. (i1.) ; return;
; end;
i1: 0 ; saved return
i0: 0 ; elements
i2: 0 ; bufsize
i3: 0 ; pool
i4: 0 ; bytes left
\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◀