|
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: 75264 (0x12600) Types: Rc489k_TapeFile, TextFile
└─⟦0d4f5e769⟧ Bits:30008171 MIPS/TS RELEASE 7.1 └─⟦this⟧
! *** ttem *** ; ; ; program for terminal access, terminal multiplexing and terminal spooling ; release 2.2 apr. 1980 knud christensen ; release 2.3 aug. 1982 flemming biggas ; release 3.0 apr. 1983 flemming biggas ; release 3.1 aug. 1984 flemming biggas ; release 4.0 aug. 1985 flemming biggas - (mp + adp3270 release). ; release 5.0 sep. 1986 flemming biggas (tty control ops.) ; release 5.1 nov. 1986 flemming biggas (error correction) ! terminalmodule begin !fp.no; !sections 32; procedure waitmess (.w3.; ! return ! w2); ! abs ref message buffer (return) ! procedure sendwait (.w3.; ! return ! w0 ; ! result (return) ! w1 ; ! abs ref message (call) ! w2); ! abs ref process name (call) ! procedure open (.w3.; ! return ! w0 ; ! number of elements to open (call) ! w2); ! abs ref semaphore (call) ! procedure lock (.w3.; ! return ! w0 ; ! number of elements to lock (return) ! w2); ! abs ref semaphore (call) ! procedure link (.w3.; ! return ! w1 ; ! abs ref queue element (call) ! w2); ! abs ref queue head (call) ! procedure move (.w3.; ! return ! w0 ; ! number of halfwords to move (call) ! w1 ; ! abs ref first halfword to move (call) ! w2); ! abs ref destination (call) ! procedure copy (.w3.; ! return ! w0 ; ! number of halfwords (call/return) ! ! or ! ! -2 stopped ! ! -3 unintel ! w2); ! abs ref first halfword (call) ! procedure create_ph (.w3.; ! return ! ref cp_phhead,cp_psname,cp_sender; w0); ! result (return) 1 = ok , 0 = not ok ! procedure remove_ph (.w3.; ! return ! ref rp_phhead); procedure create_th (.w3.; ! return ! ref ct_thhead,ct_termproc; word ct_type,ct_localid,ct_bufs,ct_timers, ct_mask,ct_subst); procedure remove_th (.w3.; ! return ! ref rt_thhead); procedure init_area (.w3.; ! return ! w1); ! abs ref area description (call) ! procedure connect (.w3.; ! return ! ref con_thhead,con_phhead); procedure disconnect (.w3.; ! return ! ref dis_thhead,dis_phhead); procedure find_ph (.w3.; ! return ! ref fp_psproc,fp_sender; w1); ! result (return) ! ! >0: abs ref ph found ! ! =0: ph not found, no free ph ! ! <0: ph not found, -abs ref free ph ! procedure unintel (.w3.; ! return ! w0); ! status (call) ! procedure wait_op (.w3.; ! return ! w0 ; ! length of operation got ! w1 ; ! abs ref operation got (return) ! w2); ! abs ref area description (call) ! procedure get_op (.w3.; ! return ! w0 ; ! length of operation got (return) ! w1 ; ! abs ref operation got (return) ! w2); ! abs ref area description (call) ! procedure put_op (.w3.; ! return ! w0 ; ! length of operation to put (call) ! w1 ; ! abs ref space for operation (return) ! w2); ! abs ref area description (call) ! procedure swop (.w3.; ! return ! ! a segment buffer is made available. ! ! the referenced segment is copied to ! ! and from bs depending on the mode-bits ! ! described below: ! w2 ; ! bit 21 released after use ! ! (i.e. next call buffer free) ! ! bit 22 the segment is updated ! ! (i.e. buffer will be copied to ! ! bs before releasing) ! ! bit 23 read from bs if segment not is ! ! present ! ! (call parameter) ! w0 ; ! segment no to swop in (call) ! w1); ! abs ref segment in core (return) ! procedure ph (.w3.); ! return (pseudo call) ! procedure th (.w3.); ! return (pseudo call) ! procedure opmess (.w3.; ! return ! w1); ! abs ref message (call) ! procedure init (.w3.); ! return ! procedure testout (.w3.; ! return (call) ! w0 ; ! record length (call) ! w1 ; ! abs ref start of test record (call) ! w2); ! record kind (call) ! label central_wait,wait_next,coru_found,activate,initialize, interrupt,io,gen_answer; record message (ref mess_next,mess_prev,mess_receiver,mess_sender; byte mess_op,mess_mode; ref mess_first,mess_last; word mess_segment,mess_8,mess_10,mess_12,mess_14); record controlmess (ref cm_next,cm_prev,cm_receiver,cm_sender; byte cm_op,cm_mode; word cm_localid; ref cm_tpda; byte cm_bufs,cm_timers; text(11) cm_name); record cm2 (word cm2_1,cm2_2,cm2_3,cm2_4,cm2_5,cm2_6,cm2_7,cm2_8; byte cm_mask,cm_subst); record controlanswer (word ca_status,ca_localid; ref ca_tpda; byte ca_bufs,ca_timers; ref ca_pool; word ca_recfull,ca_bytesfree,ca_dummy2); record coroutine (ref c_next,c_prev,c_mbuf; word c_w0,c_w1,c_w2; ref c_ic; word c_nr,c_ww0,c_ww2,c_ww3; ref a_recfull, a_bytesfree; word a_first, a_top, a_firstfull, a_firstfree); record processhandler (array (1:!length(coroutine)) ph_c of byte; ref ph_parent,ph_child,ph_psproc,ph_dummymess,ph_qreserve; word ph_thincar; ! th.incar.no of current reserver of spoolqueue ! word ph_outcar; ! only used in f8000 links ! ! incarn.no of current output link ! byte ph_sensed,ph_inpmode; word ph_blockused, ph_savew0,ph_savew1); record terminalhandler (array (1:!length(coroutine)) th_c of byte; ref th_parent,th_next,th_buf, th_control; word th_type, ! 0 = tty multiline 2 = tty singleline ! ! 4 termin/termout ! th_ndisplay;! if <> 0 input in mode 8 ! word th_incar, th_localid,th_timercount,th_timermax,th_maxbuf,th_usedbuf, th_mask,th_subst,th_blockused; text(14)th_name; ref th_procdesc); record termbufhead (byte bufm_op,bufm_mode; ref bufm_first,bufm_last; word buf_6,buf_8,buf_10,buf_12,buf_14,buf_status,buf_bytes,buf_chars,buf_result,buf_incar, buf_localid,buf_data1); record semaphore (ref sem_next,sem_prev; word sem_value); record opcom (byte opop,opmode; text(5) optext1; word logstatus; text(11) optext2); record name (double name1,name2); record spoolrec (word seg_no,seg_prio,seg_data); incode word tem; ! process description address of tem ! ref current:=0, event:=0, activqfst,activqlast, answerqfst,answerqlast, waitqfst,waitqlast; ref segpool_fst, segpool_top; word seg_size; ref phpool_fst, phpool_top; word ph_size; ref thpool_fst, thpool_top; word th_size; ref sempool_fst, sempool_top; word sem_size; word testmtop,testbuf:=0,base_event:=0; byte testmop:=5,testmode:=0; ref testmfst,testmlast; word testsegm:=0,maxtestsegm; ref cl_descriptor; double starttime; word gc_func := 4; ref gc_first,gc_last; word gc_rel := 0; word bufl; word ans_status,ans_bytes,ans_chars,ans4,ans5,ans6,ans7,ans8; word bl,localid; byte type, bufs, timers; ref procdescr; ref ph_head, th_head; double xname1, xname2; byte faultop:=2,faultmode:=1; text(20) faulttxt:="***fault"; byte spcomop:=2,spcommode:=8'1001; text(8) spcomtext:="status"; text(14) spoolname:="temspool"; word etx:= 3; ! constant equal to the iso value of etx ! ! may be changed for test purposes ! begin tem:= w3; ! save proc. descr. address ! interrupt: w3:=address(interrupt); w0:= 0; monitor(0); ! set interrupt address ! goto initialize; w1+0; w1+0; w1+0; w1+0; ! fill up interrupt area ! testout(.w3.,w0:=16,w1:=address(interrupt),w2:=15); opmess(.w3.,w1:=address(faultop)); initialize: init(.w3.); ! call init for allocating and initializing buffers, ! ! descriptors, semaphores etc. ! central_wait: w2:= base_event; ! base of event queue ! wait_next: current:=w3:=cl_descriptor; monitor(24); ! wait next event ! if w2=testbuf then begin base_event:= w2; goto wait_next; end; event:=w2; (w3).c_w0:=w0; testout(.w3.,w0:=26,w1:=w2-2,w2:=6); w2:=event; w0:=(w3).c_w0; if w0 = 1 then begin ! an answer has arrived in event queue ! w1:=address(ans_status); monitor(18); ! wait answer (take the answer home) ! w1:=answerqfst; while w3:=address(answerqfst) <> w1 do begin ! scan answer queue to find corresponding sender ! if w2 = (w1).c_mbuf then begin ! activate waiting coroutine ! (w1).c_w0:=w0; goto coru_found; end; w1:=(w1).c_next; end; w1:=phpool_top; while w1-!length(processhandler) >= phpool_fst do begin ! scan process handlers in case of a dummy answer ! if w2 = (w1).ph_dummymess then begin ! the application is removed, so remove terminal group ! w0:=0; (w1).ph_dummymess:=w0; while w2:=(w1).ph_child <> 0 do begin disconnect(.w3.,w2,w1); remove_th(.w3.,w2); end; remove_ph(.w3.,w1); goto central_wait; end; end; goto central_wait; end ! answer ! else begin ! message has arrived in event queue ! if w0:=(w2).mess_op = 3 then begin ! input output ! io: find_ph(.w3.,w0:=(w2).mess_receiver,w0:=(w2).mess_sender,w1); if w1<=0 then unintel(.w3.,w0:=-2); if w0:=(w1).c_mbuf>=0 then goto wait_next; (w1).c_w2:=w2; (w1).c_mbuf:= w2; monitor(26); ! get event ! goto coru_found; end else if w0=5 then goto io else if w0=4 then goto io else if w0=2 then goto io else if w0=0 then goto io else if w0=110 then goto io else if w0=132 then goto io else if w0=134 then goto io else if w0=9 then begin ! simulate input ! ! compute buf length, avoid trunc errors ! w0:=(w2).mess_first; -(w0 ashift -1 ashift 1); w0+(w2).mess_last; if w0<=0 then unintel(.w3.,w0:=-3); if w0>=bufl then unintel(.w3.,w0:=-3); bl:= w0+2; find_ph(.w3.,w0:=(w2).mess_receiver,w0:=(w2).mess_sender,w1); if w1<=0 then unintel(.w3.,w0:=-2); ! ph unknown ! ph_head:= w1; if w1:=(w2).mess_first<=0 then unintel(.w3.,w0:=-3); w3:= 116; w3:=(w3).word; ! no of storage bytes ! if w3<=(w2).mess_last then unintel(.w3.,w0:=-3); ! buf not inside store ! w1:=address(localid); gc_first:=w1;gc_last:=w1; localid:=w0:=-1; comment w2=buffer address; w1:=address(gc_func); monitor(84); w1:=ph_head.ph_child; w3:= 0; while w1>w3 do begin w0:= localid-(w1).th_localid; if w0 or (w1).th_type=0 then ! type=0 and localid ok ! w3:= w1 else w1:= (w1).th_next; end; if w1=0 then unintel(.w3.,w0:=-4); ! th unknown ! procdescr:= w0:= (w1).th_procdescr; type:= w0:= (w1).th_type; bufs:= w0:= (w1).th_maxbuf; timers:= w0:= (w1).th_timermax; disconnect(.w3.,w1,w0:=ph_head); remove_th(.w3.,w1); create_th(.w3.,w1,w3:=procdescr,w3:=type, w3:=localid,w3,=bufs,w3,=timers,w3:=0,w3:=0); connect(.w3.,w1,w3:=ph_head); (w1).th_usedbuf:= w0:= 1; put_op(.w3.,w0:=bl+!position(buf_localid),w1,w2:=w1); (w1).bufm_op:= w0:= 9; (w1).bufm_mode:= w0:= 0; (w1).buf_bytes:= w0:= bl; w2:= address((w1).buf_localid); gc_first:=w2; w2+w0-2; gc_last:=w2; w1:=address(gc_func); w2:=event; monitor(84); ! general copy ! ans_bytes:= w1; ans_chars:= w1+(w2:=w1 ashift -1); end ! simulate input ! else if w0=90 then begin ! create pool ! if w0:=(w2).cm_mode<>0 then unintel(.w3.,w0:=-3); find_ph(.w3.,w0:=-1,w0,w1); ! find free ph ! if w1=0 then unintel(.w3.,w0:=8'0100); -(w1); ph_head:= w1; w1:= address((w2).cm_name); move(.w3.,w0:=8,w1,w2:=address(xname1)); create_ph(.w3.,w0:=ph_head,w2,w0:=(w2:=event).cm_sender,w0); if w0=0 then unintel(.w3.,w0:=8'2000); end ! create pool ! else if w0=92 then begin ! remove pool ! if w0:=(w2).cm_mode<>0 then unintel(.w3.,w0:=-3); move(.w3.,w0:=8,w1:=address((w2).cm_name),w2:=address(xname1)); w2:= event; w3:= address(xname1); monitor(4); ! lookup process ! find_ph(.w3.,w0,w0:=(w2).cm_sender,w1); if w1<=0 then unintel(.w3.,w0:=8'0400); while w2:=(w1).ph_child<>0 do begin disconnect(.w3.,w2,w1); remove_th(.w3.,w2); end; remove_ph(.w3.,w1); end ! remove pool ! else if w0=94 then begin ! lookup pool ! if w0:= (w2).cm_mode<>0 then unintel(.w3.,w0:=-3); move(.w3.,w0:=8,w1:=address((w2).cm_name),w2:=address(xname1)); w2:= event; w3:= address(xname1); monitor(4); ! lookup process ! find_ph(.w3.,w0,w0:=(w2).cm_sender,w1); if w1<=0 then unintel(.w3.,w0:=8'0400); w2:= w1; w1:= address(ans_status); (w1).ca_recfull:= w0:= (w3:=(w2).a_recfull).sem_value; (w1).ca_bytesfree:= w0:= (w3:=(w2).a_bytesfree).sem_value; end ! lookup pool ! else if w0=100 then begin ! create link ! if w0:=(w2).cm_mode and 8'7771<>0 then unintel(.w3.,w0:=-3); ! lookup process description for device ! if w1:=(w2).cm_tpda<=0 then unintel(.w3.,w0:=-3); if w1>current then unintel(.w3.,w0:=-3); ! address not in monitor ! move(.w3.,w0:=8,w1+2,w2:= address(xname1)); w2:= event; w3:= address(xname1); monitor(4); if w0<>(w2).cm_tpda then unintel(.w3.,w0:=8'0004); ! dev. unknown! find_ph(.w3.,w0:=(w2).cm_receiver,w0:=(w2).cm_sender,w1); if w1<=0 then unintel(.w3.,w0:=8'0400); ! ph dont exist ! ph_head:= w1; ! reject if link is known allready or if no free th exist ! w3:= 0; w1:= thpool_top; while w1-!length(terminalhandler)>=thpool_fst do begin if w0:=(w1).th_procdescr=(w2).cm_tpda then unintel(.w3.,w0:=8'0020); if w0=0 then w3:= w1 ! free th ! else begin if w0:=(w1).th_parent=ph_head then if w0:=(w1).th_localid=(w2).cm_localid then unintel(.w3.,w0:=8'1000); end; end; if w3=0 then unintel(.w3.,w0:=8'0040); ! creation is possible ! w0:= w3; create_th(.w3.,w3,w3:=(w2).cm_tpda,w3:=(w2).cm_mode, w3:=(w2).cm_localid,w3,=(w2).cm_bufs,w3,=(w2).cm_timers, w3:=(w2).cm_mask,w3:=(w2).cm_subst); connect(.w3.,w0,w1:=ph_head); end ! create link ! else if w0=102 then begin ! remove link ! if w0:=(w2).cm_mode ashift -1<>0 then unintel(.w3.,w0:=-3); find_ph(.w3.,w0:=(w2).cm_receiver,w0:=(w2).cm_sender,w1); if w1<=0 then unintel(.w3.,w0:=8'0400); ph_head:= w1; w1:= (w1).ph_child; w3:= 0; while w1>w3 do begin if w0:=(w1).th_localid=(w2).cm_localid then w3:= w1 else w1:= (w1).th_next; end; if w1=0 then unintel(.w3.,w0:=8'0200); ! th unknown ! if w0:=(w2).cm_mode=0 then begin ! soft remove ! disconnect(.w3.,w1,w0:=ph_head); put_op(.w3.,w0:=2,w1,w2:=w1); (w1).bufm_op:= w0:= -1; (w1).bufm_mode:= w0:= 2; end else begin ! hard remove ! disconnect(.w3.,w1,w0:=ph_head); remove_th(.w3.,w1); end; end ! remove link ! else if w0=104 then begin ! lookup link ! if w0:=(w2).cm_mode<>0 then unintel(.w3.,w0:=-3); find_ph(.w3.,w0:=(w2).cm_receiver,w0:=(w2).cm_sender,w1); if w1<=0 then unintel(.w3.,w0:=8'0400); w1:= (w1).ph_child; w3:= 0; while w1>w3 do begin if w0:=(w1).th_localid=(w2).cm_localid then w3:= w1 else w1:=(w1).th_next; end; if w1=0 then unintel(.w3.,w0:=8'0200); ! th unknown ! gen_answer: w3:= w1; w1:= address(ans_status); (w1).ca_localid:= w0:= (w3).th_localid; (w1).ca_tpda:= w0:= (w3).th_procdescr; (w1).ca_bufs:= w0:= (w3).th_maxbufs; (w1).ca_timers:= w0:= (w3).th_timermax; if w2:=(w3).th_parent<>0 then (w1).ca_pool:= w0:= (w2).ph_psproc; (w1).ca_recfull:= w0:= (w2:=(w3).a_recfull).sem_value; (w1).ca_bytesfree:= w0:= (w2:=(w3).a_bytesfree).sem_value; end ! lookup link ! else if w0=106 then begin ! lookup term ! if w0:=(w2).cm_mode<>0 then unintel(.w3.,w0:=-3); ! lookup process description for device ! if w1:=(w2).cm_tpda<=0 then unintel(.w3.,w0:=-3); if w1>current then unintel(.w3.,w0:=0); move(.w3.,w0:=8,w1+2,w2:=address(xname1)); w3:=address(xname1); monitor(4); w2:= event; if w0<>(w2).cm_tpda then unintel(.w3.,w0:=8'0004); ! device unknown ! w0:= (w2).cm_tpda; w1:= thpool_fst; w3:= thpool_top; while w1<w3 do begin if w0=(w1).th_procdescr then w3:= w1 else w1+!length(terminalhandler); end; if w1=thpool_top then unintel(.w3.,w0:=8'0200); if w0:=(w3:=(w1).th_parent).ph_parent <> (w2).cm_sender then unintel(.w3.,w0:=8'0020); goto gen_answer; end ! lookup term ! else begin ! operation illegal ! unintel(.w3.,w0:=0); end; ! normal answer ! w2:= event; monitor(26); ! get event ! ans_status:= w0:= 0; w0:= 1; w1:= address(ans_status); monitor(22); ! send answer ! testout(.w3.,w0:=6,w1,w2:=61); goto activate end; ! message ! coru_found: link(.w3.,w1,w2:=address(activqfst)); activate: w1:=address(activqfst); if w3:=(w1).c_next=w1 then goto central_wait; current:= w3; testout(.w3.,w0:=!length(terminalhandler),w1:=current,w2:=11); w0:= (w3).c_w0; w1:= (w3).c_w1; w2:= (w3).c_w2; call w0 current.c_ic; end; ! main program ! body of waitmess begin incode ref return; begin return:=w3; w3:=b.current; (w3).c_w0:=w0; (w3).c_w1:=w1; (w3).c_ic:=w0:=return; w0:= -1; (w3).c_mbuf:= w0; link(.w3.,w1:=w3,w2:=address(b.waitqfst)); testout(.w3.,w0:=!length(coroutine),w1,w2:=62); goto b.activate; end; end; ! waitmess ! body of sendwait begin incode ref return; begin return:=w3; w3:=b.current; (w3).c_w1:=w1; (w3).c_w2:=w2; w3:=w2; w2:=(w2:=b.current).c_nr; monitor(16); ! send message ! w1:=b.current; (w1).c_mbuf:=w2; (w1).c_ic:=w0:=return; link(.w3.,w1,w2:=address(b.answerqfst)); testout(.w3.,w0:=8,w1:=(w3).c_w1,w2:=63); goto b.activate; end; end; ! sendwait ! body of open begin label exit; incode double savef1; word savew2; ref return; begin savef1:=f1; savew2:=w2; return:=w3; (w2).sem_value:=w0+(w2).sem_value; while w1:=(w2).sem_next <> w2 do begin if w0:=(w1).c_w0 > (w2).sem_value then goto exit; (w2).sem_value:=w3:=(w2).sem_value-w0; link(.w3.,w1,w2:=address(b.activqfst)); w2:=savew2; end; exit: f1:=savef1; if w0 > 0 then testout(.w3.,w0:=6,w1:=savew2,w2:=13); f1:=savef1; w2:=savew2; w3:=b.current; call w0 return; end; end; ! open ! body of lock begin incode ref savew3; begin savew3:=w3; w3:=b.current; (w3).c_w0:=w0; (w3).c_w1:=w1; (w3).c_w2:=w2; (w3).c_ic:=w0:=savew3; if w0:=(w3).c_nr < 0 then begin ! called from central logic ! (w2).sem_value:=w1:=(w2).sem_value-(w3).c_w0; w1:=(w3).c_w1; call w0 (w3).c_ic; end else begin link(.w3.,w1:=w3,w2); testout(.w3.,w0:=6,w1:=w2,w2:=12); open(.w3.,w0:=0,w2:=w1); goto b.activate; end; end; end; ! lock ! body of link begin incode double savef1; word savew2; ref return; begin savef1:=f1; savew2:=w2; return:=w3; ! remove queue element from actual queue ! w3:=(w1).c_prev; (w3).c_next:=w0:=(w1).c_next; w3:=(w1).c_next; (w3).c_prev:=w0:=(w1).c_prev; ! link up element as the last element in the queue ! (w1).c_prev:=w3:=(w2).c_prev; (w1).c_next:=w2; (w2).c_prev:=w1; (w3).c_next:=w1; f1:=savef1; w2:=savew2; w3:=b.current; call w0 return; end; end; ! link ! body of move begin incode double savef1; word savew2; ref return; begin savef1:=f1; savew2:=w2; return:=w3; w3:=w1+w0; while w1 < w3 do begin ! move from w1 to w2, one word at a time ! (w2).word:=w0:=(w1).word; w1+2; w2+2; end; f1:=savef1; w2:=savew2; w3:=b.current; call w0 return; end; end; ! move ! body of copy begin label exit; incode word savew1,savew2; ref return; word copy_func; ref copy_first,copy_last; word copy_rel; begin return:=w3; savew1:=w1; savew2:=w2; copy_first:=w2; w2+w0-2;copy_last:=w2; copy_rel:=w0:=0; w3:=b.current; w2:=(w3).c_mbuf; w0:=(w2).mess_op; if w0=3 then w0:=5 else if w0=5 then w0:=4 else begin comment unintelligible; w0:=3; goto exit; end; copy_func:=w0; w1:=address(copy_func); monitor(84); ! general copy ! exit: -(w0); if w0=0 then w0:=w1; ! number of halfwords copied ! w1:=savew1; w2:=savew2; w3:=b.current; call w0 return; end; end; ! end copy ! body of unintel begin label dumdum; begin w2:= b.event; monitor(26); ! get event ! b.ans_status:= w0; if w0=0 then w0:= 3 else if w0<0 then -(w0) else w0:= 1; w1:= address(b.ans_status); monitor(22); ! send answer ! testout(.w3.,w0:=2,w1,w2:=60); goto b.central_wait; end; end; ! unintel ! body of testout begin label close; record dump (word reg0,reg1,reg2,reg3,exreg,instr,cause,sbreg); record testhead (byte reclength,reckind; word time,testref); incode word bufrel:=0; ref return; double savef1; array (1:8) testansw of word; word savew2; byte opcode:=6,opm:=8'1000; text(8) status:= "status"; text(14) testarea:= "temtest"; begin savef1:=f1; savew2:=w2; return:=w3; if w3:=b.testmfst < b.testmlast then begin ! if testbuffer exists then generate testoutput ! if w0+bufrel+(!length(testhead)+2) > 510 then begin ! no room for next record so change buffer ! w3+bufrel; (w3).word:=w0:=-1; if w2:= b.testbuf<>0 then begin b.testbuf:= w1:= 0; b.base_event:= w1; testansw(w1:=1); monitor(18); ! wait answer ! if w2:=1 lshift w0 or (w1).word <> 2 then begin b.testmlast:=w1:=b.testmfst; w1:= address(opcode); (w1).logstatus:=w2; opmess(.w3.,w1); end; end; w1:= address(b.testmop); w3:= address(testarea); monitor(16); ! send message ! b.testbuf:= w2; ! save buffer address ! if w1:=b.testsegm+1 = b.maxtestsegm then w1:=1; b.testsegm:=w1; bufrel:=w0:=0; w1:= b.testmfst;w1+512; if w1>=b.testmtop then w1-1024; b.testmfst:= w1; w1+510;b.testmlast:= w1; end; f1:=savef1; w2:=savew2; w3:=b.testmfst+bufrel; (w3).reclength:=w0+!length(testhead); (w3).reckind:=w2; bufrel:= w1:= bufrel+w0; w1:= b.current; if w1<>0 then w1:=(w1).c_nr; (w3).testref:=w1; w1:=108; f1:=(w1).double-b.starttime lshift -7; (w3).time:=w1; f1:=savef1; move(.w3.,w0,w1,w2:=w3+!length(testhead)); end; w2:=savew2; if w2=15 then begin ! internal interrupt ! w3:=(w1).instr-2; if w0:=(w3).word lshift -18 = 51 ! key store ! then begin ! reestablish registers and continue ! w0:=(w1).instr; return:=w0; w0:=(w1).reg0; w2:=(w1).reg2; w3:=(w1).reg3; w1:=(w1).reg1; call w0 return; end else begin ! output last segment and halt ! close: if w2:= b.testbuf<>0 then begin testansw(w1:=1); monitor(18); b.testbuf:= w2:= 0; end; (w3:=b.testmfst+bufrel).word:=w0:=-2; w3:=address(testarea); w1:=address(b.testmop); monitor(16); ! send message ! monitor(18); ! wait answer ! monitor(10); ! release process ! end; end else if w2 = 64 then goto close else; f1:=savef1; w2:=savew2; w3:=b.current; call w0 return; end; end; ! testout ! body of create_ph begin label ok, testexistence; incode text(14) sendername; byte dummyop:=-2,dummymode:=0; double savef2; ref return; word savew0; begin savef2:=f2; return:=w3; w3:=(w3).cp_psname; monitor(80); ! create pseudo process ! if w0 = 0 then begin monitor(4); ! get process description address ! ok: w1:= return.cp_phhead; (w1).ph_psproc:=w0; (w1).ph_inpmode:= w0:= -1; ! no input received yet ! (w1).ph_parent:=w2:=return.cp_sender; ph(.w3.); ! force process handler into start position ! (w1).c_ic:=w3; link(.w3.,w1,w2:=address(b.activqfst)); init_area(.w3.,w1); move(.w3.,w0:=8,w1:=return.cp_sender+2,w2:=address(sendername)); w3:=w2; w1:=address(dummyop); monitor(16); ! send dummy message to trap removal of process ! w1:=return.cp_phhead; (w1).ph_dummymess:= w2; (w1).ph_thincar:= w0:= 0; savew0:=w0:=1; (w2:=(w1).ph_qreserve).sem_value:= w0; end else begin ! test why pseudo process was not created ! monitor(4); ! get process description ! if w0 > 0 then begin ! the name already did describe a process ! if w3:=b.tem=w0 then ! myself ! goto testexistence; ! test whether it is a pseudo process belonging to tem ! w1:= w0; if w2:=(w1).word=64 then begin ! it is a pseudo process ! w1+10; if w3=(w1).word then begin ! it belongs to tem ! testexistence: w1:= 1; w3:= b.phpool_top; while w3-!length(processhandler)>=b.phpool_fst do begin if w0=(w3).ph_psproc then if w2:=(w3).ph_parent=return.cp_sender then w1:= 0; end; if w1>0 then goto ok; end; end; end; savew0:=w0:= 0; end; testout(.w3.,w0:=!length(processhandler),w1:=return.cp_phhead,w2:=53); w0:=savew0; f2:=savef2; w3:=return; end; end; ! create_ph ! body of remove_ph begin incode double savef1; word savew2; ref return; text(11) psname; begin savef1:=f1; savew2:=w2; return:=w3; w1:=(w3).rp_phhead; if w2:=(w1).c_mbuf > 0 then begin ! answer pending message with result 2 ! w0:=2; monitor(22); ! send answer ! end; open(.w3.,w0:=2000,w2:=(w1).ph_qreserve); ! open for all waiting th's ! init_area(.w3.,w1); w0:=0; (w1).c_mbuf:=w0; (w1).ph_parent:=w0; (w1).ph_child:=w0; w2:=(w1).ph_psproc; (w1).ph_psproc:=w0; (w1).ph_sensed:= w0; (w1).ph_blockused:= w0; (w1).ph_outcar:= w0; if w2 > 0 then begin ! test whether pseudo process is to be removed ! w1:=b.phpool_top; while w1-!length(processhandler) >= b.phpool_fst do begin ! count phs using the same pseudo process ! if w2 = (w1).ph_psproc then w0+1; end; if w0 = 0 then begin ! remove pseudo process ! move(.w3.,w0:=8,w1:=w2+2,w2:=address(psname)); w3:=w2; monitor(64); ! remove process ! end; end; link(.w3.,w1:=return.rp_phhead,w2:=address(b.waitqfst)); if w2:=(w1).ph_dummymess > 0 then begin ! regret dummy message ! monitor(82); ! regret message ! w0:=0; (w1).ph_dummymess:=w0; end; w3:=b.thpool_top; while w3-!length(terminalhandler) >= b.thpool_fst do begin if w1 = (w3).th_parent then begin w0:=0; (w3).th_parent:=w0; end; end; testout(.w3.,w0:=!length(processhandler),w1,w2:=54); f1:=savef1; w2:=savew2; w3:=return; end; end; ! remove_ph ! body of create_th begin incode double savef1; word incar:= 0, savew2; ref return; begin savef1:=f1; savew2:=w2; return:=w3; w1:=(w3).ct_thhead; (w1).th_ndisplay:= w0:= 0; (w1).th_type:= w0:= (w3).ct_type; ! force terminal handler into start position ! th(.w3.); (w1).c_ic:=w3; incar:= w0:= incar+1; (w1).th_incar:= w0; (w1).th_localid:=w0:=(w3:=return).ct_localid; (w1).th_maxbuf:=w0:=(w3).ct_bufs; (w1).th_timermax:=w0:=(w3).ct_timers; (w1).th_mask:= w0:= (w3).ct_mask; (w1).th_subst:= w0:= (w3).ct_subst; (w1).th_procdesc:=w0:=(w3).ct_termproc; w2:=address((w1).th_name); w1:=w0+2; move(.w3.,w0:=8,w1,w2); if w0:=return.ct_type>=4 then begin w3:= w2; monitor(8); ! reserve ! !test 109; end; link(.w3.,w1:=return.ct_thhead,w2:=address(b.activqfst)); init_area(.w3.,w1); testout(.w3.,w0:=!length(terminalhandler),w1,w2:=55); f1:=savef1; w2:=savew2; w3:=return; end; end; ! create_th ! body of remove_th begin incode double savef1,savef3; begin savef1:=f1; savef3:=f3; w1:=(w3).rt_thhead; if w0:= (w2:=(w1).th_control).sem_value < 0 then begin comment pool handler waiting on control lock; open (.w3.,w0:=1, w2); w2:= (w2:=(w1).th_parent).c_mbuf; if w2>0 then begin comment send answer to control message; w0:= 0; (w2:=(w1).th_parent).c_mbuf:= w0; w0:= 4; ! disconnected ! monitor(22); ! send answer ! end; end; f1:= savef1; f3:= savef3; w1:= (w3).rt_thhead; w2:= (w1).th_parent; if w2>0 then if w0:=(w1).th_incar=(w2).ph_thincar then begin ! th reserver of ph's spool queue ! put_op(.w3.,w0:=!length(termbufhead),w1,w2); (w2).ph_thincar:= w0:= 0; open(.w3.,w0:=1,w2:=(w2).ph_qreserve); w0:= 0; (w1).buf_status:= w0; (w1).buf_bytes:= w0; (w1).buf_chars:= w0; (w1).buf_result:= w0:= 4; ! disconnect ! f3:= savef3; w2:= (w3).rt_thhead; w0:= (w2).th_incar; (w1).buf_incar:= w0; end; w1:= (w3).rt_thhead; w0:= 0; (w1).c_mbuf:=w0; (w1).th_parent:=w0; (w1).th_next:=w0; (w1).th_incar:= w0; (w1).th_localid:=w0; (w1).th_timercount:=w0; (w1).th_usedbuf:=w0; (w1).th_blockused:= w0; (w1).th_procdesc:=w0; w3:=address((w1).th_name); monitor(10); ! release terminal ! (w3).word:=w0; link(.w3.,w1,w2:=address(b.waitqfst)); init_area(.w3.,w1); testout(.w3.,w0:=!length(terminalhandler),w1,w2:=56); f1:=savef1; f3:=savef3; end; end; ! remove_th ! body of init_area begin incode double savef1; word savew2; ref return; begin savef1:=f1; savew2:=w2; return:=w3; (w1).a_firstfull:=w0:=(w1).a_first; (w1).a_firstfree:=w0; w2:=(w1).a_bytesfree; w0:=(w1).a_top-(w1).a_first-(w2).sem_value-512; open(.w3.,w0,w2); ! release all occupied bytes ! (w2:=(w1).a_recfull).sem_value:=w0:=0; f1:=savef1; w2:=savew2; w3:=return; end; end; ! init_area ! body of connect begin incode double savef1,savef3; begin savef1:=f1; savef3:=f3; w2:=(w3).con_phhead; w0:=(w2).ph_child; (w2).ph_child:=w1:=(w3).con_thhead; (w1).th_next:=w0; (w1).th_parent:= w2; if w1:=(w2).c_mbuf>0 then begin ! answer pending input or sense operation ! if w0:=(w1).mess_op<=3 then begin put_op(.w3.,w0:=!position(buf_localid),w1,w2); (w1).buf_result:= w0:= 1; (w1).buf_status:= w0:= 0; (w1).buf_bytes:= w0; (w1).buf_chars:= w0; (w1).buf_incar:= w0:= -1; ! end record not existing th ! end; end; f3:= savef3; testout(.w3.,w0:=4,w1:=w3,w2:=57); f1:=savef1; f3:=savef3; end; end; ! connect ! body of disconnect begin label exit; incode double savef1,savef3; begin savef1:=f1; savef3:=f3; w2:=(w3).dis_phhead; w1:=(w2).ph_child; if w1 = (w3).dis_thhead then begin ! disconnect first ph ! (w2).ph_child:=w0:=(w1).th_next; w0:=0; (w1).th_next:=w0; goto exit; end; w2:= w1; while w1:=(w1).th_next<>0 do begin ! scan th chain to find actual one ! if w1 = (w3).dis_thhead then begin ! disconnect th ! (w2).th_next:=w0:=(w1).th_next; w0:=0; (w1).th_next:=w0; goto exit; end; w2:= w1; end; exit: testout(.w3.,w0:=4,w1:=w3,w2:=58); f1:=savef1; f3:=savef3; end; end; ! disconnect ! body of find_ph begin label found; incode word savew0,savew2,freeph; ref return; begin savew0:=w0; savew2:=w2; return:=w3; if w2:=(w3).fp_psproc < 0 then -(w2); freeph:=w0:=0; w1:=b.phpool_top; while w1-!length(processhandler) >= b.phpool_fst do begin if w0:=(w1).ph_parent = (w3).fp_sender then begin if w2 = (w1).ph_psproc then goto found; end else begin if w0 = 0 then freeph:=w1; end; end; -(w1:=freeph); found: w0:=savew0; w2:=savew2; w3:=return; end; end; ! find_ph ! body of wait_op begin incode ref return; begin w1:= b.current; (w1).c_ww2:= w2; (w1).c_ww3:= w3; lock(.w3.,w0:=1,w2:=(w2).a_recfull); open(.w3.,w0,w2); w3:= (w3).c_ww2; swop(.w3.,w2:=1,w0:=(w3).a_firstfull ashift -9,w1); w2:= (w3).c_ww2; w0:= (w2).a_firstfull extract 9; w1+w0; testout(.w3.,w0:=20,w1,w2:=66); w0:= (w1).word-2; w1+2; w2:= (w3).c_ww3; return:= w2; w2:= (w3).c_ww2; call w0 return; end; end; ! wait_op ! body of get_op begin incode word segment; ref rec_ref; ref return; begin w1:= b.current; (w1).c_ww2:= w2; (w1).c_ww3:= w3; lock(.w3.,w0:=1,w2:=(w2).a_recfull); w3:= (w3).c_ww2; segment:= w0:= (w3).a_firstfull ashift -9; swop(.w3.,w2:=1,w0, w1); w2:= (w2:=b.current).c_ww2; w0:= (w2).a_firstfull extract 9; w1+w0; rec_ref:= w1; ! save reference to record ! ! compute new firstfull, if area is empty set firstfull ! ! and firstfree to start of current segment ! w0:= (w2).a_firstfull + (w1).word; if w0<>(w2).a_firstfree then begin w3:= w1+(w1).word; if w3:= (w3).word = -1 then begin ! last record on segment ! w0+512 ashift -9 ashift 9; if w0>=(w2).a_top then w0:= (w2).a_first; (w2).a_firstfull:=w0; open(.w3.,w0:=512,w2:=(w2).a_bytesfree); swop(.w3.,w2:=4,w0:=segment,w1); ! release buffer ! w2:= (w3).c_ww2; end else (w2).a_firstfull:= w0; end else begin (w2).a_firstfull:= w0 ashift -9 ashift 9; (w2).a_firstfree:= w0; swop(.w3.,w2:=4,w0:=segment,w1); ! release buffer ! end; testout(.w3.,w0:=2,w1:=rec_ref,w2:=50); w0:= (w1).word - 2; w1+2; w2:= (w3).c_ww3; return:= w2; w2:= (w3).c_ww2; call w0 return; end; end; ! get_op ! body of put_op begin incode ref return; begin w1:= b.current; (w1).c_ww0:= w0; (w1).c_ww2:= w2; (w1).c_ww3:= w3; lock(.w3.,w0:=512,w2:=(w2).a_bytesfree); w0:=(w1).c_ww0; w2:=(w1).c_ww2; begin ! operation buffer ready ! ! change segment if claim > rest on current segment ! ! else release segment ! w0+2; w1:= (w2).a_firstfree + w0 ashift -9 ashift 9; if w1>(w2).a_firstfree then begin if w1>=(w2).a_top then w1:= (w2).a_first; (w2).a_firstfree:= w1; end else begin open(.w3.,w0:=512,w2:=(w2).a_bytesfree); end; w2:= (w3).c_ww2; if w2:=(w2).a_firstfree extract 9=0 then w2:=2 ! dont swop in ! else w2:= 3; swop(.w3.,w2,w0:=w1 ashift -9,w1); w2:= (w3).c_ww2; w0:= (w2).a_firstfree extract 9; w1+w0; (w1).word:= w0:= (w3).c_ww0 + 2; w3:=w1+w0; (w2).a_firstfree:= w0 + (w2).a_firstfree; (w3).word:=w0:=-1; open(.w3.,w0:=1,w2:=(w2).a_recfull); end; testout(.w3.,w0:=2,w1,w2:=51); w2:= (w3).c_ww3; return:= w2; w0:= (w3).c_ww0; w1+2; w2:= (w3).c_ww2; call w0 return; end; end; ! put_op ! body of swop begin procedure transport(.w3.; w1); ! message address (call) ! incode word savew2; word found; ref wictim, return; byte op, mode; ref first, last; word s_no; word bitmask:= 8'20000000; begin savew2:= w2; return:= w3; found:= w1:= -1; wictim:= w1:= b.segpool_fst; while w1<b.segpool_top do begin w3:= (w1).seg_no extract 22; if w0=w3 then found:= w1; if w3:=(w1).seg_prio<wictim.seg_prio then wictim:= w1; (w1).seg_prio:= w3-1; w1+b.seg_size; end; if w1:= found=-1 then begin ! segment not present ! w1:= address (op); w2:= wictim; first:= w3:= address((w2).seg_data); w3+510; last:= w3; if w3:= (w2).seg_no onemask bitmask then begin ! segment updated, swop out ! op:= w3:= 5; s_no:= w3:= (w2).seg_no extract 22; transport(.w3.,w1); end; if w3:=savew2 onemask 1 then begin ! swop in ! op:= w3:= 3; s_no:= w0; transport(.w3.,w1); end; w1:= wictim; (w1).seg_no:= w0; end; (w1).seg_prio:= w3:= 0; if w3:=savew2 onemask 4 then begin ! release buffer ! (w1).seg_no:= w3:= 8'17777777; ! +infinite ! (w1).seg_prio:= -(w3); ! -infinite ! end else if w3:=savew2 onemask 2 then begin ! set update-segment-mark ! (w1).seg_no:= w3:= bitmask or (w1).seg_no; end else; w1+!position(seg_data); w2:= savew2; w3:= b.current; call w0 return; end; body of transport begin incode word status, bytes, chars, a4, a5, a6, a7, a8; double savef1, savef3; begin savef1:= f1; savef3:= f3; testout(.w3.,w0:=8,w1,w2:=52); w3:= address (b.spoolname); monitor(16); w1:= address(status); monitor(18); if w2:=1 lshift w0 or (w1).word <> 2 then begin w1:=address(b.spcomop); (w1).logstatus:=w2; testout(.w3.,w0:=16,w1,w2:=64); opmess(.w3.,w1); end; f1:= savef1; f3:= savef3; end; end; ! transport ! end; ! swop ! body of ph begin label unint,disconnect,stopped,ans_sense,zero_answer,no_input, loop,loop_stin,nextth,found, adp_found, next_message, tty_found; incode ref return; word mresult, status, bytes, chars, a4:= 0, a5:= 0, a6:= 0, a7:= 0, a8:= 0; word loc_id,outcar,thmask,help; begin return:= w3; call w3 return; ! initial lock ! while w1=w1 do begin waitmess(.w3.,w2); if w0:=(w2).mess_op=0 then begin if w0:=(w2).mess_mode=0 then begin ! sense ! ans_sense: w0:= 1; zero_answer: status:= w1:= 0; bytes:= w1; chars:= w1; w1:= address(status); end else if w0=2 then begin ! sense ready ! (w3).ph_sensed:= w0:= 1; if w0:=(w3).ph_inpmode=-1 then (w3).ph_inpmode:= w0:= 0; w2:=(w3).ph_child; while w2>0 do begin ! send input operations to all free input ! ! buffers owned by ph's childs ! if w0:=(w2).th_usedbuf<(w2).th_maxbuf then begin put_op(.w3.,w0:=!position(buf_chars),w1,w2); (w1).bufm_op:= w0:= 3; (w1).bufm_mode:= w0:= (w3).ph_inpmode; (w1).buf_bytes:= w0:= b.bufl; (w2).th_usedbuf:= w0:= (w2).th_usedbuf+1; end else w2:= (w2).th_next; end; (w3).ph_sensed:= w0:= 1; wait_op(.w3.,w0,w1,w2:=w3); if w0:=(w1).buf_bytes=0 then begin ! status error or stopped ! get_op(.w3.,w0,w1,w2); w3:= (w3).ph_child; while w3>0 do begin if w0:=(w3).th_incar=(w1).buf_incar then begin ! release buffer ! (w3).th_usedbuf:= w0:= (w3).th_usedbuf-1; w3:= 0; end else w3:= (w3).th_next; end; w0:= (w1).buf_result; status:= w1:= (w1).buf_status; w1:= address(status); end else begin ! data ready ! goto ans_sense; end; end ! sense ready ! else goto unint; end ! operation = 0 ! else if w0=3 then begin ! input ! if w0:=(w3).ph_inpmode=-1 then (w3).ph_inpmode:= w0:= (w2).mess_mode; if w0:=(w1:=(w3).a_recfull).sem_value -(w3).ph_sensed=-1 then begin ! no data ,sense read protocol used ! no_input: (w3).ph_sensed:= w0:= 0; goto ans_sense; end else begin w2:= (w3).ph_child; while w2>0 do begin ! send input operations to all free th buffers ! if w0:=(w2).th_usedbuf<(w2).th_maxbuf then begin put_op(.w3.,w0:=!position(buf_chars),w1,w2); (w1).bufm_op:= w0:= 3; (w1).bufm_mode:= w0:= (w3).ph_inpmode; (w1).buf_bytes:= w0:= b.bufl; (w2).th_usedbuf:= w0:= (w2).th_usedbuf+1; end else w2:= (w2).th_next; end; wait_op(.w3.,w0,w1,w2:=w3); (w3).ph_savew0:= w0:= (w1).buf_bytes-(w3).ph_blockused; if w0=0 then begin if w2:=(w3).ph_sensed=1 then goto no_input; end else copy(.w3.,w0,w2:=address((w1).buf_localid)+(w3).ph_blockused); if w0=-2 then goto stopped; if w0=-3 then goto unint; loc_id:= w1; ! save temporary ! testout(.w3.,w0,w1:=w2,w2:=0); w1:= loc_id; if w0=(w3).ph_savew0 then ! last of block copied into ph-owner ! begin !test 508; get_op(.w3.,w0,w1,w2:=w3); w3:= (w3).ph_child; if w0:=(w1).buf_incar >0 then ! last block in record ! while w3>0 do begin if w0=(w3).th_incar then begin ! th found ! (w3).th_usedbuf:= w0:= (w3).th_usedbuf-1; !test 510; w3:= 0; end else w3:= (w3).th_next; end; w3:= b.current; bytes:= w0:= (w3).ph_savew0; w2:= (w3).ph_blockused+(w0:=w2 ashift -1); chars:= w0:= (w1).buf_chars-w2; (w3).ph_blockused:= w0:= 0; end else begin bytes:= w0; chars:= w0+(w2:=w0 ashift -1); (w3).ph_blockused:= w0:= bytes+(w3).ph_blockused; end; a6:= w0:= (w2:=(w3).a_recfull).sem_value; a7:= w0:= (w2:=(w3).a_bytesfree).sem_value; w3:= b.current; status:= w0:= (w1).buf_status; w0:= (w1).buf_result; w1:= address(status); end; end ! input ! else if w0=5 then begin ! output ! ! compute blength avoid trunc errors ! w0:= (w2).mess_first; -(w0 ashift -1 ashift 1); w0+(w2).mess_last; if w0 < 0 then goto unint; if w0>=450 then w0:= 450 else w0+2; (w3).ph_savew0:= w0; outcar:= w0:= (w3).ph_outcar; if w0=0 then begin copy(.w3.,w0:=2,w2:=address(loc_id)); if w0=-2 then goto stopped; if w0=-3 then goto unint; end; w1:= (w3).ph_child; loop: if w1<=0 then goto disconnect; ! receiver unknown ! if w0:=outcar<>0 then begin !test 305; if w0<>(w1).th_incar then goto nextth; end else if w0:=(w1).th_type=0 then begin !test 306; if w0:=loc_id<>(w1).th_localid then goto nextth; end else if w0>=4 then begin if w0:= loc_id lshift -16 and (w1).th_mask<>(w1).th_subst then begin nextth: !test 307; w1:= (w1).th_next; goto loop; end; end else; put_op(.w3.,w0:=(w3).ph_savew0+!position(buf_localid),w1, w2:=w1); thmask:= w0:= 0; if w0:=(w2).th_type=4 then begin if w0:= (w3).ph_outcar=0 then begin thmask:= w0:= (w2).th_mask lshift 16; (w3).ph_outcar:= w0:= (w2).th_incar; end; end; a6:= w0:= (w3:=(w2).a_recfull).sem_value; a7:= w0:= (w3:=(w2).a_bytesfree).sem_value; w3:= b.current; w2:= (w3).c_mbuf; (w1).bufm_op:= w0:= 5; (w1).bufm_mode:= w0:= (w2).mess_mode; w0:= (w3).ph_savew0; copy(.w3.,w0,w2:=address((w1).buf_localid)); (w1).buf_bytes:= w0; ! if no bytes copied the 'putted' operation is changed ! if w0=-2 then goto stopped; if w0=-3 then goto unint; w3:= -1; w3 xor thmask; (w1).buf_localid:= w3 and (w1).buf_localid; testout(.w3.,w0,w1:=w2,w2:=0); status:= w2:= 0; bytes:= w0; chars:= w0+(w2:=w0 ashift -1); if w0:=(w3).ph_outcar<>0 then begin ! test end of record ! w1+bytes-2; w1:= (w1).word; while w1<>0 do begin w0:= 0; f1 lshift 8; if w0=b.etx then w1:= 0; !test 311; end; if w0=b.etx then (w3).ph_outcar:= w0:= 0; end; w0:= 1; w1:= address(status); end ! output ! else if w0=2 then begin ! f8000 control message ! ! message received from application: ! ! mess + 0: 2 shift 12 + operation ! ! mess + 2: if bit 23 then terminal ! ! mess + 4: line,cu,device(physical) ! ! mess + 6: link,cu,device(logical) ! ! mess + 8: local_id (0,cu,device) * ! ! * (used by tem to identify the link) ! loc_id:= w0:= (w2).mess_8; w1:= (w3).ph_child; while w1>0 do begin ! find terminal handler ! if w0:=loc_id lshift -8 and (w1).th_mask=(w1).th_subst then begin if w0:= (w1).th_type=4 then goto found; end; w1:= (w1).th_next; end; goto disconnect; ! not found ! found: put_op(.w3.,w0:=8,w1,w2:=w1); help:= w2; ! save th_ref ! w2:=w1;w1:=address((w1:=(w3).c_mbuf).cm_op); move(.w3.,w0,w1,w2); w1:= help; ! unsave th_ref ! lock (.w3.,w0:=1,w2:= (w1).th_control); ! wait for terminal handler to answer control message ! goto next_message; end ! control message ! else if w0=4 then begin ! f8000 control message (adp3270, see:"rcsl. 991 09910") ! ! message received from application: ! ! mess + 0: 4 shift 12 + operation ! ! mess + 2 ... mess + 10 op. dependant ! ! mess +12: local id (0, cu, device) ! ! *used by tem to identify the link ! loc_id:= w0:= (w2).mess_14; w1:= (w3).ph_child; while w1>0 do begin ! find terminal handler ! if w0:= loc_id lshift -8 and (w1).th_mask = (w1).th_subst then begin if w0:=(w1).th_type = 4 then goto adp_found; end; w1:= (w1).th_next; end; goto disconnect; ! not found ! adp_found:put_op (.w3.,w0:=16,w1,w2:=w1); help:= w2; ! save th_ref ! w2:= w1;w1:= address((w1:=(w3).c_mbuf).cm_op); move (.w3.,w0, w1, w2); w1:= help; ! unsave th_ref ! lock (.w3.,w0:=1,w2:= (w1).th_control); ! wait for terminal handler to answer control message ! goto next_message; end ! end control message (adp) ! else if w0 > 128 then begin ! tty control message ! loc_id:= w0:= (w2).mess_10; w1:= (w3).ph_child; while w1>0 do begin ! find terminal handler ! if w0=(w1).th_localid then begin if w0:= (w1).th_type <> 4 then goto tty_found; end; w1:= (w1).th_next; end; goto disconnect; tty_found:put_op(.w3.,w0:=16,w1,w2:=w1); help:= w2; ! save th ref ! w2:=w1;w1:= address((w1:=(w3).c_mbuf).cm_op); move(.w3.,w0,w1,w2); w1:= help; ! unsave th ref ! lock(.w3.,w0:=1, w2:=(w1).th_control); ! wait for terminal handler to answer control message ! goto next_message; end ! end tty control message ! else if w0=110 then begin ! start input ! w1:= (w3).ph_child; loop_stin: if w1<=0 then goto disconnect; ! receiver unknown ! if w0:=(w1).th_type=0 then w0:= (w2).cm_localid else if w0=2 then w0:= 0 else w0:= (w2).cm_localid lshift -16 lshift 16; if w0<>(w1).th_localid then begin w1:= (w1).th_next; goto loop_stin; end; (w3).ph_savew1:=w0:=(w2).mess_mode; (w3).ph_savew0:= w0:= (w2).cm_bufs; w2:= w1; while w0:=(w3).ph_savew0>0 do begin (w3).ph_savew0:= w0-1; put_op(.w3.,w0:=!position(buf_chars),w1,w2); (w1).bufm_op:= w0:= 3; (w1).bufm_mode:= w0:= (w3).ph_savew1; (w1).buf_bytes:= w0:= b.bufl; (w2).th_usedbuf:= w0:= (w2).th_usedbuf+1; end; goto ans_sense; end else if w0=w0 then begin unint: w0:= 3; goto zero_answer; end else if w0=w0 then begin stopped: w0:= 1; goto zero_answer; end else begin disconnect: w0:= 4; goto zero_answer; end; mresult:= w0; ! save result for testoutput ! ! send answer ! w2:= (w3:=b.current).c_mbuf; monitor(22); w0:= 0; (w3).c_mbuf:= w0; ! clear operation ! testout(.w3.,w0:=18,w1-2,w2:=61); next_message: end; ! for ever ! end; end; ! ph ! body of th begin label ttyloop, next, terminsense, terminput, terminanswer; incode ref return; word nl:= 4'002200000000,sense:=0,senseready:=2,help; begin return:= w3; call w3 return; ! synchronize with terminal (wait untill previous io has terminated) ! sendwait(.w3.,w0,w1:=address(sense),w2:=address((w3).th_name)); while w1=w1 do begin wait_op(.w3.,w0,w1,w2:=w3); if w0:=(w1).bufm_op = 3 then begin ! input ! get_op(.w3.,w0,w1,w2); move(.w3.,w0,w1,w2:=(w3).th_buf); w1:= w2; w0:= (w1).buf_bytes; (w1).bufm_first:= w2:= address((w1).buf_localid); w2+w0-2; (w1).bufm_last:= w2; if w2:=(w3).th_type<=2 then ! tty ! begin w0:= (w3).th_ndisplay; if w0<>0 then begin comment send input in non display mode; (w1).bufm_mode:= w0:= 8; end; w0:= (w1).buf_bytes; if w2:=(w3).th_type=0 then begin ! tty multiline, make room for localid and nl ! (w1).bufm_first:= w2:= address((w1).buf_data1); w2:= (w1).bufm_last; w2-2; (w1).bufm_last:= w2; (w1).buf_localid:= w0:= (w3).th_localid; end; (w3).th_timercount:= w0:= 0; ttyloop: ! send and wait, repeat evt. on timer status ! sendwait(.w3.,w0,w1,w2:= address((w3).th_name)); (w1).buf_result:= w0; if w0<>1 then b.ans_bytes:= w2:= 0; (w1).bufm_first:= w2:= (w1).bufm_first + b.ans_bytes; if w0 or b.ans_status = 2097153 then if w2<=(w1).bufm_last then if w0:=(w3).th_parent>0 then if w0:=(w3).th_timercount+1 <= (w3).th_timermax then begin (w3).th_timercount:= w0; goto ttyloop; end; if w0:=(w3).th_type=0 then begin w2-2; ! terminate datablock with nl ! w0:= (w2).word; if w0=0 then w0:= 1; w1:= 0; next: f1 lshift -8; if w1=0 then goto next; if w1<>nl then begin w2+2; (w2).word:= w1:= nl; end; w2+2; w1:= (w3).th_buf; end; (w1).buf_status:= w0:= b.ans_status; w0:= address((w1).buf_localid) - w2; (w1).buf_bytes:= -(w0); (w1).buf_chars:= w2:= w0 ashift -1 + w0; (w1).buf_incar:= w2:= (w3).th_incar; end else begin goto terminput; terminsense: sendwait(.w3.,w0,w1:=address(senseready),w2:=address((w3).th_name)); if w0<>1 then goto terminput; if w2:=b.ans_status=8'10000000 ! timer ! then if w2:=(w3).th_parent>0 then begin if w2:=(w3).th_timercount+1<=(w3).th_timermax then begin (w3).th_timercount:= w2; goto terminsense; end else goto terminanswer; end; terminput: sendwait(.w3.,w0,w1:=(w3).th_buf,w2:=address((w3).th_name)); terminanswer: w1:= (w3).th_buf; (w1).buf_result:= w0; if w0<>1 then begin b.ans_status:= w0:= 0; b.ans_bytes:= w0; b.ans_chars:= w0; end; if w0 or b.ans_status<>1 then (w1).buf_incar:= w0:= (w3).th_incar else begin if w0:=b.ans_bytes=0 then goto terminsense; ! test presense of etx ! (w1).buf_incar:= w0:= (w3).th_incar; w2:= (w1).bufm_first; w2+b.ans_bytes-2; w0:= (w2).word; while w0<>0 do begin w3:= 0; f0 lshift 8; if w3=b.etx then w0:= 0; end; if w3<>b.etx then (w1).buf_incar:= w0; ! block not end record ! w3:= b.current; end; (w1).buf_status:= w0:= b.ans_status; (w1).buf_bytes:= w0:= b.ans_bytes; (w1).buf_chars:= w2:= b.ans_chars; end; if w2:=(w3).th_parent>0 then begin w1:= w0; ! save temporary ! if w0:= (w2).ph_thincar<>(w3).th_incar then begin lock(.w3.,w0:=1,w2:=(w2).ph_qreserve); if w0:=(w3).th_type=4 then begin w2:= (w3).th_buf; (w2).buf_localid:= w0:= (w3).th_subst lshift 16 or (w2).buf_localid; end; end; w2:= (w3).th_parent; if w2>0 then begin (w2).ph_thincar:= w0:= (w3).th_incar; put_op(.w3.,w0:=w1+!position(buf_localid),w1,w2); w2:= w1; move(.w3.,w0,w1:=(w3).th_buf,w2); if w2:= (w1).buf_incar=0 then ! not end record ! goto terminput else if w2:=(w3).th_parent>0 then begin (w2).ph_thincar:= w0:= 0; open(.w3.,w0:=1,w2:=(w2).ph_qreserve) end else; end; end; end else if w0=5 then begin ! output ! move(.w3.,w0:=!position(buf_chars),w1,w2:=(w3).th_buf); help:= w0:= 0; if w0:=(w3).th_type=0 then w0:= -2 else w0:= 0; w1:= address((w1).buf_localid)-w0; w0+ (w2).buf_bytes-(w3).th_blockused; if w0>b.bufl then ! not last portion of block ! help:= w0:= b.bufl; move(.w3.,w0,w1+(w3).th_blockused, w2:=address((w2).buf_localid)); w1:= (w3).th_buf; (w1).bufm_first:= w2; w2+w0-2; (w1).bufm_last:= w2; w2:=(w1).bufm_mode; if w2 onemask 8 then begin comment next input in non display mode; (w3).th_ndisplay:= w2; w2-8; (w1).bufm_mode:= w2; end else (w3).th_ndisplay:= w2:= 0; if w2:=help=0 then begin ! last portion of block ! (w3).th_blockused:= w2; get_op(.w3.,w0,w1,w2:=w3); end else (w3).th_blockused:= w0+(w3).th_blockused; sendwait(.w3.,w0,w1:=(w3).th_buf,w2:= address((w3).th_name)); end else if w0=2 then begin ! f8000 control message ! get_op(.w3.,w0,w1,w2); move(.w3.,w0,w1,w2:=(w3).th_buf); sendwait (.w3.,w0,w1:=(w3).th_buf,w2:=address((w3).th_name)); w1:= (w3).th_parent; if w1>0 then begin comment send answer to control message; w2:= (w1).c_mbuf; w1:= address(b.ans_status); monitor(22); ! send answer , result in w0 ! open (.w3., w0:=1, w2:=(w3).th_control); end; end ! end f8000 control message ! else if w0=4 then begin ! f8000 control message (adp3270) ! get_op (.w3., w0, w1, w2); move (.w3., w0, w1, w2:= (w3).th_buf); sendwait (.w3.,w0,w1:=(w3).th_buf,w2:=address((w3).th_name)); w1:= (w3).th_parent; if w1>0 then begin comment send answer to control message; w2:= (w1).c_mbuf; w1:= address(b.ans_status); monitor(22); ! send answer , result in w0 ! open (.w3., w0:=1, w2:=(w3).th_control); end; end ! end f8000 control message (adp3270) ! else if w0>128 then begin ! tty control message ! get_op(.w3.,w0,w1,w2); move (.w3.,w0,w1,w2:=(w3).th_buf); w0:= (w2).bufm_op; if w0= 134 then w0:= 2 else ! 134 = 2 ! w0:= 4; ! 132 = 4 ! (w2).bufm_op:= w0; sendwait(.w3.,w0,w1:=(w3).th_buf,w2:=address((w3).th_name)); w1:= (w3).th_parent; if w1>0 then begin comment send answer to control message; w2:= (w1).c_mbuf; w1:= address(b.ans_status); monitor(22); ! send answer ! open(.w3.,w0:=1, w2:=(w3).th_control); end; end ! end tty control message ! else if w0=9 then begin ! simulate input ! get_op(.w3.,w0,w1,w2); move(.w3.,w0,w1,w2:=(w3).th_buf); w1:= (w3).th_buf; (w1).buf_status:= w2:= 0; w2:= (w1).buf_bytes; (w1).buf_chars:= w2 ashift -1 + (w1).buf_bytes; (w1).buf_incar:= w2:= (w3).th_incar; (w1).buf_result:= w2:= 1; if w2:= (w3).th_parent > 0 then begin w1:= w0; lock(.w3.,w0:=1,w2:=(w2).ph_qreserve); w2:= (w3).th_parent; if w2>0 then begin (w2).ph_thincar:= w0:= (w3).th_incar; put_op(.w3.,w0:=w1,w1,w2); w2:=w1; move(.w3.,w0,w1:=(w3).th_buf,w2); if w2:=(w3).th_parent>0 then begin (w2).ph_thincar:= w0:= 0; end; open(.w3.,w0:=1,w2:=(w2).ph_qreserve); end; end; end else begin ! give up ! remove_th(.w3.,w3); goto b.activate; end end ! for ever ! end end; ! th ! body of opmess begin incode double savef1,savef3; text(14) parent; begin savef1:=f1; savef3:=f3; w1:=b.tem+50; move(.w3.,w0:=8,w1:=(w1).word+2,w2:=address(parent)); w3:=w2; f1:=savef1; monitor(16); ! send message to parent ! w1:=address(b.ans_status); monitor(18); ! wait answer ! f1:=savef1; f3:=savef3; end; end; ! opmess ! body of init begin label allocate,initbufs; incode text(14)testarea:="temtest",spoolarea:="temspool"; byte op3:= 16, mode3:= 8'0140; text(14) verstext:= ! *** tem *** ! "release: 5.1"; word ! date of version ! version := 861101, comment ===trimstart; ! date of options ! options := 0, ! number of active terminals ! thcount := 10, ! number of terminal groups ! phcount := 4, ! size of terminal buffer (halfwords) ! termbufsize := 104, ! number of segments in each ph spool area ! phspoolsegm := 8, ! number of segments in each th spool area ! thspoolsegm := 8, ! number of spool segment buffers in core ! spoolbufs := 2, ! size of testoutput area ! testsegmnts := 168, comment ===trimfinis; corucount,spoolpointer:=0; array(1:10) tail of word; ref return, termbufref, semref; byte op1:=16,mode1:=8'40; word alarm; text(14) resource; word stdvalue,margin,bufclaim,stop:=0; text(14)size := "size", area := "area", buf := "buf"; text(20)inittr:=" ***init troubles"; byte op2:=16,mode2:=0; text(20) started:="started"; begin return:=w3; goto allocate; initbufs: f1 lshift -100; for w2:=b.cl_descriptor step 4 upto b.sempool_top do (w2).double:= f1; (w1:=b.cl_descriptor).c_nr:=w0:=-1; w1:= b.phpool_fst; for w3:=1 step 1 upto phcount do begin (w1).c_next:=w1; (w1).c_prev:=w1; (w1).c_nr:=w2:=w3+100; (w1).a_recfull:=w2:=semref; (w2).sem_next:=w2; (w2).sem_prev:=w2; w2+!length(semaphore); (w1).a_bytesfree:=w2; (w2).sem_next:=w2; (w2).sem_prev:=w2; (w2).sem_value:=w0:=phspoolsegm lshift 9; w2+!length(semaphore); (w1).ph_qreserve:= w2; (w2).sem_next:= w2; (w2).sem_prev:= w2; (w2).sem_value:= w0:= 1; w2+!length(semaphore); semref:=w2; (w1).a_first:=w0:=spoolpointer; (w1).a_firstfull:=w0; (w1).a_firstfree:=w0; (w1).a_top:=w0+(w2:=phspoolsegm+1 lshift 9); spoolpointer:=w0; w1+!length(processhandler); end; w1:= b.thpool_fst; for w3:=1 step 1 upto thcount do begin (w1).c_next:=w1; (w1).c_prev:=w1; (w1).c_nr:=w2:=w3+200; (w1).th_buf:=w2:=termbufref; w2+termbufsize+(!length(termbufhead)-4); termbufref:=w2; (w1).a_recfull:=w2:=semref; (w2).sem_next:=w2; (w2).sem_prev:=w2; w2+!length(semaphore); (w1).a_bytesfree:=w2; (w2).sem_next:=w2; (w2).sem_prev:=w2; (w2).sem_value:=w0:=thspoolsegm lshift 9; w2+!length(semaphore); (w1).th_control:= w2; (w2).sem_next:= w2; (w2).sem_prev:= w2; (w2).sem_value:= w0:= 0; w2+!length(semaphore); semref:=w2; (w1).a_first:=w0:=spoolpointer; (w1).a_firstfree:=w0; (w1).a_firstfull:=w0; (w1).a_top:=w0+(w2:=thspoolsegm+1 lshift 9); spoolpointer:=w0; w1+!length(terminalhandler); end; testout(.w3.,w0:=20,w1:=address(version),w2:=69); testout(.w3.,w0:=150,w1:=b.tem-4,w2:=8); w0:= 8'17777777; ! segm not updated , segm.no = +infinite !; w1:=0; w2:=b.segpool_top; while w2-516 >= b.segpool_fst do (w2).double:=f1; call w0 return; allocate: opmess(.w3.,w1:=address(op3)); corucount:=w0:=thcount+phcount; b.activqfst:=w0:=address(b.activqfst); b.activqlast:=w0; b.answerqfst:=w0:=address(b.answerqfst); b.answerqlast:=w0; b.waitqfst:=w0:=address(b.waitqfst); b.waitqlast:=w0; b.segpool_fst:=w1:=address(testarea); b.seg_size:=w0:=516; w0*spoolbufs; w1+w0; b.segpool_top:=w1; termbufref:=w1; w0:= termbufsize; if w0>480 then w0:= 480; b.bufl:= w0;termbufsize:= w0; w0:=(!length(termbufhead)-4)+termbufsize; w0*thcount; w1+w0; b.cl_descriptor:= w1; w1+!length(coroutine); b.phpool_fst:= w1; b.ph_size:=w0:=!length(processhandler); w0*phcount; w1+w0; b.phpool_top:= w1; b.thpool_fst:= w1; b.th_size:=w0:=!length(terminalhandler); w0*thcount; w1+w0; b.thpool_top:= w1; b.sempool_fst:=w1; semref:=w1; b.sem_size:=w0:=!length(semaphore); w0 lshift 1; w0 + !length(semaphore); w0 * corucount; w1+w0; b.sempool_top:=w1; w3:=b.tem+22; f3:=(w3).double; w3-2; w0:= address(b.phpool_fst); (w3).word:= w0; b.testmtop:=w3; if w0:= testsegmnts>0 then begin w3-512; b.testmlast:= w3; w3-510; b.testmfst:= w3; end else begin b.testmlast:= w3; b.testmfst:= w3; end; margin:=w3-w1; if w3 <> 0 then begin w0:=b.testmtop+2; stdvalue:=w0-w2-margin; move(.w3.,w0:=8,w1:=address(size),w2:=address(resource)); if w3:=margin < 0 then begin alarm:=w2:=2763306; ! "***" ! stop:=w2; end else alarm:=w2:=2105376; ! " " ! opmess(.w3.,w1:=address(op1)); end; w3:=b.tem+26; bufclaim:=w1:=(w3).byte; w3+1; w1:=(w3).byte; margin:=w1-phcount-2; if w1 <> 0 then begin stdvalue:=w1:=phcount+2; move(.w3.,w0:=8,w1:=address(area),w2:=address(resource)); if w3:=margin < 0 then begin alarm:=w2:=2763306; ! "***" ! stop:=w2; end else alarm:=w2:=2105376; ! " " ! opmess(.w3.,w1:=address(op1)); end; margin:=w1:=bufclaim-(w2:=phcount lshift 1 + thcount+2); if w1 <> 0 then begin stdvalue:=w2; move(.w3.,w0:=8,w1:=address(buf),w2:=address(resource)); if w3:=margin < 0 then begin alarm:=w2:=2763306; ! "***" ! stop:=w2; end else alarm:=w2:=2105376; ! " " ! opmess(.w3.,w1:=address(op1)); end; w3:=address(spoolarea); monitor(48); ! remove entry ! w2:=thspoolsegm+1*thcount; w1:=phspoolsegm+1*phcount; w2+w1; (tail(w1:=1)).word:=w2; monitor(40); ! create spool area ! w1:=3; monitor(50); ! permanent entry ! monitor(52); ! create area process ! monitor(8); ! reserve area process ! if w0 <> 0 then begin stdvalue:=w2; move(.w3.,w0:=8,w1:=address(spoolarea),w2:=address(resource)); alarm:=w2:=2763306; stop:=w2; opmess(.w3.,w1:=address(op1)); end; w3:=address(testarea); monitor(48); ! remove entry ! (tail(w1:=1)).word:=w2:=testsegmnts; b.maxtestsegm:=w2; if w2 > 0 then begin monitor(40); ! create testoutput area ! w1:=3; monitor(50); ! permanent entry ! monitor(52); ! create area process ! monitor(8); ! reserve area process ! if w0 <> 0 then begin stdvalue:=w2; move(.w3.,w0:=8,w1:=address(testarea),w2:=address(resource)); alarm:=w2:=2763306; stop:=w2; opmess(.w3.,w1:=address(op1)); end; end; if w0:=stop <> 0 then begin ! the resources are not available for start up ! mode1:=w0:=1; op1:=w0:=2; move(.w3.,w0:=14,w1:=address(inittr),w2:=address(alarm)); opmess(.w3.,w1:=address(op1)); end; opmess(.w3.,w1:=address(op2)); w1:=108; b.starttime:=f1:=(w1).double; goto initbufs; end; end; ! init ! end. ▶EOF◀