|
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: 92928 (0x16b00) Types: TextFile Names: »kkrcmonret«
└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ. Detaljer om "HC8000" projekt. └─⟦0364f57e3⟧ └─⟦87223b8a0⟧ »kkrcmonfil« └─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ. └─⟦b2ec5d50f⟧ └─⟦87223b8a0⟧ »kkrcmonfil« └─⟦this⟧
( message monchange release 6.2 to 7.0 clear temp mondef moncentral monprocs mondisc monfpaline monhost monfpasub, montabinit monprocfnc1 monprocfnc2 mons1 mons2 moncatinit, mdef mcentral mprocs mdisc mfpaline mhost mfpasub, mtabinit mprocfnc1 mprocfnc2 ms1 ms2 mcatinit contract entry.kkrcmonfil mondef moncentral monprocs mondisc monfpaline, monhost monfpasub montabinit monprocfnc1 monprocfnc2 mons1 mons2 moncatinit skip 36.1 c=copy mess.no 1 mdef=edit mondef skip 36.1 c=copy mess.no 1 mcentral=edit moncentral skip 36.1 c=copy mess.no 1 mprocs=edit monprocs skip 36.1 c=copy mess.no 1 mdisc=entry mondisc skip 36.1 c=copy mess.no 1 mfpaline=entry monfpaline skip 36.1 c=copy mess.no 1 mhost=edit monhost skip 36.1 c=copy mess.no 1 mfpasub=edit monfpasub skip 36.1 c=copy mess.no 1 mtabinit=entry montabinit skip 36.1 c=copy mess.no 1 mprocfnc1=entry monprocfnc1 skip 36.1 c=copy mess.no 1 mprocfnc2=edit monprocfnc2 skip 36.1 c=copy mess.no 1 ms1=edit mons1 skip 36.1 c=copy mess.no 1 ms2=edit mons2 skip 36.1 c=copy mess.no 1 mcatinit=edit moncatinit head cpu end) $def ;******************** l./b.a450/,d,i/ b.a800,b200 w. /, l./a135/,r/=6/=7/ l./a136/, r/=2/=0/ l./i0=/,r/81 03 01/81 08 01/ l./a199=2/,l1,i/ a400=0 ; coroutine monitor inclusion (default no) ; **** definition of coroutine monitor formats: ; ; coroutine description; a694 = -6 ; next in semaphore queue a696 = -4 ; previous in semaphore queue a698 = -2 ; priority a700 = 0 ; save ic (return) a702 = 2 ; next coroutine a704 = 4 ; prev coroutine a706 = 6 ; timer a708 = 8 ; mask f. waitchained a710 = 10 ; save w0(for test purposes only) or result a712 = 12 ; save w1 a714 = 14 ; save w2 a716 = 16 ; testmask a718 = 18 ; ident a720 = 20 ; user exit (0 or exit addr) a722 = 22 ; return address for waitsem,waitchained,cwaitanswer a724 = 24 ; ref. to operation (waitchained) or buf (cwaitanswer) ; operation: a670 = +0 ; next operation a672 = +2 ; prev operation a674 = +4 ; type ; chained semaphore: a650 = +0 ; next coroutine a652 = +2 ; prev coroutine a654 = +4 ; next operation a656 = +6 ; prev operation ; simple semaphore: a660 = +0 ; next coroutine a662 = +2 ; prev coroutine a664 = +4 ; count ; second process extension. ; contains key variables of the coroutine system . a538 = -12 ; start of testbuffer a540 = -10 ; start of next record in test buffer a542 = -8 ; top of test buffer a544 = -6 ; test output flag (1 = on) a546 = -4 ; next in active queue a548 = -2 ; prev in active queue a550 = 0 ; current coroutine a552 = 2 ; next in timer queue a554 = 4 ; prev in timer queue a556 = 6 ; name of the testoutput process a566 = 16 ; start of testoutput message a582 = 32 ; last event pointer a584 = 34 ; message decriptor pointer(cur) a586 = 36 ; start of table containing references to user defined procedures a588 = 38 ; first message buffer extension a590 = 40 ; start of common message-answer area a616 = 56 ; name of 'clock' a626 = 66 ; start of 'clock'-message a630 = 70 ; answer descriptor for answer from 'clock' /, l./a303=j0/,d,i/ a303= j0 ; top of save area a305= j0, j0 = j0+2 ; first process extension a306= j0, j0 = j0+2 ; second process extension /, l./format of device/,i/ a60 = 16 ; <mess descr> /,f $central ;******************** l./i0=/,r/81 01 12/81 04 06/ l./c103/,r/103/200/, l./b26=b5/,i/ c.a400-1 b27: 0 ;124: first process extension(cur) b28: 0 ;126: second process extension(cur) b141:0 ;128: coroutine testoutput address ; links to cmon procedures: b140:c100 ;130: address of cmon procedure start c101 ;132: - '' - wait c102 ;134: - '' - pass c103 ;136: - '' - inspect c104 ;138: - '' - csendmessage c105 ;140: - '' - cwaitanswer c106 ;142: - '' - answer_arrived c107 ;144: - '' - signal_binary c108 ;146: - '' - signal_sem c109 ;148: - '' - wait_sem c110 ;150: - '' - signal_chained c111 ;152: - '' - inspect_chained c112 ;154: - '' - wait_chained c113 ;156: - '' - sem_send_mess c114 ;158: - '' - sem_answer_proc c115 ;160: - '' - message_received c116 ;162: - '' - timer_message c117 ;164: - '' - timer_scan c118 ;166: - '' - cregretmessage c119 ;168: - '' - user testoutput z. /, l./c99:/,l./ds w1 x3+a325/, l./;if the new current/,i/ c.a400-1 ; insert process extension addresses in monitor table dl w1 x2+a306 ; wa w0 x2+a182 ; wa w1 x2+a182 ; ds w1 b28 ; z. /, ;<* insert date of options and room for machine id.*> l./b128=/, r/>1/>1-6/, l1 , i/ a130 ; date of options a131 ; time of options 0, r.4 ; room for machine id. /, f $procs ;******************** l./i0=/, r/81 01 12/81 04 09/ l./e57/,l1,r/c29/e58/, r/ not used/set process extensions/, l./d16:/,l./i14:/,l./jl (i3)/,d,i/ jl. (i3.) ; return; /, l./e19:/, l./ds w3 b15+2/, i/ aa w3 b15+2 ; clockchange+ /, l.';procedure start i/o',i/ ; procedure set process extension(first ext,last ext) ; ; save w0: result (return) ; save w1: first process ext (call) ; save w2: second process ext (call) ; save w3: - e58: c.a400-1 rl w2 x1+a29 ; first:= save w1(cur) rl w0 x1+a30 ; last:= save w2(cur) sl w2 (0) ; if last < first then rx w2 0 ; exchange(first,last) jl w3 d112 ; check within(first,last) rl w3 x1+a30 ; w3:= sec. proc. ext. rl w2 x1+a29 ; w2:= first proc. ext. ds w3 x1+a306 ; insert log. addr in process description wa w2 x1+a182 ; wa w3 x1+a182 ; ds w3 b28 ; insert phys. addr in monitor table jl r0 ; goto result 0; z. c.a400 jl c29 ; z. /, l./e.;end of start i/,l1,i# c.a400-1 \f m. coroutine monitor ;************************** c o r o u t i n e m o n i t o r ************************* ; locations in process extension 1 are used by cmonprocedures as described below: ; ; -2: signalch ; b27 +0: start ; +2: check_eventqueue ; +4: check_eventqueue ; +6: ; +8: generate_testoutput ; +10: inspect_chained ; +12: inspect_chained ; +14: timermess ; +16: timerscan ; +18: timerscan ; +20: generate_testoutput ; +22: " - " ; +24: " - " \f b.h50 w. ; procedure remove(elem); ; ; removes a given element from its queue and leaves the element ; linked to itself. ; ; call return ; w0: - unchanged ; w1: - next(elem) ; w2: elem elem ; w3: link link h0: rl w1 x2 ; begin rx w2 x2+2 ; prev(elem):= elem; rs w1 x2 ; next(prev(elem)):= next(elem); rx w2 x1+2 ; prev(next(elem)):= old prev(elem); rs w2 x2 ; next(elem):= elem; jl x3 ; end; ; procedure link(head,elem); ; ; links the element to the end of the queue; ; ; call return ; w0 - destroyed ; w1 head head ; w2 elem elem ; w3 link old last(head) h1: al w0 x3 ; begin rl w3 x1+2 ; old prev:= last(head); rs w2 x1+2 ; prev(head):= elem; rs w2 x3+0 ; next(old prev):= elem; rs w1 x2+0 ; next(elem):= head; rs w3 x2+2 ; prev(elem):= old prev; rl w3 0 ; jl x3 ; end; \f ; procedure get_mess_ext(ref); ; ; returns a reference to the first free message buffer extension ; or 0 if no extensions are available. the extension is removed from the chain. ; ; call return ; w0: - destroyed ; w1: - destroyed ; w2: - ref or 0 ; w3: link link b.j5 w. h7: rl w1 b28 ; begin rl w2 x1+a588 ; ref:= cur.ext2.buffer_extension_head; sn w2 0 ; if ref <> 0 then jl. j0. ; begin rl w0 x2 ; cur.ext2.buffer_extension_head:= next(ref); rs w0 x1+a588 ; al w2 x2+2 ; ref:= ref+2; ; end; j0: jl x3 ; end; e. \f ; procedure answer arrived(buf,ref); ; ; is called from procedure 'check_event_queue' when an answer appears in ; the event queue and 'ref.open' is true, i. e. when a coroutine has ; called 'cwaitanswer(buf)'. the coroutine is activated and the answer ; descriptor is closed. ; ; call return ; w0: - destroyed ; w1: ref destroyed ; w2: buf buf ; w3: link link b.j5 w. c106: am (b27) ; begin ds w3 +6 ; ext1(4,6):= (buf,link); am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate testoutput(1<6); jl. w3 h4. ; 3<22+1<6 ; j0: al w0 0 ; hs w0 x1 ; ref.open:= false; rl w2 x1+2 ; corout:= ref.param1; al w1 1 ; result:= ok; rl w0 x2+a698 ; priority:= corout.priority; jl. w3 c100. ; start(corout,priority,ok); am (b27) ; dl w3 +6 ; (buf,link):= ext1(4,6); jl x3 ; end; e. \f ; procedure central wait; ; ; central waiting point in coroutine system. checks the eventqueue ; and schedules pending events. if the active queue is empty the ; monitor procedure wait event is called otherwise the first co- ; routine is started. if 'corout.user_exit' <> 0 a jump to 'user_exit' is ; made with register contents: ; w0: - ; w1: - ; w2: current_coroutine ; w3: link b.j5 w. h2: ; begin ; repeat j0: jl. w3 h6. ; check event queue; rl w2 b28 ; if active queue empty then rl w3 x2+a546 ; begin se w3 x2+a546 ; buf:= cur.ext2.last event; jl. j1. ; wait event(buf,result); rl w2 x2+a582 ; jd 1<11+24 ; jl. j0. ; ; end; j1: al w2 x3-2 ; until active queue not empty; rs w2 (b28) ; corout:= first in active queue; rl w1 x2+a720 ; if corout.user_exit <> 0 se w1 0 ; then jump to user_exit; jl w3 x1 ; rl w3 (b28) ; dl w1 x3+a712 ; rl w2 x3+a714 ; restart corout;; jl (x3) ; end; e. \f ; procedure check eventqueue; ; ; inspects the eventqueue starting at 'last event'('last event' = 0 ; if the queue must be inspected from the start). pending events ; which have arrived after 'last event' are scheduled if ; 'event descriptor.open' = true. the scheduling is performed by calling ; either a 'cmon'-standard procedure (even procedure number in event ; descriptor) or a user defined procedure (odd procedure number which ; is used as index in the procedure table in process extension 2). ; ; a procedure ('user' or 'cmon') which is used for scheduling answers or messages ; must return with w2=0 if the answer/message is removed from the event queue ; - otherwise with w2='buf' ; i. e. the event queue must be inspected from the ; start when an event is removed by a scheduling procedure. ; exit to 'cmon'- or user-procedure with: ; w0: - ; w1: ref(event descriptor) ; w2: buf ; w3: link b. j10 w. h6: am (b27) ; begin rs w3 +2 ; ext1(2):= link; rl w3 b28 ; rl w2 x3+a582 ; last_buf:= cur.ext2.last_event; j0: jd 1<11+66 ; repeat rl w3 b28 ; sh w0 -1 ; test_event(last_buf,buf,result); jl. j5. ; if result <> empty then se w0 0 ; begin jl. j2. ; if result = message rl w1 x2+4 ; ac w1 x1 ; se w1 (b1) ; then ref:= jl. j1. ; if buf.receiver = cur then cur.ext2.messdescr rl w1 x3+a584 ; else buf.receiver.messdescr <* pseudoprocess *> jl. j2. ; j1: rl w1 x1+a60 ; else <* answer *> ref:= buf.ref; j2: hl w0 x1 ; sn w0 0 ; jl. j0. ; if ref.open then hl w0 x1+1 ; begin sz w0 1 ; if even procedure number jl. j3. ; then call cmonproc(buf,ref); am (0) ; jl w3 (130) ; jl. j0. ; else j3: ; begin <* odd procedure number *> rl w3 x3+a586 ; <* use procedure number in event *> hl w0 x1+1 ; <* descriptor as index in proce- *> ls w0 +1 ; <* dure table in cur.ext2 *> wa w0 x3 ; am (0) ; jl w3 (0) ; call userproc(buf,ref); jl. j0. ; end; ; end; ; end; ; until result = empty; j5: sn w2 0 ; <* if 'last_buf' points at a message , 'last_event' jl. j6. ; <* must be reset as the message may be regretted rl w0 x2+4 ; <* before next scan. se w0 0 ; sz w0 -8 ; cur.ext2.last_event:= if last_buf points at message al w2 0 ; then 0 j6: rs w2 x3+a582 ; else last_buf; am (b27) ; link:= ext1(2); jl (2) ; end; e. \f ; procedure entry pass(priority); ; ; pending events are scheduled and calling coroutine is restarted ; with the priority given in call. ; ; call return ; w0: priority destroyed ; w1: - destroyed ; w2: - destroyed ; w3: link current coroutine b.j5 w. c102: am (b28) ; begin rs w3 (0) ; current_coroutine.ic:= link; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate testoutput(testkind); jl. w3 h4. ; 3<22+1<2 ; j0: rl w2 (b28) ; rl w1 x2+a710 ; result:= current_coroutine.result; jl. w3 c100. ; start(current_coroutine,priority,result); jl. h2. ; central wait; e. ; end; \f ; procedure entry inspect(priority,result); ; ; schedules pending events and checks if the active queue contains ; coroutines with priority higher than the call parameter 'priority'. in ; this case 'result' returns true (1). ; ; call return ; w0: priority result ; w1: - destroyed ; w2: - destroyed ; w3: link current coroutine b.j5 w. c103: am (b28) ; begin rs w3 (0) ; current_coroutine.ic:= link; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput is active then jl. j0. ; generate testoutput(1<3); jl. w3 h4. ; 3<22+1<3 ; j0: rs w0 (b27) ; ext1(0):= priority; jl. w3 h6. ; check_event_queue; rl w0 (b27) ; priority:= ext1(0); rl w3 b28 ; rl w3 x3+a546 ; corout:= first in active queue; sl w0 (x3-4) ; am -1 ; result:= corout.prio > priority; al w0 1 ; rl w3 (b28) ; jl (x3) ; end; e. \f ; procedure entry start(corout,priority,result); ; ; removes the coroutine from its queue (normally the timer queue) and ; inserts it in active queue according to the call parameter 'priority'. ; the call parameter 'result' is returned in w0 of ; the coroutine which is activated. ; ; call return ; w0: priority destroyed ; w1: result destroyed ; w2: corout corout ; w3: link current coroutine b.j5 w. c100: rs w3 (b27) ; begin am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput is active then jl. j0. ; generate testoutput(1<0); jl. w3 h4. ; 3<22+1<0 ; j0: rs w1 x2+a710 ; corout.result:= result; rs w0 x2+a698 ; corout.priority:= priority; al w2 x2+2 ; jl. w3 h0. ; remove(corout); rl w1 0 ; al w0 x2 ; rl w2 b28 ; worse:= rear of active queue; al w3 x2+a546 ; while worse.prio > prio and al w1 x1+1 ; worse <> active queue head do j1: rl w3 x3+2 ; worse:= prev(worse); sn w3 x2+a546 ; jl. j2. ; 'insert corout in the rear of sh w1 (x3-4) ; other coroutines of the same jl. j1. ; priority' j2: rl w1 x3 ; rl w2 0 ; jl. w3 h1. ; link(worse,corout); al w2 x2-2 ; rl w3 (b28) ; am (b27) ; jl (0) ; end; e. \f ; procedure entry wait(timer,result); ; ; calling coroutine is suspended for max 'timer' seconds. ; 'timer' = 0 indicates no timeout. the return parameter 'result' ; indicates whether the coroutine was started by timeout or by ; the arrival of an internal or external event. ; ; call return ; w0: timer result ; w1: - destroyed ; w2: - - ; w3 link current coroutine b.j5 w. c101: am (b28) ; begin rs w3 (0 ) ; current coroutine.return:= link; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active then jl. j0. ; generate testoutput(1<1); jl. w3 h4. ; 3<22+1<1 ; j0: rl w2 (b28) ; current coroutine.timer:= timer; rs w0 x2+a706 ; al w2 x2+2 ; jl. w3 h0. ; remove(current coroutine); rl w3 b28 ; al w1 x3+a552 ; jl. w3 h1. ; link(timer queue head,current coroutine); jl. h2. ; central wait; ; end; e. \f ; procedure entry csendmessage(mess,name,buf); ; ; allocates a message buffer extension and prepares it for cwaitanswer. ; then calls sendmessage. ; ; return parameter 'buf': 0 buffer claims exceeded ; 1 no free extensions ; >1 message buffer address ; ; call return ; w0: - destroyed ; w1: mess destroyed ; w2: name buffer address (or 0 or 1) ; w3: link current coroutine b.j5,i5 w. c104: am (b28) ; begin rs w3 (0) ; current_coroutine.ic:= link; am (b28) ; rl w3 +a544 ; sn w3 0 ; jl. j0. ; if testoutput active jl. w3 h4. ; then generate_testoutput(1<4); 3<22+1<4 ; j0: ds w2 (b27) ; jl. w3 h7. ; get_mess_ext(ref); sn w2 0 ; if ref <> 0 <* extension available *> then jl. j1. ; begin rl. w0 i0. ; <* initialize answer descriptor *> rs w0 x2 ; ref.open:= false; ref.proc:= 12; rl w3 b27 ; rs w2 x3+2 ; ext1(2):= ref; rl w1 x3-2 ; rl w3 x3 ; send message(mess,name,buf,ref); jd 1<11+16 ; se w2 0 ; if buffer claims exceeded jl. j2. ; then release message buffer extension; am (b27) ; rl w1 (+2) ; rl w3 b28 ; al w0 x1-2 ; rx w0 x3+a588 ; rs w0 x1-2 ; jl. j2. ; j1: al w2 1 ; end j2: rl w3 (b28) ; else buf:= 1; <* no free extensions *> jl (x3) ; end; i0: 0<12+12 ; answer descriptor init (open=false,proc='answer_arrived') e. \f ; procedure entry cwaitanswer(buf,timer,result); ; ; prepares the message buffer extension for receiving the answer. if ; the buffer has been answered, 'last_event' is reset as the buffer ; may have been skipped during an earlier inspection of the event queue. ; the coroutine waits for max. 'timer' seconds for the answer. when the ; coroutine is restarted the action depends on 'result': ; ; result = timeout : the answer descriptor is closed ; ; result = answer arrived : the answer is received in the answer ; area in process extension 2 and the message ; buffer extension is released. ; ; call return ; w0: timer result (timeout:0,wait_answer result:1,2,3,4,5) ; w1: - answer area in ext2 if result <> timeout ; w2: buf buf ; w3: link current coroutine b.j10 w. c105: rs w3 (b27) ; begin am (b28) ; rl w3 +a544 ; sn w3 0 ; jl. j0. ; if testoutput active jl. w3 h4. ; then generate_testoutput(1<5); 3<22+1<5 ; j0: rl w3 (b28) ; rl w1 (b27) ; current_coroutine.return:= link; ds w2 x3+a724 ; current_coroutine.buf:= buf; rs w0 (b27) ; ext1(0):= timer; rl w1 x2-2 ; with buf.ref do al w0 1 ; begin hs w0 x1 ; open:= true; rs w3 x1+2 ; corout:= current_coroutine; ; end; rl w0 x2+4 ; sz w0 -8 ; if buf.state = answer pending jl. j1. ; then last_event:= 0; <* inspect from start *> al w0 0 ; am (b28) ; rs w0 +a582 ; j1: rl w0 (b27) ; timer:= ext1(0); jl. w3 c101. ; wait(timer,result); rl w2 x3+a724 ; buf:= current_coroutine.buf; rl w1 x2-2 ; ref:= buf.ref; se w0 0 ; if result = timeout jl. j2. ; then ref.open:= false hs w0 x1 ; jl. j4. ; else j2: ; begin <* result = answer arrived *> rl w3 b28 ; release message buffer extension; al w0 x1-2 ; rx w0 x3+a588 ; rs w0 x1-2 ; se w2 (x3+a582) ; jl. j3. ; al w0 0 ; if buf = last_event then last_event:= 0; rs w0 x3+a582 ; j3: al w1 x3+a590 ; jd 1<11+18 ; wait answer(buf,cur.ext2.answer_area); j4: rl w3 (b28) ; end; jl (x3+a722) ; end; e. ; end; \f ; procedure entry signal binary(sem); ; procedure entry signal(sem); ; ; call return ; w0: - destroyed ; w1: - destroyed ; w2: sem destroyed ; w3: link current coroutine b.j5 w. c107: am 1 ; signal_binary: c108: al w0 0 ; signal: am (b28) ; begin rs w3 (0) ; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate_testoutput(1<7); jl. w3 h4. ; 3<22+1<7 ; j0: rl w1 x2+4 ; with sem do al w3 x1+1 ; begin se w0 0 ; count:= count+1; la w3 0 ; if binary rs w3 x2+4 ; then count:= count and 1; sl w1 0 ; if count <= 0 then jl. j1. ; begin rl w2 x2 ; corout:= next(sem); jl. w3 h0. ; remove(corout); al w2 x2+6 ; rl w0 x2+a698 ; priority:= corout.prio; al w1 1 ; result:= ok; jl. w3 c100. ; start(corout,priority,result); j1: rl w3 (b28) ; end; jl (x3) ; end; e. ; end; \f ; procedure entry wait_semaphore(sem); ; ; call return ; w0: - destroyed ; w1: - destroyed ; w2: sem destroyed ; w3: link current coroutine b.j5 w. c109: am (b28) ; begin rs w3 (0) ; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate_testoutput(1<8); jl. w3 h4. ; 3<22+1<8 ; j0: rl w1 x2+4 ; with sem do al w1 x1-1 ; begin rs w1 x2+4 ; count:= count-1; rl w3 (b28) ; sl w1 0 ; if count < 0 then jl (x3) ; begin rl w1 x3 ; rs w1 x3+a722 ; current_coroutine.return:= link; al w1 x2 ; head:= sem.coroutine_queue_head; al w2 x3-6 ; elem:= current_coroutine.sem_queue_elem; jl. w3 h1. ; link(head,elem); al w0 0 ; timer:= 0 <* no timeout *> jl. w3 c101. ; wait(timer); rl w3 (b28) ; end; jl (x3+a722) ; end with; e. ; end; \f ; procedure entry signal_chained(sem,oper); ; ; signals an operation to a chained semaphore. if the coroutine queue of ; the semaphore contains a coroutine which is waiting for an operation ; of this type,the coroutine is started. otherwise the operation is ; queued to the semaphore. ; ; two reserved types exist: ; 1<0: message ; 1<1: answer ; ; call return ; w0: - destroyed ; w1: operation destroyed ; w2: semaphore destroyed ; w3: link current coroutine b.j10 w. c110: am (b27) ; begin rs w3 -2 ; am (b28) ; rl w3 +a544 ; sn w3 0 ; jl. j0. ; if testoutput active jl. w3 h4. ; then generate_testoutput(1<9); 3<22+1<9 ; j0: rl w3 x2 ; head:= sem.coroutine_queue_head; j1: sn w3 x2 ; corout:= next(head); found:= false; jl. j4. ; while corout <> head and -, found do rl w0 x3-a694+a708; if logand(corout.mask,oper.type) <> 0 then la w0 x1+4 ; begin se w0 0 ; jl. j3. ; found:= true; rl w3 x3 ; jl. j1. ; j3: rs w1 x3-a694+a724; corout.latop:= operation; rl w0 x1+4 ; type:= oper.type; al w2 x3 ; jl. w3 h0. ; remove(corout); al w2 x2-a694 ; rl w1 0 ; result:= type; rl w0 x2+a698 ; priority:= corout.prio; jl. w3 c100. ; start(corout,priority,result); jl. j5. ; end ; else corout:= next(corout); j4: rx w2 2 ; if -,found al w1 x1+4 ; then link(sem.operation_queue,oper); jl. w3 h1. ; j5: rl w3 (b28) ; am (b27) ; jl (-2) ; end; e. \f ; procedure entry inspect_chained(sem,mask,oper,result); ; ; checks if 'sem_operation_queue' contains an operation which matches 'mask'. ; if no matching operation is found, 'oper' returns = 0, ; otherwise 'oper' refers to the first matching operation. ; 'result' returns 'true' (1) if the active queue contains coroutines of ; priorities higher than the priority of calling coroutine. ; ; call return ; w0: - (result= 0,1) ; w1: mask oper or 0 ; w2: sem sem ; w3: link current coroutine b.j10 w. c111: am (b28) ; begin rs w3 (0) ; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate_testoutput(1<10); jl. w3 h4. ; 3<22+1<10 ; j0: am (b27) ; rs w2 +12 ; save(sem); al w0 x1 ; rl w1 x2+4 ; head:= sem.operation_queue_head; j1: ; oper:= next(head); found:= false; sn w1 x2+4 ; while oper <> head and -,found do jl. j3. ; if logand(oper.type,mask) <> 0 rl w3 x1+4 ; then found:= true la w3 0 ; else oper:= next(oper); se w3 0 ; jl. j4. ; rl w1 x1 ; jl. j1. ; j3: al w1 0 ; if -,found then oper:= 0; j4: rl w3 (b28) ; rl w0 x3+a698 ; priority:= current_coroutine.prio; rl w2 b28 ; rl w2 x2+a546 ; corout:= first in active queue; sh w0 (x2-4) ; am -1 ; al w0 1 ; result:= corout.prio > priority; am (b27) ; rl w2 +12 ; jl (x3) ; end; e. \f ; procedure entry wait_chained(sem,mask,timer,oper); ; ; if 'sem.operation_queue' contains an operation ; which matches 'mask', the operation is removed from the queue . a 'pass' ; is executed if the active queue contains coroutines of priorities higher ; than the priority of calling coroutine. if no matching operation is found ; pending events are scheduled and the calling coroutine waits for max. 'timer' ; seconds for an operation to arrive. ; ; if the operation contains a message or an answer ('oper.type' = 1<0 or 1<1 , ; resp ) , the buffer contents is copied to the common message-answer area in ; process extension 2. a buffer containing an answer is removed from the event ; queue by 'waitanswer'. ; ; ; call return ; w0: timer result ( 0(timeout) or oper.type) ; w1: mask oper (undefined if result = timeout) ; w2: sem destr. ; w3: link current_coroutine b.j10 w. c112: rs w3 (b27) ; begin am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate_testoutput(1<11); jl. w3 h4. ; 3<22+1<11 ; j0: rx w1 (b27) ; rl w3 (b28) ; rs w1 x3+a722 ; current_coroutine.return:= link; rx w1 (b27) ; current_coroutine.waitch_mask:= mask; ds w1 x3+a708 ; current_coroutine.timer:= timer; jl. w3 c111. ; inspect_chained(sem,mask,oper,result); se w1 0 ; if oper = 0 then jl. j1. ; begin <* wait in semaphore queue *> al w1 x2 ; head:= sem.coroutine_queue_head; al w2 x3+a694 ; elem:= current_coroutine.sem_queue_elem; jl. w3 h1. ; link(head,elem); rl w0 x2-a694+a706 ; timer:= current_coroutine.timer; jl. w3 c101. ; wait(timer,result); se w0 0 ; if result = timeout then jl. j3. ; begin rs w0 x3+a710 ; current_coroutine.result:= timeout; al w2 x3+a694 ; elem:= current_coroutine.sem_queue_elem; jl. w3 h0. ; remove(elem); jl. j6. ; goto exit; ; end; ; end; j1: rs w1 x3+a724 ; current_coroutine.latop:= oper; rl w2 x1+4 ; rs w2 x3+a710 ; current_coroutine.result:= oper.type; al w2 x1 ; jl. w3 h0. ; remove(oper); rl w3 (b28) ; if waiting <* coroutines of higher sn w0 0 ; priority in active queue *> then jl. j2. ; begin rl w0 x3+a698 ; priority:= current_coroutine.prio; jl. w3 c102. ; pass(priority); ; end; j2: rl w0 x3+a710 ; j3: sz w0 -4 ; if oper.type = message or answer then jl. j6. ; begin rl w2 x3+a724 ; oper:= current_coroutine.latop; rl w3 b28 ; rl w2 x2+8 ; buf:= oper.buf; se w0 1<1 ; if oper.type = answer then jl. j5. ; begin se w2 (x3+a582) ; jl. j4. ; if buf = last_event al w0 0 ; then last_event:= 0; rs w0 x3+a582 ; j4: al w1 x3+a590 ; area:= common message-answer area; jd 1<11+18 ; waitanswer(buf,area); jl. j6. ; end j5: al w1 x3+a590 ; else dl w0 x2+10 ; begin <* message *> ds w0 x1+2 ; dl w0 x2+14 ; ds w0 x1+6 ; dl w0 x2+18 ; <* copy to common massage-answer area *> ds w0 x1+10 ; dl w0 x2+22 ; ds w0 x1+14 ; end; ; end; j6: rl w3 (b28) ; exit: rl w0 x3+a710 ; result:= current_coroutine.result; rl w1 x3+a724 ; oper:= current_coroutine.latop; <* undef if timeout *> jl (x3+a722) ; e. ; end; \f ; procedure entry sem_sendmessage(name,message,oper,sem.result); ; ; sends a massage to the process given by 'name'. when the answer arrives ; it is signalled to the chained semaphore 'sem'. the calling coroutine must ; provide the operation 'oper' which is used as: ; ; 1) message_buffer_extension and 2) answer_operation(sem_answer_proc) ; -6 (next operation) oper +0 next operation ; -4 (prev operation) +2 prev operation ; -2 (type) +4 type=answer(1<1) ; ext. +0 open,'sem_answer_proc' +6 - ; +2 answer_sem +8 buffer address ; ; ; call return ; w0: sem destr. ; w1: params destr. ; w2: oper buffer addres ( or 0 = claims exceeded ) ; w3: link current coroutine ; ; 'params' points at a parameter area containing: ; ; params +0: name(1) ; +2: name(2) ; +4: name(3) ; +6: name(4) ; +8: name table address ; +10: mess(1) ; +12: mess(2) ; etc. b.j5,i5 w. c113: am (b28) ; begin rs w3 (0) ; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate_testoutput(1<12); jl. w3 h4. ; 3<22+1<12 ; j0: rs w0 (b27) ; with oper.answer_descriptor do rl. w0 i0. ; begin rs w0 x2+6 ; proc:= sem_answerproc; rl w0 (b27) ; open:= true; rs w0 x2+8 ; answer_sem:= sem; al w3 x1 ; end; al w1 x1+10 ; name_address:= params; ; message_address:= params+10; al w2 x2+6 ; ref:= oper.answer_descriptor; jd 1<11+16 ; sendmessage(name_addres,message_address,ref,result); rl w3 (b28) ; jl (x3) ; end; i0: 1<12+28 ; answer_descriptor init; e. \f ; procedure sem_answer_proc(ref,buf); ; ; this procedure is called from procedure 'check_event_queue' when an ; answer to a message, sent by 'sem_sendmessage, has arrived. 'ref' ; contains the address of the answer_descriptor and 'buf' contains the ; message buffer address. the answer is signalled to the chained semaphore ; given in answer_descriptor. ; ; call return ; w0: - destr. ; w1: ref destr. ; w2: buf buf ; w3: link link b.j5 w. c114: am (b27) ; begin ds w3 +6 ; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate_testoutput(1<13); jl. w3 h4. ; 3<22+1<13 ; j0: al w0 0 ; with ref do hs w0 x1 ; begin al w0 1<1 ; open:= false; rs w0 x1-2 ; type:= answer; rx w2 x1+2 ; sem:= answer_sem; al w1 x1-6 ; buffer:= buf; jl. w3 c110. ; signal_chained(sem,operation); am (b27) ; end; dl w3 +6 ; jl x3 ; end; e. \f ; procedure message_received(buf,ref); ; ; this procedure is called from 'check_event_queue' when a message is ; received and mess_descr.proc = 'message_received'. the message descriptor ; must contain an operation and the address of a chained semaphore. ; ; message_descriptor message_operation ; -6: next operation - ; -4: prev operation - ; -2: type type = message (1<0) ; mess_descr +0: open,'message_received' - ; +2: semaphore address buffer address ; ; ; call return ; w0: - destr. ; w1: ref destr. ; w2: buf 0 (the message buffer is removed) ; w3: link link b.j5 w. c115: am (b27) ; begin rs w3 +6 ; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate_testoutput(1<14); jl. w3 h4. ; 3<22+1<14 ; j0: jd 1<11+26 ; getevent(buf); al w0 0 ; with ref do hs w0 x1 ; begin al w0 1<0 ; open:= false; <* the message class must be ; explicitly opened by a ; receiving coroutine *> rs w0 x1-2 ; oper.type:= message; rx w2 x1+2 ; oper.buffer:= buf; al w1 x1-6 ; sem:= message_sem; jl. w3 c110. ; signal_chained(sem,oper); am (b27) ; end; rl w3 +6 ; al w2 0 ; buf:= 0; <* has been removed *> jl x3 ; end; e. \f ; procedure entry timer_message; ; ; sends a delay-message to 'clock'. ; ; call return ; w0: - unchanged ; w1: - destr. ; w2: - buf or 0 ; w3: link current_coroutine b.j5 w. c116: am (b27) ; begin rs w3 +14 ; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate_testoutput(1<15); jl. w3 h4. ; 3<22+1<15 ; j0: rl w3 b28 ; al w1 x3+a626 ; mess:= cur.ext2.delaymess; al w2 x3+a630 ; ref:= cur.ext2.answer_descr; al w3 x3+a616 ; name:= <:clock:>; jd 1<11+16 ; sendmessage(name,mess,ref,result); rl w3 (b28) ; am (b27) ; rl w1 +14 ; jl x1 ; end; e. \f ; procedure timerscan(ref,buf); ; ; this procedure is called from 'check_event_queue' when an answer arrives ; from 'clock'. the timer queue is inspected and coroutines which time out ; are started with result = timeout. after the inspection a delay-message is ; sent to 'clock'. ; ; call return ; w0: - destr. ; w1: ref destr. ; w2: buf 0 (the message buffer is removed) ; w3: link link b.j5,i5 w. c117: am (b27) ; begin rs w3 +16 ; ext1(16):= link; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate_test_output(1<16); jl. w3 h4. ; 3<22+1<16 ; j0: rl w3 b28 ; al w1 x3+a566 ; <* release messagebuffer *> jd 1<11+18 ; wait_answer(cur.ext2.test_mess_area,buf); j4: ; al w2 x3+a552 ; corout:= first in timer queue; j1: rl w2 x2 ; while corout <> timer queue head do j3: sn w2 x3+a552 ; begin jl. j2. ; corout:= next(corout); rl w1 x2+4 ; with corout do sh w1 0 ; begin jl. j1. ; if timer > 0 then al w1 x1-1 ; begin rs w1 x2+4 ; se w1 0 ; timer:= timer-1; jl. j1. ; if timer = 0 rl w0 x2 ; then start(corout,prio,timeout); am (b27) ; rs w0 +18 ; al w2 x2-2 ; rl w0 x2+a698 ; end; al w1 0 ; end; jl. w3 c100. ; am (b27) ; rl w2 +18 ; rl w3 b28 ; jl. j3. ; end while; j2: jl. w3 c116. ; timer_message; am (b27) ; rl w3 +16 ; link:= ext1(16); al w2 0 ; buf:= 0; <* has been removed *> jl x3 ; end; e. \f ; procedure entry cregretmessage(buf); ; ; this procedure is used to regret a message sent by csendmessage, i. e. the ; monitor procedure 'regretmessage' is called and the corresponding message ; buffer extension is released. ; ; call return ; w0: - destr. ; w1: - destr. ; w2: buf buf ; w3: link current_coroutine b.j5 w. c118: am (b28) ; begin rs w3 (0) ; am (b28) ; rl w3 +a544 ; sn w3 0 ; if testoutput active jl. j0. ; then generate test_output(1<17); jl. w3 h4. ; 3<22+1<17 ; j0: jd 1<11+82 ; regretmessage(buf); rl w1 x2-2 ; ref:= buf.ref; rl w3 b28 ; ext:= next(message_buffer_ext_head); al w0 x1-2 ; next(message_buffer_ext_head):= ref; rx w0 x3+a588 ; next(ref):= ext; rs w0 x1-2 ; rl w3 (b28) ; jl (x3) ; end; e. \f ; procedure entry testout ; ; ; this procedure creates a user test record defined by the registers ; as follows: ; ; call return ; w0: testrecord ident unch. ; w1: start address unch. ; w2: no_of_halfwords unch. ; w3: link current coroutine b.j5 w. c119: am (b28) ; begin rs w3 (0) ; am (b28) ; if test output active then rl w3 +a544 ; sn w3 0 ; jl. j0. ; jl. w3 h4. ; generate testoutput(1<18) 3<22+1<18; j0: rl w3 (b28) ; jl (x3) ; end; e. \f ; procedure generate testoutput(testkind); ; ; this procedure creates a testrecord or initiates the creation of a test ; record as follows: ; ; 1) if word 128 in monitor table is set ( <> 0 ) a message defining the ; test record is sent to the coroutine test output process. ; ; 2) otherwise a test record is written in the cyclical test output buffer. ; formats in the cyclical buffer: ; ; user test record coroutine function (signal etc.) ; +0 testkind testkind ; +2 time1 time1 ; +4 time2 time2 ; +6 user_ident,length w0 ; +8 test information w1 ; +10 - " - w2 ; +12 - " - coroutine ident ; +14 etc. address of current coroutine ; ; testkind values: ; 1<0 : start ; 1<1 : wait ; 1<2 : pass ; 1<3 ; inspect ; 1<4 : csendmessage ; 1<5 : cwaitanswer ; 1<6 : answer_arrived ; 1<7 : signal_sem-signal_binary ; 1<8 : wait_semaphore ; 1<9 : signal_chained ; 1<10 : inspect_chained ; 1<11 : wait_chained ; 1<12 : sem_sendmessage ; 1<13 : sem_answer_proc ; 1<14 : message_received ; 1<15 : timer_message ; 1<16 : timer_scan ; 1<17 : cregretmessage ; 1<18 : user defined testrecord ; ; call return ; w0: - unchanged ; w1: - unchanged ; w2: - unchanged ; w3: link current coroutine b.j10,i5 w. h4: am (b27) ; begin rs w3 +8 ; ext1(8):= link; rl w3 b27 ; ds w1 x3+22 ; save working registers rs w2 x3+24 ; rl w1 x3+8 ; rl w3 (b28) ; rl w0 x3+a716 ; if testkind is included in curr.corout.testm then la w0 x1 ; begin sn w0 0 ; jl. j6. ; rl w3 b141 ; if core(128) <> 0 then sn w3 0 ; begin jl. j1. ; rl w3 b28 ; al w1 x3+a566 ; rs w0 x1 ; cur.ext2.testmess(1):= testkind; al w3 x3+a556 ; jd 1<11+16 ; send message(testmes,cmontest); jd 1<11+18 ; wait answer; jl. j6. ; else j1: rl w3 b28 ; begin ! create record in cyclical buffer ! am (b27) ; if testkind = user record rl w1 +24 ; se. w0 (i0.) ; then length:= length(user record) al w1 8 ; else length:= 8; rl w2 x3+a540 ; if (start(next record)+length+8) > wa w1 x3+a540 ; top(test buffer) then al w1 x1+8 ; begin sh w1 (x3+a542) ; jl. j2. ; al w1 0 ; insert dummy end record rs w1 x2 ; rl w2 x3+a538 ; start(next record):= start(test buffer); ; end; j2: rs w0 x2 ; insert testkind in record rl w3 0 ; jd 1<11+36 ; get clock ds w1 x2+4 ; insert time in test record sn. w3 (i0.) ; if testkind = coroutine function then jl. j3. ; begin rl w3 (b28) ; am (b27) ; dl w1 +22 ; ds w1 x2+8 ; insert w0,w1 am (b27) ; rl w0 +24 ; rs w0 x2+10 ; insert w2 rl w0 x3+a718 ; ds w0 x2+14 ; insert coroutine_ident, addr. of curr,corout. al w2 x2+14 ; jl. j5. ; end j3: rl w3 b27 ; else dl w1 x3+22 ; begin <* user defined test record *> rl w3 x3+24 ; hs w0 x2+6 ; insert user identification hs w3 x2+7 ; insert length al w2 x2+8 ; j4: rl w0 x1 ; transfer test information rs w0 x2 ; al w3 x3-2 ; sh w3 0 ; jl. j5. ; al w2 x2+2 ; al w1 x1+2 ; jl. j4. ; end; ; end; j5: rl w3 b28 ; al w2 x2+2 ; update start(next record) in procees ext2 rs w2 x3+a540 ; j6: rl w3 b27 ; dl w1 x3+22 ; load working registers rl w2 x3+24 ; rl w3 x3+8 ; return:=ext1(8); jl x3+2 ; end; i0: +1<18 ; testkind f. user test record e. e. z. #, ;<*rettelse til errorlog *> l./g66:/, l./j1:/, l./rlw1x1+a141/, l1,i/ sh w1 (b3) ; if receiver defined then jl. j2. ; /, l./al w3 32/, r/ /j2: /, l./h4:/, l./dlw0/, i/ rs. w2 i8. ; save received buffer rl w1 b19 ; check for clockchange c.w1=cur receiver jl. w3 j24. ; rl. w2 i8. ; restore buffer /, l./c35:/, l./rx w0/, i/ al. w3 j38. ; set continue adr /, l./j22:/, r/j22 :/ /, i/ j22 : al. w3 j38. ; prepare continue adr /, l./j24:/, i/ ; called when a message or an interrupt is received ; called with w1=cur receiver and w3 holding the return adr /, l./jl.j38./, r/./ /, r/j38./x3 /, l1, i/ rs. w3 i9. ; save return adr /, l./j36:/, l./b19/, l1, i/ jl. (i9.) ; /, l./i6:/, l 1, i/ i8 : 0 ; saved buffer from message received i9 : 0 ; return adr for j24 /, f $disc ;******************** $fpaline ;******************** $host ;******************** l./i0=/, r/01 12/04 27/ l./n4:/, l./n5:/, l./j1/, r/j1/j0/, l./n11:/, l./+p99/, r/rl/zl/, l./n22:/, l./p93/, r/p93 /p323/, l./p91/, r/p91 /p321/, f $fpasub ;******************** l./i0=/, r/810112/81 03 25/ ;<* ret fejl i mt driver: set state=regretted hvis sender er stoppet*> l./h118:/, l./q1:/, l./j1:/, l./u2/, r/u2/u3/, r/testmore/no block/, f $tabinit ;******************** $procfnc1 ;******************** $procfnc2 ;******************** l./i0=/,r/81 01 09/81 04 06/ l./m158:/,l./x2+a50/,i/ rl w0 x1+a30 ; rs w0 x2+a60 ; mref.pseudo:= save w2(cur) /,f $s1 ;******************** l./i0=/, r/810126/81 05 20/ l./c4=/, i/ c16= 2 ; stack depth ( of nested 'reads' ) /, l./c82=/, r/1760/0760/, l./c16:c82/, d, l./; definition of core table entry format:/, l./c19/, d 2,i/ c22=c18+2 ; segment no in susercat or -1 c19=c22+2 ; kind , name of alternative primary input c93=c19+10 ; kind , name of alternative primary output c11=c93+10+2 ; size of coretable entry /, l./; definition of a console descr/, l./c44=/, r/c43+4/c96+10/, i/ c95=c43+4 ; primin : kind , name c96=c95+10 ; primout: kind , name /, l./; meaning of command mask:/, l./; bit 2:/, r/print/print,date/, l./; bit 3:/, r/load/load,read,unstack,i,o/, l./; definition of work area format:/, l./c90=/, i/ ; *** start of part to be saved-restored /, l./c65=c57+2/, r/c57/c71/, i/ ; *** end of part to be saved-restored c58=c57+2 ; input stack pointer c59=c58+2 ; first stack element ; subformat of stack entry: ; name + nta of area c60=10 ; segment no c61=c60+2 ; saved last addr c62=c61+2 ; saved char shift c63=c62+2 ; saved char addr c64=c63+2 ; (size of entry) c71=c16*c64+c59; (top of stack) c72=c71-c64 ; last stack entry start c73=c59-c64 ; base of stack /, l./d0:/, l./rl w0 b4;/, d./rl w0 x1;/, i/ am (b4) ; rl w0 a199<1 ; /, l./jl. f1./, d, i/ jl. (i4.) ; goto end line; /, l./i3:/, l1, i/ i4: g30 ; /, l./; procedure next char/, i/ b. i20, j20 w. i0: 0 ; saved link i1: 0 ; saved w3 i2: 0 ; saved w1 i5: h20 ; first of buffer j0: g3 ; end line: not allowed j1: g12 ; end line: area unknown j2: g15 ; end line: area error j5: e24 ; pointer to: work j6: e26 ; pointer to: last addr j7: e28 ; pointer to: char addr j8: e27 ; pointer to: char shift j10: e47 ; pointer to: area input mess j11: e49 ; pointer to: last of buffer j12: e50 ; pointer to: segment number j13: e32 ; pointer to: answer ; procedure stack input ; stacks the input pointers and selects the given area for input ; ; call: w2=name, w3=link ; exit: all regs undef d79: ; stack input: rs. w3 i0. ; save return; rl. w1 (j5.) ; w1 := work; rl w3 x1+c58 ; w3 := stack pointer; sn w3 x1+c72 ; if stack pointer = last stack entry then jl. (j0.) ; goto not allowed; (* i.e. stack overflow *) al w3 x3+c64 ; increase (stack pointer); rs w3 x1+c58 ; rl. w1 (j6.) ; rs w1 x3+c61 ; save last addr in stack entry; dl. w1 (j7.) ; ds w1 x3+c63 ; save char shift and char addr in stack entry; dl w1 x2+2 ; move name to stack entry; ds w1 x3+2 ; dl w1 x2+6 ; ds w1 x3+6 ; ; prepare variables for immediately buffer change al w0 -1 ; rs w0 x3+c60 ; segment.stack entry := -1; rl. w2 i0. ; w2 := return; jl. d82. ; goto next segment; ; procedure unstack input ; restores the char pointers from the stack, and maybe also the buffer ; ; call: w2=link ; exit: all regs undef d80: ; unstack input: rl. w1 (j5.) ; w1 := work; rl w3 x1+c58 ; w3 := stack pointer; sn w3 x1+c73 ; if stack pointer = stack base then jl x2 ; return; al w0 x3-c64 ; rs w0 x1+c58 ; decrease (stack pointer); dl w1 x3+c63 ; ds. w1 (j7.) ; restore char shift and char addr from stack entry; rl w1 x3+c61 ; rs. w1 (j6.) ; restore last addr from stack entry; jl. d81. ; goto get segment; ; procedure get segment ; ; call: w2 = link ; exit: w1,w2,w3=unch, w0=undef d81: ; get segment: am 0-1 ; increment := 0; ; procedure get next segment ; ; call: w2 = link ; exit: w1,w2,w3=unch, w0=undef d82: ; next segment: al w0 1 ; increment := 1; ; procedure read segment ; ; call: w0 = increment, w2 = link ; exit: w1,w2,w3=unch, w0=undef d83: ; read segment: ds. w3 i1. ; save return, w3; rs. w1 i2. ; save w1; rl. w1 (j5.) ; w1 := work; rl w3 x1+c58 ; w3 := stack pointer; sn w3 x1+c73 ; if stack pointer = stack base then jl. i10. ; goto return; rl. w1 i5. ; w1 := first of buffer; al w2 x1+510 ; w2 := last of buffer; ds. w2 (j11.) ; sn w0 0 ; if increment <> 0 then jl. i8. ; begin rs. w2 (j6.) ; last addr := last of buffer; rs. w1 (j7.) ; char addr := first of buffer; al w1 -16 ; rs. w1 (j8.) ; char shift := -16; i8: ; end; wa w0 x3+c60 ; segment := segment + increment; rs w0 x3+c60 ; rs. w0 (j12.) ; jd 1<11+92; create entry lock process(area name); se w0 0 ; if result <> ok then jl. (j1.) ; goto area unknown; al. w1 (j10.) ; jd 1<11+16; send message (area input, area name); al. w1 (j13.) ; jd 1<11+18; wait answer(answer area); rl w1 x1 ; lo w1 0 ; w1 := status 'or' result; jd 1<11+64; remove process (area name); se w1 1 ; if any arror then jl. (j2.) ; goto area error; i10: ; return: rl. w1 i2. ; restore regs; dl. w3 i1. ; jl x2 ; return; e. ; /, l./d1:/, l./al w0 10;/, d./al w2 x2+2;/, i/ al w1 -16 ; char shift := -16; al w2 x2+2 ; char addr := char addr + 2; sh. w2 (e26.) ; if char addr > last addr then jl. i0. ; begin al w0 10 ; char := newline; rl. w1 e24. ; rl w2 x1+c58 ; sn w2 x1+c73 ; if stack pointer = stack base then jl. i1. ; goto classify char; (* i.e. not end of area-read-buffer *) jl. w2 d82. ; get next segm; jl. d1. ; goto next char; ; end; /, l./i1:/, d, i/ ds. w2 e28. ; i1: ; classify char: /, l./se w1 5;/, d./z. jl x3+0;/, i/ jl x3 ; end; /, l./d2:/, l./al w0 0;/, d1, i/ al w1 0 ; se. w1 (e87.) ; if areabuf undef then jl. w2 d81. ; get segment; rs. w1 e87. ; areabuf := defined; al w0 0 ; param type := 0; /, l./d3:/, l./ld w2 -2;/, i/ al w2 0 ; /, l./d7:/, d, i/ d11: ; newline or semicolon: sn w0 10 ; jl. d8. ; while char <> newline do jl. w3 d1. ; next char; jl. d11. ; goto delimiter; d7: ; unknown: sn w0 25 ; if char = em then jl. w2 d80. ; unstack input; al w2 3 ; /, l./d22:/, l./; procedure typeline(buf)/, l./b.i24/, i/ ; procedure send buf (mess, buf) ; (as typeline, but at call: w1=mess) /, l./d23:/, d, i/ w. d23: ; type line: al. w1 e44. ; mess := output message; d26: ; send buf: rs. w3 e60. ; /, l./dl w1 x2+a11+2;/, g3/w1/w0/, l./al. w1 e44./, d, l./d31:/, l./+12/, r/+12/c22/, l./d35:/, l./i25:/, l./jl. w3 d30./, r/;/; reserve core/, l1, d 2, i/ al w3 x1+c95 ; move kind,name of primin al w2 x2+c19 ; and primout to coretable j0 : rl w0 x3 ; (set by i and o commands ) rs w0 x2 ; al w3 x3+2 ; al w2 x2+2 ; se w3 x1+c44 ; jl. j0. ; /, l./i10:/, d, l./i8:/, d./i23:/, i/ ; transfer claims to child, ; the claimlist in the console-description i8: ; not 'all' bs (console): rl. w3 e25. ; w3 := claimbase := console; i13: ; next chaintable: rs. w3 i22. ; save claimbase; dl w1 x3+c44+6 ; perm claim := claimlist(claimbase); ds. w1 i24. ; wa w0 x3+c44+0 ; temp entries := temp+perm entry claim; wa w1 x3+c44+2 ; temp segms := temp+perm segm claim; rs. w0 i23. ; main entries := temp entries; al w0 0 ; temp entries := 0; ws. w3 e25. ; w3 := index in claimlist; ls w3 -2 ; wa w3 b22 ; w3 := chain table number; sl w3 (b24) ; if all chains handled then jl. (i2.) ; return; rl w3 x3 ; w3 := chain table addr; al. w2 g20. ; error addr := claims exceeded; i14: ; transfer claim: ; w0=temp entries, w1=temp segments ; w2=error address ; w3=chaintable address rs. w2 i20. ; save(error addr); al w2 0 ; key := 0; i15: ; next key: ds. w1 x2+e52. ; claim(key) := entries,segments; al w2 x2+4 ; increase(key); sn w2 a109*4 ; if key = min aux key then dl. w1 i24. ; entries,segments := perm claim; sh w2 a110*4 ; if key <= max cat key then jl. i15. ; goto next key; dl w1 x3-a88+18 ; name := docname.chaintable; ds. w1 e21. ; dl w1 x3-a88+22 ; ds. w1 e23. ; rl. w3 e25. ; w3 := proc name; al w3 x3+c29 ; al. w2 e20. ; w2 := docname; al. w1 e51. ; w1 := claim; jd 1<11+78; set bs claim; sn w0 0 ; if result = ok then jl. i16. ; goto maincat entries; se w0 1 ; if result <> claims exceeded then jl. i17. ; goto next entry; al w0 1 ; hs. w0 e81. ; fiddle with remove indicator... jl. w3 d40. ; remove child; jl. (i20.) ; goto error; i16: ; maincat entries: ld w1 -100 ; perm claim := 0,0; ds. w1 i24. ; rx. w0 i23. ; w0 := main entries; main entries := 0; rl w3 b25 ; w3 := main catalog chain table; al. w2 g25. ; w2 := error addr := no maincat entries; se w0 0 ; if main entries <> 0 then jl. i14. ; goto transfer claim; i17: ; next entry: rl. w3 i22. ; increase (claimbase); al w3 x3+8 ; jl. i13. ; goto next chaintable; i20: 0 ; error addr i22: 0 ; claimbase i23: 0 ; main entries; i24=k+2, 0,0 ; perm claim (entries, segments) /, l./d36:/, l./jl. w3 d25./, r/ole,/ole,coretableelement,/, l./al. w1 e61./, i/ ; override these default w0 and w2 assignments, ; in case of user-defined primary input (or -output) names al w1 x3+c19 ; w1 := addr of primary input descr; rl w0 x1+2 ; se w0 0 ; if name defined then rs. w1 e61. ; child w0 := primary input descr; al w1 x3+c93 ; w1 := addr of primary output descr; rl w0 x1+2 ; se w0 0 ; if name defined then rs. w1 e63. ; child w2 := primary output descr; /, l./d37:/, l1 ,i/ rl. w1 e29. ; if state.process <> wait start zl w1 x1+a13 ; then goto error so w1 2.100000 ; jl. g3. ; /, l./1<11+52/, l1, i/ al. w3 i1. ; prevent remove of process /, l./e51./, i/ al. w3 e40. ; /, l./1<11+16/, l-1, d, l./w3/, r/w3/w1/, l./rs. w3 (i19.)/, r/i19/e12/, r/w3/w1/, l./i12:/, i/ i9: am 2 ; i10: am 2 ; i11: am 2 ; /, l./i14:/, g 1/w3/w2/, l./al.w3 e40/, d, l./;dont/, d./jl. i15./, l./i19:/, d, i/ i3 : 2.100000 ; state bit : wait for stop or start /, l./d41:/, d./jl. i0./, i/ w. d41: ; find work: rl. w1 e13. ; work := first work; i0: ; loop: rs. w1 e24. ; sn w2 (x1+c50) ; if state(work) = state then jl x3 ; return; al w1 x1+c2 ; increase(work); sh. w1 (e14.) ; if work <= last work then jl. i0. ; goto loop; jl. g31. ; goto exam next; <* not expecting this answer *> /, l./d42:/, l./ds w3 x1+c51/, l1, i/ rs. w2 e88. ; expected answer := state; /, l./; procedure restore work/, l./; w0 destroyed/, r/destroyed/logical status/, l./; w1 work/, r/work/ /, l./d43:/, r/rs./rl./, l./i0:/, i/ rs. w2 e87. ; areabuf := undef; /, l./rl. w3 e59./, g1/w3/w0/, l./d45:/, l./;procedure set_zero/, d./i3:/, i/ ; procedure clear claimlist ; comment sets zeroes in whole claimlist of console descr ; ; call: w3 = link ; exit: all regs undef b. i10 w. d46: ; clear claimlist: rl. w1 e25. ; w1 := console; al w2 x1+c48-c44+2; w2 := rel top of claimlist; al w0 0 ; i0: ; rep: al w2 x2-2 ; decrease(pointer); sl w1 x2 ; if pointer <= start of console then jl x3 ; return; rs w0 x2+c44 ; claimlist(pointer) := 0; jl. i0. ; goto rep; /, l./d61:/, l./j1:/, g2/w1/w3/, l-1, r/x1/x3/, l2, r/rl/wa/, l1, d, r/al w3 x3/ /, l./d71:/, l./e.z.jl. g18/, r/ jl.g18.//, l./d78:/, l./i1:/, l./shw1/, r/h/l/, r/1/3/, r/x3/x1/, l./; parameter table:/, l./i6=/, l1, i/ i9=(:d11-d2:)<2+0 /, l./h1:/, l./i6,i7/, r/i7/i9/, r/delimit0/endline/, l./i7,i7/, r/,i7/, i9/, r/,delimit0/, endline/, l./i7,i7/, r/,i7/, i9/, r/,delimit0/, endline/, l./d25=k-2/, l1, i/ jl. d26. ; d26=k-2 /, l./d35=k-2/, l1, i/ jl. d36. d36=k-2 jl. d38. d38=k-2 /, l./f1: jl. g30./, d, i/ jl. d79. ; d79=k-2 /, f $s2 ;******************** l./i0=/, r/810112/81 05 05/ l./e8:/, i/ e12:h3 ; <top command table> /, l./e24:h8/, r/>/> ( initially: first work )/, l1, i/ ; *** the following variables must match part of work-area /, l./e25:/, r/0 /h21/, r/>/> ( initially: first console )/, l./e27:/, r/0/8/, r/>/> (initially: prepared for empty char buf)/, l./e30:/, l1, i/ ; *** end of work-area match /, l./e39:/, i/ e88:0 ; expected answer e89:0 ; executing reentrant code: 0=false, -1=true (initially = false) /, l./e50:/, l1, i/ e87: 0 ; areabuf state: 0=defined, else undef (initially defined) /, l./g1:/, l1, d, i/ g48=k+4 <:ready **date not initialized <0>:> ; text until date initialized /, l./g2:/, l./<:syntax error/, r/error/error:/, l./g27:/, l1, r/<:ille/<:ille/, l./g28:/, i/ g47: jl. w1 g28. ; <:input aborted<0>:> /, l./g28:/, l./g2./, i/ se w3 (b13) ; if clock initialized then rs. w3 g48. ; remove warning /, l./al w3 -1;/, l1, i/ rs. w3 e89. ; executing reentrant code := true; /, l./al w0 58;/, d1, l./g46:/, l./al w1 0; reset remove list/, d./rs. w1 e33./, l./g30:/, l1, i/ rs. w2 e81. ; reset remove list indicator /, l./g32:/, l./sn w0 0;/, i/ sz. w2 (e89.) ; if executing non-reentrant code jl. g41. ; and se. w2 (e88.) ; event <> expected answer then jl. g32. ; goto exam next; g41: ; /, l./al. w1 e51./, i/ jl. w3 d41. ; find work(event,old work); /, l1, l./jl. w3 d41./, d1, l./g34:/, l./dl w0 x1+4/, d3, l./rs. w1 e24./, d, i/ al w0 x1+c73 ; input stack pointer := stack base; rs w0 x1+c58 ; g39: ; end; /, l./al w2 x2-2/, d./al. w3 e40./, l./jd 1<11+16/, d, i/ jl. w3 d26. ; send buf (input mess, buf); /, l./jl. g2./, r/g2. /g47./, l./rl. w2 e52./, d./ds. w3 e27./, i/ al w2 x1+c66-2 ; char shift := > 0; (* i.e. change word *) ds. w2 e28. ; char addr := work + linebuf - 2; wa. w2 e52. ; rs. w2 e26. ; last addr := char addr + bytes; /, l./g36:/, l1, r/g1/g98/, l./rl. w3 e7./, i/ jl. w3 d19. ; init write; al w3 -1 ; rs. w3 e89. ; executing reentrant code := true; /, l./g45:/, d, i/ ; init write has been called /, l./g38:/, l./jl. g2./, l1, i/ ; all commands, not contained in primary part of command table, are ; considered non-reentrant al w3 0 ; rs. w3 e89. ; executing reentrant code := false; /, l./g50:/, i/ g98: rl. w1 e24. ; if stack=stackbase then rl w2 x1+c58 ; goto endline else sn w2 x1+c73 ; goto next command jl. g1. ; jl. g35. ; /, l./jl. w3 d41./, l1, d, l./g42:/, l./jl.w3 d42./, d./jl.g30./ , i/ rs. w2 e23.+2 ; clear function zl. w1 e32.+1 ; if stop bit on then so w1 8.200 ; begin jl. g97. ; zl. w1 e32. ; save function rs. w1 e23.+2 ; se w1 10 ; if function = replace then jl. g97. ; save areaname rl. w3 e24. ; save name in input buffer al w3 x3+c66 ; dl. w1 e32.+10 ; ds w1 x3+2 ; dl. w1 e32.+14 ; ds w1 x3+6 ; end dl. w1 e26. ; simulate empty input string ds. w1 e28. ; ( after unstack command) g97: jl. w3 d42. ; save work am 0 ; +2 error (dont care) rl. w3 e23.+2 ; if function =finis or replace then se w3 10 ; sn w3 2 ; sz ; jl. g30. ; jl. w3 d76. ; adjust bs claim jl. w3 d40. ; remove process rl. w3 e23.+2 ; if function =replace then se w3 10 ; jl. g30. ; rl. w2 e24. ; stack input and al w2 x2+c66 ; jl. w3 d79. ; goto next command jl. g35. ; /, l./b.i30w.;new:/, i/ g45: ; base for command-relatives ; define pseudo-entries for conditinally-assembled commands g70: ; break g72: ; include g73: ; exclude g74: ; call g75: ; list g76: ; max g77: ; replace g83: ; all g89: ; job g90: ; print g91: ; modify jl. g18. ; goto not implemented; ; command syntax: read <area name> g57: ; read: jl. w3 d15. ; next name; al. w2 e20. ; am -2048 ; jl. w3 d79.+2048; stack input (name); jl. g35. ; goto next command; ; command syntax: unstack g58: ; unstack: am -2048 ; jl. w2 d80.+2048; unstack input; jl. g35. ; goto next command; ; command syntax: date <year> <month> <date> <hour> <min> <sec> b. i20, j30 w. ; j0: ; minimum values: 81 , 1 , 1 , 0 , 0 , 0 j1: ; top values: 99+1, 12+1, 31+1, 23+1, 59+1, 59+1 j2: ; year,month,day,hour,min,sec 0 , 0 , 0 , 0 , 0 , 0 j5: ; month table: jan, ..., dec h. 365, 396, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 w. j11: 4 ; minutes per four minutes j13: 24 ; hours per day j14: 60 ; minutes per hour j17: 365*3+366 ; days per four years (inclusive leap year) j18: 10000 ; units per second j20: 60*4 * 10000 ; units per four minutes j30: <:oldcat:> ; name of successor-command g49: ; date: al w1 0 ; for i := 0 step 2 until 10 do i0: ; begin jl. w3 d16. ; next integer; sl. w0 (x1+j0.) ; if number < min value sl. w0 (x1+j1.) ; or number >= top value then jl. g2. ; goto syntax error; (* i.e. illegal date *) rs. w0 x1+j2. ; save number; al w1 x1+2 ; se w1 12 ; jl. i0. ; end; dl. w2 j2.+2 ; w1 := year; w2 := month; sh w2 2 ; if month > february then al w1 x1-1 ; year := year - 1; al w1 x1-68 ; days := (year - 68) wm. w1 j17. ; * days in four years as w1 -2 ; æ47æ 4 ba. w1 x2+j5.-1 ; + month table (month) wa. w1 j2.+4 ; + day; wm. w1 j13. ; w1 := hours := days * 24 wa. w1 j2.+6 ; + hour; al w2 0 ; w2w3 := min; rl. w3 j2.+8 ; wm. w1 j14. ; w0w1 := minutes := hours * 60 aa w1 6 ; + min; wd. w1 j11. ; w1 := fourmin := minutes æ47æ 4; wm. w0 j14. ; seconds := minutes mod 4 * 60 wa. w0 j2.+10 ; + sec; wm. w0 j18. ; msec := seconds * 10000; rl w3 0 ; (w2=0) w3 := msec; wm. w1 j20. ; clock := fourmin * 2400000 aa w1 6 ; + msec; jd 1<11+38; set clock (clock); dl. w1 j30.+2 ; name := successor command name; ds. w1 e21. ; al w0 1 ; type := 1; <* i.e. pretend that 'oldcat' has been read *> sl w0 (b25) ; if maincat not defined yet then jl. g36. ; goto next command; <* i.e. interpret 'oldcat' *> jl. g35. ; goto next command; e. ; /, l./g51:/, l./rl. w3 e25.;/, d./al w2 x3+c1-2/, r/;/; clear claimlist;/, l./jl. g16.;sorry goto end line/, l./rl. w3 e25.;/, d./al w1 x1+4;/, d./ds w0 x1 ;/, i/ wa. w2 e25. ; dl. w0 i6. ; perm claim(work device) := ds w0 x2+c44+6 ; standard segment,entries; /, l./jl. g52./, i/ al w0 0 ; rs w0 x1+c95+2 ; clear primary input name; rs w0 x1+c96+2 ; clear primary output name; /, l./i11:0/, d-1, l./g83:/, d, l1, i/ g83 = k ; all: /, l./c.-4000/, l./hs w0 x1+c26;/, l./rl.w1 e25.;/, d./al w1 x1+c44;/, r/;/; clear claimlist;/, l./e. jl. g18.; goto endline/, d, i/ e. /, l./g52:/, i/ b. j5 w. g94: am c95-c96 ; i: g95: al w1 x1+c96+2 ; o: jl. w3 d16. ; get kind rs w0 x1-2 ; jl. j1. ; continue with get name /, l./jl. w3 d15./, r/ / j1: /, l./j2:/, l1, i/ e. /, l./g70:/, d, l1, i/ g70 = k ; break: /, l1, r/w./ /, l./jl. g18./, d, i/ z. /, l./g72:/, d1, l1, i/ g72 = k ; include: am 2 ; g73 = k ; exclude: /, l./al w0 0; dummy instr/, d, l1, d1, l./g74:/, d, l1, i/ g74 = k ; call: /, l./jl. g18./, d, i/ e. z. /, l./g75:/, d, l./b.i24/, r/24 /24 w./, l1, i/ i7: <: error <0>:> i8: <: stop <0>:> i9: <: run <0>:> i10: <: wait <0>:> g75 = k ; list: /, l./w. rl w2 b6/, r/w./ /, l./al w1 x1 -12;/, r/al/ac/, l1, d, l./zl w1 x2+a13;/, d./i11:/, i/ bl w0 x2+a13 ; w0 := process state; al. w1 i7. ; sz w0 2.10000000; al. w1 i10. ; sz w0 2.00100000; al. w1 i8. ; sz w0 2.01000000; al. w1 i9. ; jl. w3 d21. ; writetext(process state); rl w1 x2+a34 ; /, l./jl. g2.;/, r/g2. /g47./, l1, d, l./jl. g35./, d./<: wait /, l./jl. g18./, d, i/ e. z. /, l./g76:/, d, l1, i/ g76 = k ; max: /, l./w.jl.w3 d19./, d, i/ w. /, l./i0:/, l./jl. g2.;/, r/g2. /g47./, l./jl. g18./, d, i/ e. z. /, l./g77:/, d, i/ /, l./b.i24/, i/ g77 = k ; replace: /, l./rl w3 66/, r/66/b1/, l./i13:;/, d./i4:/, i/ i2: am g13-g11; i3: am g11-g12; i4: am g12-g14; /, l./i21:/, d, l./i23:/, d1, i/ e. z. /, l./; stepping stone/, l./jl.d16./, i/ jl. d15., d15=k-2 /, l./d34./, i/ jl. g27., g27=k-2 /, l./jl. d61./, i/ jl. d46., d46=k-2 /, l./d78=k-2/, l1, i/ /, l./g79:/, l./jd 1<11+52/, l1, i/ al. w3 i1. ; (prevent remove process(name)) /, l./jd 1<11+8;/, i/ al. w3 e20. ; /, l./g86:/, d3, i/ ; command syntax: user <lower> <upper> ; command syntax: login <lower> <upper> ; command syntax: project <lower> <upper> g86: am c43-c42; user: update userbase; g82: am c42-c41; login: update loginbase; g80: al w2 x1+c41 ; project: update projectbase; /, l./rs. w0 i3./, d, i/ rs w0 x2+0 ; lower := integer; /, l./i0:/, d-1, i/ rs w0 x2+2 ; upper := integer; /, l./i1:/, d2, l./i3:/, d, l./g81:/, l./al.w1e66.-2/, r/e66.-2;/e51.+a110*4;/, l./g84:/, d, i/ ; command syntax: temp <docname> <segments> <entries> g84: ; temp: am c45-c47; (update temp claims) ; command syntax: perm <docname> <segments> <entries> g85: ; perm: al w3 c47 ; (update perm claims) wa. w3 e25. ; rs. w3 i6. ; save abs addr of claim; /, l./rl. w3 e25./, d2, i/ am. (i6.) ; update segments and entries; ds w1 x2 ; /, l./g85:/, d./jl.g35./, l./i5:0/, l1, i/ i6: 0 ; abs addr of claim (in console descr) /, l./g89:/, d, i/ w. /, l./rl. w1 e25./, i/ g96 = k ; get: am -1 ; g89 = k ; job: al w0 0 ; set startflag rs. w0 i16. ; al w3 0 ; rs w3 x1+c95+2 ; clear primin and primout rs w3 x1+c96+2 ; /, l./rl. w1 e25./, d./jl. w3 d46./, i/ jl. w3 d46. ; clear claimlist; /, l./rs. w1 i16./, d, l./al w3 510;/, d1, i/ al w3 x2-510 ; w3 := last used in segment; /, l./j8:/, r/e21. /(i6.)/, l1, r/e23. /(i7.)/, l./sh w1 -1/, d1, l./e79./, g 9/e79. /(i5.)/, l./j4:/, l./e25/, r/e25. /(i3.)/, l./j5:/, l./c44/, r/c44/c95/, r/;/; (until i and o are defined in susercat)/, l./j2:/, d 1, i/ j2: ; rl. w1 (i3.) ; restore console al w2 -1 ; areabuf := undef; rs. w2 (i4.) ; sn. w2 (i16.) ; if only load then jl. g35. ; goto next command; /, l./i10:/, i/ i3: e25 i4: e87 i5: e79 i6: e21 i7: e23 /, l./i16:/, r/entry0/job/, r/getentry0/job command/, l./jl. g18./, d, l./g87:/, d./i1:/, i/ w. g87: am 1<8 ; lock: lock := true; g88: al w0 0 ; unlock:lock := false; rs. w0 (i0.) ; jl. g35. ; goto next command; i0: e80 ; lock indicator /, l./;print:/, r/;print:/;/, i/ c. (:c23>15a.1:)-1/, l./g91:/, d1, i/ g91 = k ; modify: /, l./g90:/, d-1,d, i/ g90 = k ; print: /, l./i26:/, l./am -2046/, d1, i/ z. e. /, l./g93:/, l./sl w0 -1/, d1, i/ sz. w0 (i1.) ; if prio < 0 or prio >= 4096 then /, l./jl. g35.;/, l./i1:1<12/, r/1<12/-1<12/, l1, i/ e. /, l./d76:/, l./rl.w1 e25/, r/e25/e29/, r/console/child/, l 1, r/c29/a11/, l./j6:/, l./jl. (i10.)/, i/ am -2048 ; rs. w3 e87.+2048; areabuf := undef; /, l./h0:/, l./; can em sub/, r/8.77/8.76/, l./w.h2=/, l./:dump:/, i/ <:date:> , 1<21+1<14+g49-g45 /, l./:functi:/, i/ <:i:>,0 , 1<20+g94-g45 /, l./list/, i/ <:get<0>:> , 1<20+g96-g45 /, l./:perm:/, i/ <:o:>,0 , 1<20+g95-g45 /, l./:remove:/, i/ <:read:> , 1<20+1<14+g57-g45 /, l./:user:/, i/ <:unstac:> , 1<20+1<14+g58-g45 /, l./b110 = g45/, d./g77=g18/, i/ b110 = g45 ; command base b112 = d2 ; call next param b113 = d15 ; call next name b114 = d16 ; call next integer b115 = g2 ; goto syntax error b116 = g35 ; goto next command b117 = g36 ; goto exam command b118 = e19 ; integer just read b119 = e20 ; name just read b120 = e8 ; pointer to: last of init code b121 = d19 ; call init write b122 = d20 ; call write char b123 = d21 ; call write text b124 = d23 ; call type line b125 = d42 ; call save work b126 = g47 ; goto input aborted b129 = g11 ; goto catalog error b130 = d79 ; call stack input /, l./h10:;/, d, i/ h10 = k - c11 ; base of core table: /, l./i0:/, r/h10 /h10+c11/, l./i1:/, r/h10. /h10.+c11/, l./se. w2 i0./, r/i0. /h11./, l./g39 ; addr of after initcat/, d1, i/ /, l./h12:/, l./i10:/, l1, i/ ; initialize work table b. j1 w. al. w3 h8. ; j0: ; rep: al w1 x3+c73 ; for all work table entries do rs w1 x3+c58 ; stack pointer := stack base; al w3 x3+c2 ; sh. w3 h9. ; jl. j0. ; e. ; /, l./b.j1/, r/j1/j3/, l./h21/, r/h21. /(j2.)/, l./j0:/, r/c18/c25/, l./c18/, r/c18/c25/, l./h5/, r/h5. /(j3.)/, l./e./, i/ jl. i9. j2: h21 j3: h5 /, l./rl w1 (b6)/, r/ / i9: /, l./rs w0 x1+a18; top address(s) :=/, i/ rs. w0 (4) ; top core := jl. 4 ; e17 ;/, f $catinit ;******************** l./i0=/, r/801124/81 04 06/ l./s.k=k/, r/f40/f50/, l./e5:/, g 2/:>/<0>:>/, l./initialize date/, r/::/using the date command <10> :/, l./;procedure typechar(char)/, d./f0:/, d./f1:/, d./f2:/, d./f4:/, d./i1:/, d./e.;end/, i/ ; procedure type newline ; outputs a newline char on the console ; ; call: w3 = link ; exit: w0 = undef, w1,w2,w3 = unch f3: ; type newline: al w0 10 ; char := newline; ; continue with type char; ; procedure type char ; outputs the given char on the console ; (if the char is <newline>, the buffer is sent) ; ***** note: return inf etc are not saved for reentrant use of this code!!! ; ; call: w0 = char, w3 = link; ; exit: all regs unch f0: ; type char: b. i24 w. ds. w2 i0. ; save regs; ds. w0 i1. ; rl w2 0 ; i10: ; put char: (w0 = w2 = char) jl. w3 f42. ; write char (char); se w2 10 ; if char = newline then jl. i15. ; begin jl. w3 f44. ; type line (buf); jl. w3 f45. ; save work (buf); am ;+2: error: (continue) ; (maybe status-errors ougth to repeat a couple of times ???) jl. w3 f41. ; init write; i15: ; end; dl. w2 i0. ; restore regs; dl. w0 i1. ; jl x3 ; return; ; procedure typetextline (text); ; outputs the text on the console, terminated by a newline char ; call: w1=text addr, w3=link ; exit: w0,w1,w3=unch, w2 = undef f2: ; typetextline: am 10-32 ; char := newline; ; continue with typeout; ; procedure typetext (text); ; outputs the text on the console, terminated by a space ; call: w1=text addr, w3=link ; exit: w0,w1,w3=unch, w2=undef f1: ; typetext: al w2 32 ; char := space; ds. w2 i0. ; save regs; ds. w0 i1. ; jl. w3 f43. ; writetext (text); al w0 x2 ; jl. i10. ; goto put char i0=k+2, 0, 0 ; saved w1,w2 i1=k+2, 0, 0 ; saved w3,w0 e. ; /, l./f5:/, l./al w2 x1+6;/, d, l./al. w2 e6./, d, l./i0:/, d1, i/ i0: ; end with newline: jl. w3 f3. ; type newline; /, l./f6:/, l./al w2 x1+6/, d, l./al. w2 e8./, d, l./jl. i0./, r/;/; goto end with newline;/, l./f8:/, l./i2:/, l./al. w2 e10./, d./jl.w3 f0./, i/ jl. w3 f2. ; type textline (<:input sumerror:>); /, l./f22:/, l./i20:/, l./al w2 x1-2;/, d./jl. i21.;/, l./; procedure insert all entries/, l./j7=k-2/, d, l./j9=k-2/, d, l./j11=k-2/, d, g-3/:>/<0>:>/, l./i20: ; error at output catsegment:/, l./al. w2 j7./, d./jl.w3 f0./, i/ jl. w3 f2. ; type textline (<:repair not possible:>); /, l./i21:/, l./al. w2 j9./, d./jl. w3 f0./, i/ jl. w3 f2. ; type textline (<:update of entry count not possible:>); /, l./i25:/, l./al. w2 j11./, d1, i/ jl. w3 f1. ; typetext (<:insert entry:>); /, l./d38:/, i/ d49: 0, r.4 ; initcat switches: automatic startup area name /, l./e0:/, d, i/ /, l./e9:/, r/,e10=k-2//, l./e11:/, r/,e12=k-2//, l./e13:/, r/,e14=k-2//, l./e15:/, d, l./e17:/, d, g-3/:>/<0>:>/, l./jl.f4.,f4=k-2/, d, i/ jl. f2. , f2 = k-2 /, l./; procedure dismount kit/, l./j6=k-2/, d, l./j8=k-2/, d, g-2/:>/<0>:>/, l./i10:/, l./al. w1 j5./, d./jl. i15./, i/ am j5-j7 ; text := <:delete bs:> /, l./al. w1 j7./, d, r/w2 j8./w1 j7./, l./; procedure mount main catalog/, l./j4=k-2/, d, l./j6=k-2/, d, l./j8=k-2/, d, l./j10=k-2/, d, l./j12=k-2/, d, g-5/:>/<0>:>/, l./i15:/, l./al. w1 j3./, d1, i/ am j3-j5 ; text := <:remove aux entry:>; i17: ; error at connect main catalog: am j5-j9 ; text := <:connect main catalog:>; i19: ; error at create main catalog: al. w1 j9. ; text := <:create aux entry:>; /, l./i17:/, d./jl.i16.;/, l./i18:/, l./al. w1 j7./, d, r/w2 j8./w1 j7./, r/out/ textline/, l./jl. w3 f1./, d./i19:/, d./jl. i16./, i/ jl. w3 f2. ; /, l./i20:/, l./al. w1 j11./, d, r/w2 j12/w1 j11/, r/out/ textline/, l1, r/f1./f2./, l./al w0 10/, d1, l./f35:/, l1, i/ f41: jl. (2),b121; call init write; f42: jl. (2),b122; call write char; f43: jl. (2),b123; call write text; f44: jl. (2),b124; call type line; f45: jl. (2),b125; call save work; f46: jl. (2),b126; goto command aborted; f47: jl. (2),b129; goto catalog error; f48: jl. (2),b130; call stack input; /, l./f40:/, l./rs. w3 j0./, d./j2=k-2/, i/ jl. w1 f2. ; type textline... and return; <:auxcat to be repaired<0>:> /, l./; error in init/, d./e. ;end of scatinit;/, i/ æ12æ ; ********************************************* ; ********************************************* ; ** ** ; ** main control of monitor initialization ** ; ** ** ; ********************************************* ; ********************************************* b. i10 w. i0: f19 ; autoload device controllers i1: f20 ; start up device controllers g0: ; init catalog: jl. w3 f41. ; init write; rl. w0 d36. ; se w0 0 ; if discload then jl. w3 (i0.) ; autoload device controllers; jl. w3 (i1.) ; start up device controller; rl. w0 d36. ; w0 := discload flag; rl. w1 d49. ; w1 := first word of startup area name; se w0 0 ; if not discload sn w1 0 ; or area name <> 0 then jl. i2. ; goto write start header; ; automatic startup is demanded jl. w3 g11. ; call (automatic oldcat); al. w2 d49. ; name := startup area name; jl. w3 f48. ; stack input (name); jl. f31. ; goto next command; i2: am (b4) ; get name of console 2 rl w2 +a199<1 ; dl w1 x2+4 ; ds. w1 e1.+2 ; dl w1 x2+8 ; ds. w1 e1.+6 ; al. w3 e1. ; send output message al. w1 i3. ; jd 1<11+16 ; jd 1<11+18 ; wait answer dont care about the answer and dont check jl. f31. ; i3: 5<12, e19 , e20 0, r.5 ; eight words for answer e. ; ; ************************************************ ; ************************************************ æ12æ /, l./g43:/, l./i5:/, l./dl w1 x3+d61+2/, r/text/textline/, l./al. w2 j5./, d, r/f1/f2/, l./al w0 10/, d1, l./jl. g10./, r/g10/f47/, l./i8:/, l./jl. w3 f5./, l1, r/:>/<0>:>/, l./j5=k-2/, r/j5=k-2/ 0 /, l./g49:/, l./i3:/, l./al. w2 j6./, d, l./jl. w3 i3./, r/w3/ /, l./j6=k-2/, d, g-1/:>/<0>:>/, l./g46:/, l-2, r/:>/<0>:>/, l./j9=k-2/, d, i/ j10: 0,0 ; current command name 0 ; (end of name) j6: 0, 0 ; saved w3,w0 /, l./i5:/, l./al. w1 j8./, d, r/w2 j9/w1 j8/, r/out/ textline/, l1, r/f1/f2/, l1, d1, l./jl. f31. ; goto next command;/, l1, d, l./g54:/, l./g2:/, l./al. w2 e12./, d./al w0 10/, i/ ; type textline (<:input sizeerror:>); /, l./jl. w3 f0./, r/f0/f2/, l./g3:/, l./g5:/, l./rl w0 x1+0;/, d, i/ dl w1 x1+2 ; w0 := first word of command; ds. w1 j10.+2 ; save command; ; cur action := action table; /, l./al. w2 e14./, d, r/f1/f2/, r/out/ textline/, l./ ; create:/, i/ ; local procedure type command; ; ; call: w2=link ; exit: w0,w2,w3=unch, w1=undef f4: ; type command: ds. w0 j6.+2 ; save regs; al. w1 j10. ; jl. w3 f1. ; typetext (command name); dl. w0 j6.+2 ; restore regs; jl x2 ; return; /, l./g35:/, l./jl. g54.;/, l1, i/ e. ; end binin-command /, l./procedure initialize date./, d./i30: 60 ; sec/, d, l./f19:/, l./s24=s22/, l./w.i0:rs.w3 i2./, d./i2:/, i/ w. i0: ; initialize segment: rl. w0 i3. ; initialize (top of initcat code); rs. w0 (i4.) ; rl. w2 i5. ; dl w1 x3-2 ; move initcat switches; ds w1 x2+d37-d36; dl w1 x3-10 ; move startup area name; ds w1 x2+d49+2-d36; dl w1 x3-6 ; ds w1 x2+d49+6-d36; jl (10) ; goto system start; i3: h13 ; top of initcat code i4: b120 ; pointer to ... i5: d36 ; pointer to initcat switches /, l./; segment 10/, l./j0:/, r/;/;x3-4: /, i/ j9: 0, r.4 ;x3-12: init cat switch: startup area name /, l./j1:/, r/;/;x3-2: /, l./i3:/, l./rs. w2 j2./, l1, i/ ; ************* note: uses special knowledge to format of autoboot-program dl w1 30 ; get startup area name from fixed part of autoboot!!! ds. w1 j9.+2 ; dl w1 34 ; ds. w1 j9.+6 ; /, f ▶EOF◀