!* !* OPER37 - 2nd April 1982 * !* !* Communications record format - extant from CHOPSUPE 22A onwards * !* %RECORDFORMAT COMF(%INTEGER OCPTYPE,SLIPL,SBLKS,SEPGS,NDISCS,DLVNADDR, %C (%INTEGER GPCTABSIZE,GPCA %OR %INTEGER DCUTABSIZE,DCUA), %C %INTEGER SFCTABSIZE,SFCA,SFCK,DIRSITE, %C DCODEDA,SUPLVN,TOJDAY,DATE0,DATE1,DATE2, %C TIME0,TIME1,TIME2,EPAGESIZE,USERS,CATTAD,SERVAAD, %C %BYTEINTEGER NSACS,RESV1,SACPORT1,SACPORT0, %C NOCPS,RESV2,OCPPORT1,OCPPORT0,%INTEGER ITINT,CONTYPEA, %C (%INTEGER GPCCONFA %OR %INTEGER DCUCONFA), %C %INTEGER FPCCONFA,SFCCONFA,BLKADDR,RATION, %C (%INTEGER SMACS %OR %INTEGER SCUS), %C %INTEGER TRANS,%LONGINTEGER KMON, %C %INTEGER DITADDR,SMACPOS,SUPVSN,PSTVA,SECSFRMN,SECSTOCD, %C SYNC1DEST,SYNC2DEST,ASYNCDEST,MAXPROCS,INSPERSEC,ELAPHEAD, %C COMMSRECA,STOREAAD,PROCAAD,SFCCTAD,DRUMTAD,TSLICE,FEPS, %C MAXCBT,PERFORMAD,SP1,SP2,SP3,SP4,SP5,SP6, %C LSTL,LSTB,PSTL,PSTB,HKEYS,HOOT,SIM,CLKX,CLKY,CLKZ, %C HBIT,SLAVEOFF,INHSSR,SDR1,SDR2,SDR3, %C SDR4,SESR,HOFFBIT,BLOCKZBIT,BLKSHIFT,BLKSIZE,END) !* %CONSTRECORD(COMF)%NAME COM=X'80000000'!48<<18 !* %CONSTINTEGER SDIAGS=NO; ! YES for cyclic CC trace %IF MONLEVEL>>1&1=YES %START %EXTRINSICLONGINTEGER KMON %OWNINTEGER OPMON; ! copy of KMON bit %CONSTINTEGER KMONNING=YES %FINISH %ELSE %START %CONSTINTEGER KMONNING=NO %FINISH !* %IF MONLEVEL&1=YES %START %CONSTINTEGER VIDEO UPDATING=YES %OWNINTEGER OPER FACILITIES %FINISH %ELSE %START %CONSTINTEGER VIDEO UPDATING=NO %FINISH !* %RECORDFORMAT PF(%INTEGER DEST,SRCE,P1,P2,P3,P4,P5,P6) %RECORDFORMAT MP F(%INTEGER DEST,SRCE,%STRING(23)TXT) !* %EXTERNALROUTINESPEC DUMPTABLE(%INTEGER X,A,S) %EXTERNALROUTINESPEC PON(%RECORD(PF)%NAME P) %EXTERNALROUTINESPEC PKMONREC(%STRING(20)TXT,%RECORD(PF)%NAME P) %EXTERNALROUTINESPEC PARSE COM(%INTEGER SRCE,%STRINGNAME S) %EXTERNALROUTINESPEC RETURN PP CELL(%INTEGER CELL) %EXTERNALINTEGERFNSPEC STOI(%STRINGNAME S) %EXTERNALSTRINGFNSPEC HTOS(%INTEGER N,L) %EXTERNALSTRINGFNSPEC STRINT(%INTEGER I) %IF SSERIES=YES %START %EXTERNALINTEGERFNSPEC REALISE(%INTEGER AD) %FINISH %SYSTEMROUTINESPEC ITOE(%INTEGER A,S) %SYSTEMROUTINESPEC ETOI(%INTEGER A,S) %SYSTEMROUTINESPEC MOVE(%INTEGER S,FROM,TO) %EXTERNALINTEGERFNSPEC NEW PP CELL %EXTRINSICLONGINTEGER PARM DES %ROUTINESPEC DISPLAY TEXT(%INTEGER WHICH,I,J,%STRING(41)TXT) %ROUTINESPEC OPMESS3(%STRING(63)S) !* %RECORDFORMAT BILL F(%INTEGER DEST,SRCE, %C %BYTEINTEGER LINE,POS,ZERO,%STRING(20)TXT) %RECORDFORMAT BUFFER F(%INTEGER STREAM NO, %C EXTERNAL STREAM NO,AMTX,OFFSET,LENGTH, %C REAL ADDRESS,P5,P6,LINK) %OWNRECORD(BUFFER F)%ARRAYFORMAT BUFFERS F(0:4095) %RECORDFORMAT DEVICE ENTRY F(%INTEGER BUFF S, %C X1,X2,X3,X4,X5,X6,X7, %C BUFF A,SCREEN DESC) %RECORDFORMAT IP F(%HALFINTEGER %C IN STRM, IN CELL, IN P2, IN P3, %C OUTSTRM, OUTCELL, OUTP2, OP, %C %INTEGER CURSOR, %C STATE) %RECORDFORMAT PICTURE F(%INTEGER LENGTH,UPDATED,DATA) %RECORDFORMAT PP CELL F(%RECORD(PF) P,%INTEGER LINK) %OWNRECORD(PP CELL F)%ARRAYFORMAT PP CELLS F(0:4095) %IF SSERIES=YES %START %RECORDFORMAT TCBF(%INTEGER COMMAND,STE,LEN,DATAD,NTCB,RESP, %C %INTEGERARRAY PREAMBLE,POSTAMBLE(0:3)) %FINISH %ELSE %START %RECORDFORMAT RCB F(%INTEGER FLAGS,LSTBA,LBS,LBA, %C ALS,ALA,X1,X2) %FINISH %RECORDFORMAT SCREEN F(%INTEGER ID, %C LENGTH, %C HL CURSOR, %C PICTURE A,CURSOR,SIZE,CNTRL, %C %BYTEINTEGER CODE, X, Y, WRITE PENDING) %RECORDFORMAT STREAM F(%HALFINTEGER STREAM NO,%C EXTERNAL STREAM NO, %C %BYTEINTEGER STATE,MODE,ADAPTOR NO,DEVICE NO, %C %INTEGER LENGTH,OWNER,CALLER,AMTX,START,CURSOR,LINK) %OWNRECORD(STREAM F)%ARRAYFORMAT STREAMS F(0:4095) %IF SSERIES=YES %START %RECORDFORMAT UNIT F(%RECORD(TCBF) TCB1,TCB2,TCB3,TCB4, %C %INTEGER BUFFER A,CALLER,READ Q, %C %BYTEINTEGER INPUT ENABLED,INPUT MODE, %C COMMAND PENDING,ENTER PENDING,READ PENDING, %C BUFF STATE,SNO,STATE, %C %STRING(35) PROMPT, %C %STRING(127) INPUT LINE, %C %RECORD(SCREEN F)%ARRAY SCREEN(0:3)) %CONSTINTEGER UREC SPACE=576 %FINISH %ELSE %START %RECORDFORMAT UNIT F(%RECORD(RCB F) RCB, %C %INTEGER ALE0S,ALE0A,ALE1S,ALE1A,ALE2S,ALE2A, %C BUFFER A,CALLER,READ Q, %C %BYTEINTEGER INPUT ENABLED,INPUT MODE, %C COMMAND PENDING,ENTER PENDING,READ PENDING, %C BUFF STATE, %C SNO,STATE, %C %STRING(35)PROMPT, %C %STRING(127)INPUT LINE, %C %RECORD(SCREEN F)%ARRAY SCREEN(0:3)) %CONSTINTEGER UREC SPACE=384 %FINISH %CONSTRECORD(BUFFER F)%ARRAYNAME BUFFERS=PARM0AD %CONSTRECORD(PP CELL F)%ARRAYNAME PP CELLS=PARM0AD %CONSTRECORD(STREAM F)%ARRAYNAME STREAMS=PARM0AD %OWNRECORD(PICTURE F)%NAME OPERLOG %OWNRECORD(PICTURE F)%NAME PROCESS LIST %CONSTINTEGER IPL = 16 %OWNRECORD(IP F)%ARRAY IPS(1:IPL) %OWNINTEGERARRAY RESIDENT PICTURE(0:7) ! 0 OPERLOG ! 1 PROCESS LIST ! 2 SPOOLR ! 3 VOLUMS ! %OWNINTEGERARRAY CONTEXT(0:7) %OWNBYTEINTEGERARRAY OPONOFF(0:7) %CONSTBYTEINTEGER ON=0,OFF=1 !* %IF SSERIES=YES %START %CONSTINTEGER INPUT=0 %CONSTINTEGER OUTPUT=1 %OWNINTEGER SINIT=0 %FINISH %ELSE %START %OWNINTEGER INPUT %OWNINTEGER OUTPUT %FINISH %OWNBYTEINTEGERARRAY SVPICS(0:2047); ! semi temporary home for SPOOLR and VOLUMS pics ! %CONSTINTEGER ATTENTION = 1 %CONSTINTEGER BEING FILLED = 4 %OWNINTEGER CLEAR3 = X'40151515'; ! EBCDIC SP and 3 NLS %CONSTINTEGER COM LIMIT = 1 %CONSTINTEGER COMMAND = X'2000' %CONSTINTEGER COMMANDED = 0 %CONSTINTEGER CONNECTING = 2 %CONSTINTEGER DISCONNECTING = 1 %CONSTINTEGER EBCDIC = 1 %CONSTINTEGER EMPTY = 0 %CONSTINTEGER ENABLING = 7 %CONSTINTEGER ENTER = X'8000' %CONSTINTEGER EXECUTE=X'30000C' %CONSTINTEGER EX REPLY=X'320003' %CONSTINTEGER FFFF=X'FFFF' %CONSTINTEGER FIRST PART = 1 %CONSTINTEGER FULL = 3 %CONSTINTEGER HDR S = 8 %CONSTINTEGER IDLE = 0 %CONSTINTEGER ISO = 0 %OWNINTEGER LAST PROC %OWNINTEGER LAST3C = X'15030000'; ! LINE 21 FOR 3 LINES %OWNINTEGER LINE21C = X'15000000'; ! LINE 21 FOR 1 LINE %CONSTINTEGER NORMAL = 8 %CONSTINTEGER PGB = X'0100' %CONSTINTEGER PGF = X'1000' %CONSTINTEGER PROMPT ISSUED = 3 %CONSTINTEGER READ ISSUED = 1 %CONSTINTEGER REQUESTED = 1 %CONSTINTEGER RESIDENT = 64 %CONSTINTEGER SECOND PART = 2 %CONSTINTEGER SLOW WRITE ISSUED = 4 %CONSTINTEGER STILL BEING FILLED = 5 %CONSTINTEGER TOP BIT = X'80000000' %CONSTINTEGER WRITE ISSUED = 2 !* %CONSTINTEGERARRAY CONTROL WORDS(0:3) = %C X'00140000', X'20180000', X'40180000', X'60180000' ! SCR0 21L SCR1 24L SCR2 24L SCR3 24L ! %IF SSERIES=YES %START %OWNINTEGER INIT DATA=X'0000FF00' %FINISH %ELSE %START %CONSTINTEGERARRAY IN LBE(0:3) = %C X'04F00204', X'84E00100', X'84E00500', X'80E00302' ! READ(ALE2,40 BYTES TO INPUT LINE) INITIALISE WRITE CONTROL(ALE0) WRITE(ALE1) %CONSTINTEGERARRAY OUT LBE(0:3) = %C X'04010800', X'84E00100', X'84E00500', X'80E00302' ! CONNECT INITIALISE etc %FINISH !* %CONSTBYTEINTEGERARRAY BLANKLINE(0:40) = 64(40), 21 %CONSTBYTEINTEGERARRAY MINUSLINE(0:40) = 96(40), 21 %CONSTSTRING(6)%ARRAY OP COMMAND(1:COM LIMIT) = %C "??" %CONSTBYTEINTEGERARRAY KYNL(0:1) = 1,10 %CONSTBYTEINTEGERARRAY SNLS(0:2) = 2,133,133 %OWNSTRING(8)COMMANDP = E"COMMAND:" %CONSTSTRING(4)LPSV = "LPSV" %CONSTSTRINGNAME TIME = X'80C0004B', DATE = X'80C0003F' !* %IF SDIAGS=YES %START %OWNRECORD(PF)%ARRAY CCT BUFFER(0:127) %OWNINTEGER CCTBPTR=0,CCTSEMA=-1 %IF MULTI OCP=YES %START %EXTERNALROUTINESPEC SEMALOOP(%INTEGERNAME SEMA,%INTEGER PARM) %FINISH %ROUTINE CC TRACE(%RECORD(PF)%NAME P); ! TRACE CC ACTIVITY %IF MULTI OCP=YES %START *INCT_CCTSEMA *JCC_8, SEMALOOP(CCTSEMA,0) CCTSEMAGOT: %FINISH CCTBUFFER(CCTBPTR)<-P CCTBPTR=(CCTBPTR+1)&127 %IF MULTI OCP=YES %START; *TDEC_CCTSEMA; %FINISH %END %FINISH !* %ROUTINE DO PON(%RECORD(PF)%NAME P) PON(P) %IF SDIAGS=YES %AND P_DEST>>16=X'37' %THEN CC TRACE(P) %IF KMONNING=YES %START PKMONREC("OPER PONS",P) %IF OPMON=YES %FINISH %END; ! OF DO PON !* %ROUTINE REPLY(%INTEGER DEST,%STRING(63)TXT) %RECORD(PF) Q Q=0 Q_DEST=DEST LENGTH(TXT)=23 %IF LENGTH(TXT)>23 STRING(ADDR(Q_P1))=TXT DO PON(Q) %END; ! OF REPLY !* %ROUTINE REPORT(%STRING(63)TXT) PRINTSTRING("**OPER ".TXT." ") %END; ! OF REPORT !* ! called to sort out contents of a comms ! buffer into an op buffer for display ! I is place after last ch in buffer ! A0 and A1 are first and last addrs in comms buffer ! (which is of of course circular) ! B0 is the start of the op buffer ! LIM is no of lines reqd ! SCREEN_CURSOR = N*(21*41) where N <= 0 ! indicates which frame is required %ROUTINE FORMAT(%INTEGER I,A0,A1,B0,LIM,CURS) %INTEGERARRAY START, FINIS(1:21) %INTEGER N, I0, IL, CH, BL, SIZE %INTEGER C, P, F, F REQD, S, ISTART %INTEGER A, B, L, X, Y %STRING(63)LINE -> START HERE STACK: ! given a line fragment (A,B), not 'NORMALISED', ! records it in START and FINIS arrays, incrementing ! array index N and frame no F (0,1,,,,) A=A-SIZE %IF A>A1 B=B-SIZE %IF B>A1 %IF N>LIM %START F=F+1 ->OUT %IF F>F REQD N=0 %FINISH N=N+1 START(N)=A FINIS(N)=B OUT: *J_%TOS ! END; ! OF STACK SCROLL: ! given a normalised line fragment (START(I),FINIS(I)), ! picks it up, ITOE and store in buffer ! I=1 : last line I=2 : penultimate etc X=START(I) Y=FINIS(I) L=Y-X+1 %IF X<=Y %THEN MOVE(L,X,ADDR(LINE)+1) %ELSE %START L=L+SIZE MOVE(A0+SIZE-X,X,ADDR(LINE)+1) MOVE(Y+1-A0,A0,ADDR(LINE)+(A0+SIZE-X)+1) %FINISH LENGTH(LINE)=L ITOE(ADDR(LINE)+1,L) MOVE(L,ADDR(LINE)+1,B0+BL-41*(I-1)) *J_%TOS ! END; ! OF SCROLL START HERE: SIZE=A1-A0+1; ! size of comms buffer ISTART=I; ! remember for wrapround FREQD=-CURS F=0 LIM=LIM-1 BL=LIM*41 N=0; ! no. of lines found %IF I=A0 %THEN I=A1 %ELSE I=I-1; ! address of last NL NEXT LINE: %IF I=A0 %THEN I=A1 %ELSE I=I-1; ! last ch on line IL=I I0=I; ! 1st ch on line C=0; ! chars on line LOOP: -> FINISHED %IF I=ISTART CH=BYTEINTEGER(I); ! 'PARSE' buffer into line fragments %IF CH=10 %OR CH=0 %START; ! 10=NL, 0=unused buffer ! got a line %IF C>0 %START P=(C-1)//40; ! no. of line fragments-1 A=I0+P*40 B=IL *JLK_; ! last or only fragment ->FINISHED %IF F>F REQD %IF P>0 %START %FOR S=P-1,-1,0 %CYCLE A=I0+S*40 B=I0+S*40+39 *JLK_; ! any remaining fragments ->FINISHED %IF F>F REQD %REPEAT %FINISH %FINISH ->FINISHED %IF CH=0 ->NEXT LINE %FINISH C=C+1 I0=I %IF I=A0 %THEN I=A1 %ELSE I=I-1 ->LOOP FINISHED: MOVE(41,ADDR(BLANKLINE(0)),B0); ! clear op buffer MOVE(BL,B0,B0+41) %RETURN %IF N=0 %FOR I=N,-1,1 %CYCLE *JLK_ %REPEAT %END; ! OF FORMAT !* %ROUTINE CLEAR RESIDENT PICTURE(%INTEGER PICTURE ID) %INTEGER L %INTEGER A A=RESIDENT PICTURE(PICTURE ID) L=INTEGER(A) MOVE(41,ADDR(BLANK LINE(0)),A+HDR S) MOVE(L-41,A+HDR S,A+HDR S+41) %END; ! OF CLEAR RESIDENT PICTURE !* %ROUTINE INIT RESIDENT PICTURES %INTEGER A,B %RECORD(PICTURE F)%NAME PIC %IF SSERIES=YES %THEN A=COM_DCUA %ELSE A=COM_GPCA B=INTEGER(A+43<<2)+2048 PIC==RECORD(B) RESIDENT PICTURE(2)=B PIC_LENGTH=24*41 CLEAR RESIDENT PICTURE(2) PIC==RECORD(B+1024) RESIDENT PICTURE(3)=B+1024 PIC_LENGTH=24*41 CLEAR RESIDENT PICTURE(3) B=INTEGER(A+42<<2); ! addr(process list) PROCESS LIST==RECORD(B) RESIDENT PICTURE(1)=B CLEAR RESIDENT PICTURE(1) B=INTEGER(A+41<<2); ! addr(operlog) RESIDENT PICTURE(0)=B OPERLOG==RECORD(B) %END; ! OF INIT RESIDENT PICTURES !* %EXTERNALROUTINE OPER(%RECORD(PF)%NAME P) %SWITCH FOUND(1:COM LIMIT) %SWITCH ACT(1:19) %INTEGER A %INTEGER A0, A1 %INTEGER B0 %INTEGER BASE %INTEGER CCSTATE %INTEGER CELL %INTEGER CH %INTEGER DACT %INTEGER DEST %INTEGER FLAG %INTEGER I,J %INTEGER IPI %INTEGER L %INTEGER OP %INTEGER PREFIX %INTEGER P1 %INTEGER P2 %INTEGER SCREEN NO %INTEGER SCURSOR %INTEGER STATE %INTEGER STREAM NO %INTEGER TO %STRING(7)X,Y %STRING(40)EBCDICTXT, ISOTXT %OWNSTRING(63)MSG; ! needs to be 'OWN' to write from it %RECORD(PF) Q %RECORD(BILL F)%NAME BILL %RECORD(BUFFER F)%NAME BUFFER %RECORD(DEVICE ENTRY F)%NAME DEVICE ENTRY %RECORD(IP F)%NAME IP %RECORD(MP F)%NAME MP %RECORD(PICTURE F)%NAME PICTURE %RECORD(SCREEN F)%NAME SCREEN %RECORD(STREAM F)%NAME STREAM %RECORD(UNIT F)%NAME U !* ! used to 'FIND PLACE' in IPS array ! and return index. ! called with STRM=0 to find free ! place, >0 to locate specific entry %INTEGERFN FP(%INTEGER STRM) %RECORD(IP F)%NAME IP %INTEGER I %FOR I=1,1,IPL %CYCLE IP==IPS(I) %IF STRM=0 %START %IF IP_OUTSTRM=0 %THEN %RESULT=I %FINISH %ELSE %START %IF STRM=IP_INSTRM %OR STRM=IP_OUTSTRM %C %THEN %RESULT=I %FINISH %REPEAT REPORT("FP fails to find ".STRINT(STRM)) %RESULT=0 %END; ! OF FP !* %ROUTINE TRANSFER REQUEST(%INTEGERNAME CURSOR) SCREEN_CURSOR=CURSOR CURSOR=-1 U_BUFF STATE=BEING FILLED IP==IPS(SCREEN_ID) STREAM==STREAMS(IP_OUT CELL) STREAM_LENGTH=SCREEN_CURSOR+SCREEN_SIZE-1 Q=0 Q_P1=IP_OUT STRM Q_P2=SCREEN_CURSOR Q_SRCE=X'320000' Q_DEST=X'37000A'; ! transfer request DO PON(Q) %END; ! OF TRANSFER REQUEST !* %ROUTINE TRANSFER COMPLETE(%INTEGER STRM,P2,P3,P6) Q=0 Q_P1=STRM Q_P2=P2; ! 1 bit = next page reqd ! 2 bit = page not eligible for recapture ! 4 bit = update users cursor Q_P3=P3; ! no of bytes transferred Q_P5=OP!SCREEN NO<<4 Q_P6=P6; ! no of lines<<24!first line displayed ! or -1 if no longer on display Q_SRCE=X'320000' Q_DEST=X'37000C'; ! transfer complete DO PON(Q) %END; ! OF TRANSFER COMPLETE !* %ROUTINE TELL PICTURE OWNER %RECORD(IP F)%NAME IP %RECORD(STREAM F)%NAME STREAM %RECORD(PF) Q IP==IPS(SCREEN_ID) STREAM==STREAMS(IP_OUT CELL) Q=0 Q_SRCE=X'320008' Q_P1=STREAM_STREAM NO Q_P2=4; ! suspending Q_DEST=X'370004'; ! disable DO PON(Q) Q_P6=-1 Q_DEST=STREAM_OWNER DO PON(Q) %IF U_BUFF STATE>>4=SCREEN NO %THEN U_BUFF STATE=EMPTY %END; ! OF TELL PICTURE OWNER !* %ROUTINE UPDATE OPERLOG(%STRING(63)TXT,%INTEGER MODE) %INTEGER A %IF MODE=ISO %START ISOTXT<-TXT ISOTXT=ISOTXT." " %WHILE LENGTH(ISOTXT)<40 EBCDICTXT=ISOTXT ITOE(ADDR(EBCDICTXT)+1,40) %FINISH %ELSE %START EBCDICTXT<-TXT EBCDICTXT=EBCDICTXT.E" " %WHILE LENGTH(EBCDICTXT)<40 ISOTXT=EBCDICTXT ETOI(ADDR(ISOTXT)+1,40) %FINISH A=RESIDENT PICTURE(0) MOVE(OPERLOG_LENGTH-41,A+HDR S+41,A+HDR S) MOVE(40,ADDR(EBCDICTXT)+1,A+HDR S+OPERLOG_LENGTH-41) OPERLOG_UPDATED=-1 LENGTH(ISOTXT)=LENGTH(TXT); ! remove space pads PRINTSTRING("DT: ".DATE." ".TIME." OPERLOG ".ISOTXT." ") %END; ! OF UPDATE OPERLOG !* %ROUTINE CLEAN %IF LENGTH(MP_TXT)>23 %THEN LENGTH(MP_TXT)=23 ISOTXT=MP_TXT %IF ISOTXT->ISOTXT.(STRING(ADDR(KYNL(0)))).MSG %THEN I=I PREFIX=MP_SRCE>>16 %IF PREFIX0 %THEN TELL PICTURE OWNER SCREEN_ID=TOP BIT!PICTURE ID SCREEN_PICTURE A=A PICTURE==RECORD(A) SCREEN_LENGTH=PICTURE_LENGTH SCREEN_CODE=EBCDIC A=0 %IF PICTURE ID=0 %THEN A=OPERLOG_LENGTH-SCREEN_SIZE SCREEN_CURSOR=A SCREEN_WRITE PENDING=1 %END; ! OF DISPLAY RESIDENT PICTURE !* %ROUTINE FIRE(%INTEGER CHAIN,CONTROL A,SIZE,BUFFER A) %IF SSERIES=YES %START U_TCB1_RESP=0; ! *** protem ? *** U_TCB2_RESP=0 U_TCB3_RESP=0 U_TCB4_RESP=0 U_TCB3_STE=REALISE(CONTROL A&X'FFFC0000')!1 U_TCB3_DATAD=CONTROL A U_TCB4_STE=REALISE(BUFFER A&X'FFFC0000')!1 U_TCB4_LEN=SIZE U_TCB4_DATAD=BUFFER A %FINISH %ELSE %START U_RCB_LBA = CHAIN U_ALE0A = CONTROL A U_ALE1S = SIZE U_ALE1A = BUFFER A %FINISH Q = 0 Q_DEST = EXECUTE Q_SRCE=EX REPLY!OP<<8 %IF SSERIES=YES %START %IF CHAIN=INPUT %THEN Q_P1=ADDR(U_TCB1) %ELSE Q_P1=ADDR(U_TCB2) %FINISH %ELSE Q_P1=ADDR(U_RCB) Q_P2 = U_SNO %IF SSERIES=NO %THEN Q_P3 = X'11'; ! DO STREAM COMMAND + CLEAR ABNORMAL PON(Q) %END; ! OF FIRE !* %ROUTINE DISPLAY PAGE FIRE(OUTPUT,ADDR(SCREEN_CNTRL),SCREEN_SIZE,U_BUFFER A) SCREEN_WRITE PENDING=0 U_STATE=WRITE ISSUED %END; ! OF DISPLAY PAGE !* %ROUTINE PROCESS PAGE %INTEGER RA ! needs BUFFER and IP to be set up %RETURN %IF IP_INSTRM=X'FFFF'; ! lest CC has already freed incell STREAM==STREAMS(IP_INCELL) RA=X'81000000'+BUFFER_REAL ADDRESS A0=RA+STREAM_START B0=U_BUFFER A SCURSOR=A0+STREAM_CURSOR A1=A0+STREAM_LENGTH FORMAT(SCURSOR,A0,A1,B0+17*41,4,IP_CURSOR); ! input bit STREAM==STREAMS(IP_OUTCELL); ! output stream A0=RA+STREAM_START SCURSOR=A0+STREAM_CURSOR A1=A0+STREAM_LENGTH FORMAT(SCURSOR,A0,A1,B0,16,IP_CURSOR); ! output bit MOVE(41,ADDR(MINUSLINE(0)),B0+16*41); ! line to separate input and output MSG=STRINT(100-IP_CURSOR) ITOE(ADDR(MSG)+2, 2) MOVE(2,ADDR(MSG)+2,B0+16*41+38) %END; ! OF PROCESS PAGE !* %ROUTINE QUEUE(%RECORD(PF)%NAME P) CELL=NEW PP CELL PP CELLS(CELL)_P=P PP CELLS(CELL)_LINK=-1 %IF U_READ Q=-1 %THEN U_READ Q=CELL %ELSE %START I=U_READ Q %WHILE PP CELLS(I)_LINK>=0 %CYCLE I=PP CELLS(I)_LINK %REPEAT PP CELLS(I)_LINK=CELL %FINISH %END; ! OF QUEUE !* RETRY: ! start of main program %IF KMONNING=YES %THEN OPMON<-KMON>>X'32'&1 MP==P DEST=P_DEST OP=DEST>>8&7 DACT=DEST&255 P1=P_P1 P2=P_P2 ! filter out OPER 'COMMANDS' %IF DACT=12 %START MSG=MP_TXT ISOTXT=MSG P1=P_SRCE %FOR I=1,1,COM LIMIT %CYCLE -> FOUND(I) %IF MSG->(OP COMMAND(I)).MSG %REPEAT I=STOI(MSG); ! maybe "OPER n ON/OFF" %IF MSG="ON" %THEN P2=2 %C %ELSE %IF MSG="OFF" %THEN P2=-1 %C %ELSE P2=0 %IF 0<=I<8 %AND CONTEXT(I)#0 %AND P2#0 %AND %C ((OPONOFF(I)=ON %AND P2<0) %OR (OPONOFF(I)=OFF %AND P2>0)) %START %IF P2<0 %START; ! reset 'sensitive' fields U==RECORD(CONTEXT(I)) U_CALLER=0 U_BUFF STATE=EMPTY U_STATE=IDLE OPONOFF(I)=OFF %FINISH %ELSE OPONOFF(I)=ON P_DEST=X'A0001'; ! switch tick on/off P_P1=X'32000A'!I<<8 P_P2=P2 DO PON(P) X=" OK" %FINISH %ELSE X=" ??" REPLY(P1,"OPER ".ISOTXT.X) %RETURN FOUND(1): %IF SDIAGS=YES %START %IF MULTI OCP=YES %START *INCT_CCTSEMA *JCC_8, SEMALOOP(CCTSEMA,0) CCTSEMAGOT1: %FINISH J=CCTBPTR %FOR I=0,1,127 %CYCLE PKMONREC("OPER CCTRACE:",CCTBUFFER(J)) J=(J+1)&127 %REPEAT %FINISH PRINTSTRING("OPER IPS:-") DUMPTABLE(-1,ADDR(IPS(1)),24*IPL) %IF SDIAGS=YES %AND MULTI OCP=YES %START; *TDEC_CCTSEMA; %FINISH %RETURN %FINISH ! filter out PARSE COM entries %IF DACT=14 %START PARSE COM(MP_SRCE, MP_TXT) %RETURN %FINISH ! filter out comms controller commands %IF P_SRCE>>16=X'37' %START %IF SDIAGS=YES %THEN CC TRACE(P) %IF KMONNING = YES %START PKMONREC("OPER CCCM",P) %IF OPMON = YES %FINISH %IF DACT=8 %START; ! CC replying to 'DISABLE' for a picture Q=0 Q_SRCE=X'320009' Q_P1=P1 Q_DEST=X'370005'; ! disconnect a picture DO PON(Q) %RETURN %FINISH %RETURN %IF DACT=9; ! CC replying to 'DISCONNECT' STREAM NO=P1&FFFF IPI=-1 CC STATE=-1 %IF P1>>16>0 %START ! low level CC STATE=P2>>24 %IF CC STATE=CONNECTING %START CELL=P_P4 STREAM==STREAMS(CELL) IPI=STREAM_EXTERNAL STREAM NO>>1 %IF IPI=0 %THEN IPI=FP(0) %IF IPI=0 %THEN ->FCCR IP==IPS(IPI) %IF STREAM NO&1>0 %THEN IP_OUTCELL=CELL %AND IP_OUTSTRM=STREAMNO %C %ELSE IP_INCELL=CELL %AND IP_INSTRM=STREAM NO IP_STATE=0 IP_OP=P_P5 IP_CURSOR=0 %FINISH %FINISH %IF IPI<0 %START IPI=FP(STREAM NO) %IF IPI=0 %THEN ->FCCR IP==IPS(IPI) %IF STREAM NO&1>0 %THEN CELL=IP_OUTCELL %ELSE CELL=IP_INCELL STREAM==STREAMS(CELL) %IF CC STATE=ENABLING %AND STREAM NO&1>0 %AND IP_INCELL#0 %START ! 4K max IT buffer for NEWSTARTs %IF STREAM_START+STREAM_LENGTH>4095 %START OPMESS3(" 0/ NEWSTART - IT buffer too large") ->RIP %FINISH %FINISH %FINISH I=STREAM_DEVICE NO&7 %IF OPONOFF(I)=OFF %THEN ->RIP; ! configured off U==RECORD(CONTEXT(I)) SCREEN NO=STREAM_DEVICE NO>>4 ->RIP %UNLESS 0<=SCREEN NO<=3 SCREEN==U_SCREEN(SCREEN NO) ->RIP %IF SCREEN_SIZE=0 %IF DACT=6 %THEN ->GO AHEAD %IF DACT=7 %THEN ->SEND CONTROL RIP: ! release IP record IP=0 FCCR: ! fail CC request P1=P1>>16 %UNLESS P1=0 %START; ! Reply to CC if possible Q=0 Q_DEST=X'370000'!P1 Q_SRCE=DEST Q_P1=STREAM NO Q_P2=-1 DO PON(Q) %FINISH PKMONREC("**OPER CC REQFAIL",P) %RETURN %FINISH ! check/perform initialisation BASE=CONTEXT(OP) %IF BASE=0 %START %IF (SSERIES=YES %AND SINIT=0) %OR %C (SSERIES=NO %AND INPUT=0) %START %IF SSERIES=YES %THEN SINIT=1 %ELSE %START INPUT=ADDR(IN LBE(0)) OUTPUT=ADDR(OUT LBE(1)) %FINISH LAST PROC=COM_MAXPROCS-1 %IF SSERIES=YES %THEN I=COM_DCUA %ELSE I=COM_GPCA INTEGER(I+43<<2)=ADDR(SVPICS(0))-2048 INIT RESIDENT PICTURES %FINISH %IF DACT=2 %START %IF P1=0 %START DEVICE ENTRY==RECORD(P_P3) BASE=DEVICE ENTRY_BUFF A CONTEXT(OP)=BASE U==RECORD(BASE) U=0 U_SNO=P_P2 U_READ Q=-1 U_BUFF STATE=EMPTY %IF SSERIES=YES %START U_TCB1_COMMAND=X'2F404002'; ! read U_TCB1_STE=REALISE(ADDR(U_INPUT LINE)&X'FFFC0000')!1 U_TCB1_LEN=40 U_TCB1_DATAD=ADDR(U_INPUT LINE)+86 U_TCB1_NTCB=ADDR(U_TCB2) U_TCB2_COMMAND=X'2E404081'; ! init U_TCB2_STE=REALISE(ADDR(INIT DATA)&X'FFFC0000')!1 U_TCB2_LEN=4 U_TCB2_DATAD=ADDR(INIT DATA) U_TCB2_NTCB=ADDR(U_TCB3) U_TCB3_COMMAND=X'2E404085'; ! write control U_TCB3_LEN=2 U_TCB3_NTCB=ADDR(U_TCB4) U_TCB4_COMMAND=X'2E004083'; ! write %FINISH %ELSE %START U_RCB_FLAGS=X'00FF4000' U_RCB_LBS=4*4 U_RCB_ALS=3*2*4 U_RCB_ALA=ADDR(U_ALE0S) U_ALE0S=2; ! rest set up by FIRE U_ALE2S=40 U_ALE2A=ADDR(U_INPUT LINE)+86 %FINISH U_BUFFER A=CONTEXT(OP)+UREC SPACE %FOR I=0,1,3 %CYCLE SCREEN NO=I SCREEN==U_SCREEN(I) %IF DEVICE ENTRY_SCREEN DESC>>I&1>0 %START ! screen exists %IF I=0 %START SCREEN_SIZE=21*41 %FINISH %ELSE %START SCREEN_SIZE=24*41 %FINISH SCREEN_HL CURSOR=-1 SCREEN_CNTRL=CONTROL WORDS(I) DISPLAY RESIDENT PICTURE(I&1) %FINISH %REPEAT P=0 P_DEST=X'A0001'; ! clocktick P_P1=X'32000A'!OP<<8 P_P2=2 DO PON(P) %IF SSERIES=YES %THEN FIRE(OUTPUT,ADDR(LAST3C),4,ADDR(CLEAR3)) %C %ELSE FIRE(ADDR(OUT LBE(0)),ADDR(LAST3C),4,ADDR(CLEAR3)) U_STATE=WRITE ISSUED %FINISH %FINISH %ELSE %START REPORT(STRINT(OP)." not initialised") %FINISH %RETURN %FINISH U==RECORD(BASE) %IF DACT=5 %START; ! analyse interrupt response %IF OPONOFF(OP)=OFF %START; ! configured off U_STATE=IDLE %RETURN %FINISH FLAG=P1>>20&15 %IF FLAG&NORMAL#0 %THEN DACT=15 %ELSE %START %IF FLAG=ATTENTION %START %IF P1&ENTER#0 %THEN DACT=16 %ELSE %C %IF P1&COMMAND#0 %THEN DACT=17 %ELSE %C %IF P1&PGF#0 %START DACT=18 P1=1 P2=0 %FINISH %ELSE %START %IF P1&PGB#0 %START DACT=18 P1=-1 P2=0 %FINISH %FINISH %FINISH %FINISH %FINISH !* %IF KMONNING=YES %START PKMONREC("OPER gets:",P) %IF OPMON =YES %FINISH !* %IF DACT=5 %START REPORT(STRINT(OP)." abnormal termination") ->NOW IDLE %FINISH !* ->ACT(DACT) !* ACT(9): %RETURN !* ACT(*): ->HELP !* ACT(1): ! provide DIRECT with ex strm no ! director uses n & n+1 for the input and output streams Q=0 Q_DEST=P_SRCE Q_SRCE=DEST I=FP(0); ! find free record %IF I=0 %THEN ->HELP; !*JM* ->none free IP==IPS(I) IP=0 IP_OUTSTRM=1; ! in use Q_P1=I<<1 DO PON(Q) %RETURN !* ACT(3): ! execute failure REPORT(STRINT(OP)." fire fails P1=".STRINT(P1)) ->NOW IDLE !* ACT(4): ! set OPER facilities bits %IF VIDEO UPDATING=YES %START OPER FACILITIES=P1 %FINISH %RETURN !* ACT(11): LENGTH(ISOTXT)=36 MOVE(36,P_P1,ADDR(ISOTXT)+1) RETURN PP CELL(P_P2) ->ACT7B !* ACT(13): PREFIX=P_SRCE>>16 %IF PREFIXACT7A !* ACT(7): ! write line to operlog CLEAN ACT7A: ISOTXT=STRINT(PREFIX)."/ ".ISOTXT %IF PREFIX<10 %THEN ISOTXT=" ".ISOTXT ACT7B: UPDATE OPERLOG(ISOTXT,ISO) ->LOOK FOR WORK !* ACT(6): ! PON for display text BILL==P %IF BILL_ZERO=255 %START; ! clear relevant picture %IF BILL_LINE<72 %THEN CLEAR RESIDENT PICTURE(3) %C %ELSE CLEAR RESIDENT PICTURE(2) %FINISH DISPLAY TEXT(0,BILL_LINE,BILL_POS,BILL_TXT) ->LOOK FOR WORK !* ACT(8): ! request input %UNLESS U_CALLER=0 %THEN QUEUE(P) %ELSE %START U_CALLER=P_SRCE CLEAN LENGTH(ISOTXT)=15 %IF LENGTH(ISOTXT)>15 MSG=ISOTXT." from ".STRINT(PREFIX).STRING(ADDR(SNLS(0))) ITOE(ADDR(MSG)+1,LENGTH(MSG)) U_PROMPT=MSG U_READ PENDING=2 %FINISH ->LOOK FOR WORK !* ACT(15): ! normal termination STATE=U_STATE %IF STATE=IDLE %START REPORT(STRINT(OP)." spurious termination") ->HELP %FINISH ->NOW IDLE %IF STATE=WRITE ISSUED ->NOW IDLE %IF STATE=SLOW WRITE ISSUED %IF STATE=PROMPT ISSUED %START U_INPUT ENABLED=1 %UNLESS U_INPUT MODE=REQUESTED %THEN -> NOW IDLE !* a NEWSTART prompt - I think!! SCREEN==U_SCREEN(0) %IF SCREEN_ID>0 %THEN TELL PICTURE OWNER %AND SCREEN_ID=0; !*JM* DISPLAY PAGE %RETURN %FINISH %IF STATE=READ ISSUED %START U_INPUT ENABLED=0 L=40 %IF SSERIES=YES %THEN A=U_TCB1_DATAD-1 %ELSE A=U_ALE2A-1 %FOR I=1,1,40 %CYCLE %IF BYTEINTEGER(A+I)=X'1D' %START; ! EBCDIC NL L=I-1 %EXIT %FINISH %REPEAT BYTEINTEGER(A)=L MSG=STRING(A) ETOI(A+1,L) %IF U_INPUT MODE=COMMANDED %START U_INPUT LINE=U_INPUT LINE.STRING(A) L=LENGTH(U_INPUT LINE) %IF 0>16-RESIDENT)&LAST PROC MSG=STRINT(PREFIX)."< ".STRING(A) MSG=" ".MSG %IF PREFIX<10 UPDATE OPERLOG(MSG,ISO) MSG=STRING(A)." " %CYCLE MP_TXT<-MSG DO PON(MP) PKMONREC("To caller:",MP) L=LENGTH(MSG)-23 %EXIT %UNLESS L>0 LENGTH(MSG)=L MOVE(L,ADDR(MSG)+24,ADDR(MSG)+1) %REPEAT %FINISH U_CALLER=0 %FINISH %FINISH ->NOW IDLE !* ACT(16): ! ENTER key %IF U_INPUT ENABLED>0 %THEN U_ENTER PENDING = 1 ->LOOK FOR WORK !* ACT(17): ! COMMAND key %IF U_STATE=PROMPT ISSUED %START %UNLESS U_INPUT MODE=COMMANDED %START U_COMMAND PENDING=1 U_READ PENDING=U_INPUT MODE %FINISH %FINISH %ELSE %START %IF U_INPUT ENABLED=0 %START U_COMMAND PENDING=1 %FINISH %ELSE %START %UNLESS U_INPUT MODE=COMMANDED %START U_COMMAND PENDING=1 U_READ PENDING=U_INPUT MODE %FINISH %FINISH %FINISH ->LOOK FOR WORK !* ACT(18): ! PGF or PGB %RETURN %UNLESS 0<=P2<=3 SCREEN==U_SCREEN(P2) %RETURN %IF SCREEN_SIZE=0 %IF SCREEN_ID>>28=X'C' %START IPI=SCREEN_ID&255 IP==IPS(IPI) %IF IP_STATE&4=0 %START IP_STATE=IP_STATE!4; ! set PGF/PGB bit SCURSOR=IP_CURSOR+P1 %IF SCURSOR>0 %THEN SCURSOR=0 IP_CURSOR=SCURSOR %FINISH %FINISH %ELSE %START SCURSOR=SCREEN_CURSOR+P1*SCREEN_SIZE %IF SCURSOR<0 %THEN SCURSOR=0 %IF SCURSOR+SCREEN_SIZE>SCREEN_LENGTH %THEN SCURSOR=SCREEN_LENGTH-SCREEN_SIZE %UNLESS SCURSOR=SCREEN_CURSOR %START %IF SCREEN_ID<0 %THEN SCREEN_WRITE PENDING=1 %C %AND SCREEN_CURSOR=SCURSOR %ELSE %START IP==IPS(SCREEN_ID) Q=0 Q_P1=IP_OUTSTRM Q_P6=SCURSOR//41 Q_DEST=STREAMS(IP_OUTCELL)_OWNER Q_SRCE=X'320000' DO PON(Q) %FINISH %FINISH %FINISH ->LOOK FOR WORK !* ACT(19): ! show picture,screen %RETURN %UNLESS 0<=P2<=3 SCREEN==U_SCREEN(P2) %RETURN %IF SCREEN_SIZE=0 %IF P1<0 %START %IF LPSV->X.(STRING(ADDR(P_P3))).Y %THEN P1=LENGTH(X) %FINISH DISPLAY RESIDENT PICTURE(P1) ->LOOK FOR WORK !* SEND CONTROL: ! message from comms controller %IF CC STATE<0 %START ! high level %IF STREAM_EXTERNAL STREAM NO=0 %START ! picture %RETURN %IF SCREEN_HL CURSOR>=0; ! previous call still being processed I=P_P6*41; ! check/make P6 sensible %IF I<0 %THEN I=0 %ELSE %C %IF I+SCREEN_SIZE>SCREEN_LENGTH %THEN I=SCREEN_LENGTH-SCREEN_SIZE SCREEN_HL CURSOR=I %FINISH %ELSE %START ! interactive process, input or output request %IF STREAM NO&1=0 %START IP_INP2=P2 IP_INP3=P_P3 IP_STATE=IP_STATE!1 %FINISH %ELSE %START STREAM_CURSOR=P2 Q=0 Q_SRCE=DEST %IF P_SRCE&255=18 %START Q_DEST=STREAM_OWNER Q_P5=P2 %FINISH %ELSE %START Q_DEST=P_SRCE Q_P1=STREAM NO Q_P2=0 %FINISH DO PON(Q) IP_STATE=4 %IF IP_STATE=0; ! display if idle %FINISH %FINISH %FINISH %ELSE %START ! low level %IF CC STATE=DISCONNECTING %START %IF STREAM NO&1#0 %THEN IP=0 %ELSE IP_INSTRM=X'FFFF' %FINISH %ELSE %START %IF STREAM_EXTERNAL STREAM NO=0 %START ! picture %IF CC STATE=CONNECTING %START %IF SCREEN_ID>0 %THEN TELL PICTURE OWNER SCREEN_ID=IPI %FINISH %ELSE %START %IF CC STATE=ENABLING %START SCREEN_CODE=STREAM_MODE>>4 SCREEN_LENGTH=STREAM_LENGTH+1 %FINISH %FINISH %FINISH %FINISH Q=0 Q_P1=STREAM NO Q_SRCE=DEST Q_DEST=X'370000'!P1>>16; ! reply DO PON(Q) %FINISH ->LOOK FOR WORK !* GO AHEAD: ! picture now available ! P2 = buffer no BUFFER==BUFFERS(P2) %IF STREAM_EXTERNAL STREAM NO=0 %START ! picture %IF BUFFER_LENGTH=SCREEN_SIZE %THEN STATE=FULL %ELSE %START %IF U_BUFF STATE=BEING FILLED %THEN STATE=FIRST PART %C %ELSE STATE=SECOND PART %FINISH U_BUFF STATE=STATE!SCREEN NO<<4 %FINISH %ELSE %START ! interactive process I=IP_STATE IP_STATE=I&X'F0F'!((I&X'F0')<<4) %FINISH ->LOOK FOR WORK !* HELP: PKMONREC("OPER help",P) %RETURN !* ACT(10): ! mark process list updated INTEGER(RESIDENT PICTURE(1)+4)=-1 ->LOOK FOR WORK !* NOW IDLE: U_STATE=IDLE LOOK FOR WORK: %IF OPONOFF(OP)=OFF %START; ! configured off %IF OP=0 %START; ! find pseudo 'MAIN' OPER %FOR I=1,1,7 %CYCLE %IF OPONOFF(I)=ON %AND CONTEXT(I)#0 %START U==RECORD(CONTEXT(I)) ->NEWMAIN %FINISH %REPEAT %FINISH %RETURN NEWMAIN: %FINISH %UNLESS U_STATE=IDLE %THEN %RETURN %IF U_ENTER PENDING>0 %START; ! deal with 'ENTER' U_ENTER PENDING=0 FIRE(INPUT,ADDR(LAST3C),4,ADDR(CLEAR3)) U_STATE=READ ISSUED %RETURN %FINISH %IF U_COMMAND PENDING>0 %START; ! deal with 'COMMAND' U_COMMAND PENDING=0 U_STATE=PROMPT ISSUED U_INPUT MODE=COMMANDED U_INPUT LINE="" FIRE(OUTPUT,ADDR(LINE21C),LENGTH(COMMANDP),ADDR(COMMANDP)+1) %RETURN %FINISH %IF U_CALLER=0 %AND U_READQ>=0 %START ! no read in progress but one queued CELL=U_READ Q U_READ Q=PP CELLS(CELL)_LINK P=PP CELLS(CELL)_P RETURN PP CELL(CELL) ->RETRY %FINISH ACT10A: %IF U_READ PENDING>0 %AND U_INPUT ENABLED=0 %START U_INPUT MODE=U_READ PENDING U_READ PENDING=0 U_STATE=PROMPT ISSUED FIRE(OUTPUT,ADDR(LINE21C),LENGTH(U_PROMPT),ADDR(U_PROMPT)+1) %IF U_INPUT MODE=REQUESTED %AND U_CALLER#0 %START IP==IPS(U_CALLER) STREAM==STREAMS(IP_INCELL); ! input stream BUFFER==BUFFERS(STREAM_LINK) SCREEN==U_SCREEN(0) PROCESS PAGE %FINISH %RETURN %FINISH %UNLESS U_BUFF STATE=EMPTY %START STATE=U_BUFF STATE&15 %UNLESS STATE>=BEING FILLED %START; ! being filled or still being filled SCREEN NO=U_BUFF STATE>>4 SCREEN==U_SCREEN(SCREEN NO) IPI=SCREEN_ID IP==IPS(IPI) STREAM==STREAMS(IP_OUTCELL) BUFFER==BUFFERS(STREAM_LINK) I=X'81000000'+BUFFER_REAL ADDRESS+BUFFER_OFFSET TO=U_BUFFER A %IF STATE=SECOND PART %THEN TO=TO+SCREEN_SIZE-BUFFER_LENGTH MOVE(BUFFER_LENGTH,I,TO) %IF STATE=FIRST PART %START TRANSFER COMPLETE(IP_OUTSTRM,1,BUFFER_LENGTH,0) U_BUFF STATE=U_BUFF STATE&X'F0'+STILL BEING FILLED %FINISH %ELSE %START ITOE(U_BUFFER A,SCREEN_SIZE) %IF SCREEN_CODE=ISO DISPLAY PAGE U_BUFF STATE=EMPTY TRANSFER COMPLETE(IP_OUTSTRM,4,0,(SCREEN_SIZE//41)<<24!(SCREEN_CURSOR//41)) %FINISH %FINISH %RETURN; ! either displaying or awaiting second part %FINISH %FOR I=0,1,3 %CYCLE SCREEN NO=I SCREEN==U_SCREEN(I) %UNLESS SCREEN_SIZE=0 %START %IF SCREEN_ID>>28=8 %START PICTURE==RECORD(SCREEN_PICTURE A) A=1<<(OP<<2+I) %IF PICTURE_UPDATED&A>0 %OR SCREEN_WRITE PENDING>0 %START PICTURE_UPDATED=PICTURE_UPDATED&(\A) MOVE(SCREEN_SIZE,SCREEN_PICTURE A+SCREEN_CURSOR+HDR S,U_BUFFER A) DISPLAY PAGE U_STATE=SLOW WRITE ISSUED %RETURN %FINISH %FINISH %ELSE %START %IF SCREEN_ID>0 %START %IF SCREEN_HL CURSOR>=0 %START TRANSFER REQUEST(SCREEN_HL CURSOR) %RETURN %FINISH %FINISH %FINISH %FINISH %REPEAT %FOR IPI=1,1,IPL %CYCLE IP==IPS(IPI) U==RECORD(CONTEXT(IP_OP&7)) SCREEN==U_SCREEN(IP_OP>>4) STATE=IP_STATE %IF STATE&X'F0'=0 %AND STATE#0 %START ! no transfer in progress %IF STATE&X'F00'>0 %START ! some transfer completed %IF STATE&X'100'>0 %START ! an input transfer %IF U_CALLER=0 %START %IF SCREEN_ID>0 %THEN TELL PICTURE OWNER SCREEN_ID=X'C0000000'+IPI U_CALLER=IPI BUFFER==BUFFERS(STREAMS(IP_INCELL)_LINK) STREAM==STREAMS(IP_OUTCELL); ! output stream A0=X'81000000'+BUFFER_REALADDRESS+STREAM_START A1=A0+STREAM_LENGTH SCURSOR=A0+STREAM_CURSOR; ! first CH of prompt message L=A0+IP_INP2; ! last CH+1 I=1 %CYCLE %EXIT %IF SCURSOR=L CH=BYTEINTEGER(SCURSOR) %UNLESS CH=10 %THEN BYTEINTEGER(ADDR(MSG)+I)=CH %C %AND I=I+1 %IF SCURSOR=A1 %THEN SCURSOR=A0 %C %ELSE SCURSOR=SCURSOR+1 %EXIT %IF I>20 %REPEAT LENGTH(MSG)=I-1 U_PROMPT=MSG." from ". %C STRINT((STREAM_OWNER>>16-RESIDENT)&LASTPROC). %C STRING(ADDR(SNLS(0))) %IF KMONNING=YES %START PRINTSTRING("OPER PRMT ".U_PROMPT) %IF OPMON=YES %FINISH ITOE(ADDR(U_PROMPT)+1,LENGTH(U_PROMPT)) U_READ PENDING=1 IP_STATE=STATE&X'EF3'; ! clear input transfer complete ->ACT10A %IF U_STATE=IDLE %FINISH %FINISH %ELSE %START ! PGF/B transfer complete %IF U_STATE=IDLE %START STREAM==STREAMS(IP_OUTCELL) %IF SCREEN_ID=X'C0000000'+IPI %C %AND STREAM_MODE&X'30'#X'30' %START ! on display & not control mode BUFFER==BUFFERS(STREAM_LINK) PROCESS PAGE DISPLAY PAGE %FINISH %IF STATE&X'400'>0 %START ! PG/B complete TRANSFER COMPLETE(IP_OUTSTRM,0,0,0) IP_STATE=STATE&X'3F3' %FINISH %FINISH %FINISH %FINISH %ELSE %START %IF STATE&X'F'>0 %START ! transfer requested %IF STATE&1>0 %START STATE=STATE&X'FF0'!X'10' STREAM NO=IP_INSTRM %FINISH %ELSE %START STATE=STATE&X'FF0'!X'40' STREAM NO=IP_OUTSTRM %FINISH IP_STATE=STATE Q=0 Q_P1=STREAM NO Q_SRCE=X'320000' Q_DEST=X'37000A'; ! transfer request DO PON(Q) %FINISH %FINISH %FINISH %REPEAT !* %RETURN !* %END; ! OF OPER !* %EXTERNALROUTINE DISPLAY TEXT(%INTEGER WHICH,I,J,%STRING(41)TXT) %INTEGER OP,U,R %RECORD(PF) P %RETURN %UNLESS 0<=J<=39 %RETURN %UNLESS LENGTH(TXT)>0 %IF LENGTH(TXT)>40-J %THEN LENGTH(TXT)=40-J ITOE(ADDR(TXT)+1,LENGTH(TXT)) R=1 ->SKIP LINE CHECK %IF WHICH<0 %RETURN %UNLESS 0<=I<=95 %IF I>47 %START I=I-48 %IF I<24 %THEN R=3 %ELSE R=2 %AND I=I-24 %FINISH SKIP LINE CHECK: MOVE(LENGTH(TXT),ADDR(TXT)+1,RESIDENT PICTURE(R)+HDR S+41*I+J) %IF VIDEO UPDATING=YES %START %IF OPER FACILITIES&1>0 %START %IF R=1 %START; ! keep process list display up to date U=PROCESS LIST_UPDATED P=0 %FOR OP=0,1,7 %CYCLE %UNLESS U&15=15 %THEN P_DEST=X'32000A'!OP<<8 %C %AND DO PON(P) U=U>>4 %REPEAT %FINISH PROCESS LIST_UPDATED=-1 %FINISH %FINISH %UNLESS R=1 %THEN INTEGER(RESIDENT PICTURE(R)+4)=-1; ! mark relevant picture 'UPDATED' %END; ! OF DISPLAY TEXT !* %EXTERNALROUTINE OPMESS3(%STRING(63)TXT) %STRING(36)T %RECORD(PF) Q %INTEGER CELL, CELL A Q=0 Q_DEST=X'32000B' T<-TXT T=T." " %WHILE LENGTH(T)<36 CELL=NEW PP CELL CELL A=ADDR(PP CELLS(CELL)) MOVE(36,ADDR(T)+1,CELL A) Q_P1=CELL A Q_P2=CELL DO PON(Q) %END; ! OF OPMESS3 !* %ENDOFFILE