!*
!* Communications record format - extant from CHOPSUPE 22B onwards *
!*
RECORDFORMAT  CDRF(BYTEINTEGER  IPDAPNO,DAPBLKS,DAPUSER,DAPSTATE, C 
                        INTEGER  DAP1,DAPINT)
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, C 
         (BYTEINTEGER  SACPORT1,SACPORT0 OR  BYTEINTEGER   C 
            OCP1 SCU PORT,OCP0 SCU PORT), BYTEINTEGER   C 
         NOCPS,SYSTYPE,OCPPORT1,OCPPORT0,INTEGER  ITINT, C 
         (INTEGER  CONTYPEA,GPCCONFA,FPCCONFA,SFCCONFA OR   C 
          INTEGER  DCU2HWNA,DCUCONFA,MIBA,SP0), C 
         INTEGER  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,RECORD (CDRF)ARRAY  CDR(1:2), C 
         INTEGER  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)
RECORDFORMAT  PARMF(INTEGER  DEST,SRCE,P1,P2,P3,P4,P5,P6)
                                        ! misc. routine specs
EXTERNALROUTINESPEC  PKMONREC(STRING (20)TEXT,RECORD (PARMF)NAME  P)
EXTERNALSTRING (8)FNSPEC  STRHEX(INTEGER  N)
EXTERNALROUTINESPEC  OPMESS3(STRING (63)TXT)
EXTERNALROUTINESPEC  PON(RECORD (PARMF)NAME  P)
EXTERNALROUTINESPEC  DPON(RECORD (PARMF)NAME  P,INTEGER  DELAY)
EXTERNALROUTINESPEC  INHIBIT(INTEGER  N)
EXTERNALROUTINESPEC  UNINHIBIT(INTEGER  N)
EXTERNALROUTINESPEC  DISPLAYTEXT(INTEGER  VID,L,POS,STRING (41)TX)
EXTERNALROUTINESPEC  SEMALOOP(INTEGERNAME  SEM,INTEGER  PARM)
EXTERNALROUTINESPEC  DUMPTABLE(INTEGER  T,A,L)
IF  MONLEVEL&2#0 THEN  START 
      EXTRINSICLONGINTEGER  KMON
FINISH 
IF  MONLEVEL&256#0 START 
      EXTERNALROUTINESPEC  TRACER(STRING (63) S)
FINISH 
OWNINTEGER  DUMPID=M'COMS'
CONSTRECORD (COMF)NAME  COM=X'80000000'!48<<18
EXTERNALSTRING (15)FNSPEC  STRINT(INTEGER  I)
EXTERNALSTRING (15)FNSPEC  HTOS(INTEGER  N,M)
CONSTINTEGER  UNASSIGNED = X'80808080'
CONSTINTEGER  RESIDENT = 64
CONSTINTEGER  LAST PROC = MAXPROCS-1
!------------------------------------------------------------------------
EXTERNALLONGINTEGERFN  CLOCK
LONGINTEGER  L
  *RRTC_0
  *ST_L
  RESULT =(L>>33<<32!L&X'0FFFFFFFF')<<1
END ; ! OF CLOCK
!
!
!
!------------------------------------------------------------------------
EXTERNALROUTINE  WAIT(INTEGER  MILLESECS)
INTEGER  T0,T1,T2,T3,ISA
      ISA=COM_CLKX
      *RRTC_0; *ST_T0
      IF  T0&1#T1>>31 START ;           ! guard bit set
         *LSS_1; *IAD_T0; *LB_ISA
         *ST_(0+B )
      FINISH 
      T1=T1<<1
      *LSS_MILLESECS; *IMY_2
      *IAD_1; *IMYD_512;                ! ACC=delay in microsecs
      *IAD_T0; *ST_T0
L1:   *RRTC_0; *ST_T2
      IF  T2&1#T3>>31 START ;           ! guard bit set
         *LSS_1; *IAD_T2
         *LB_ISA; *ST_(0+B )
      FINISH 
      T3=T3<<1
      *LSD_T2
      *UCP_T0; *JCC_4,<L1>
END ; ! OF WAIT
!
!
!
!------------------------------------------------------------------------
EXTERNALROUTINE  HOOT(INTEGER  NUM)
INTEGER  J, HOOTISA, I, HOOTBIT
   HOOTBIT = COM_HBIT
   HOOTISA = COM_HOOT
   IF  HOOTISA # 0 START ;              ! lest no hooter
      CYCLE  J = 1,1,NUM
         *LB_HOOTISA
         *LSS_(0+B )
         *OR_HOOTBIT
         *ST_(0+B )
         CYCLE  I=1,1,5*COM_INSPERSEC
         REPEAT 
         *LB_HOOTISA
         *LSS_(0+B )
         *SLSS_-1
         *NEQ_HOOTBIT
         *AND_TOS 
         *ST_(0+B )
         CYCLE  I=1,1,5*COM_INSPERSEC
         REPEAT 
      REPEAT 
   FINISH 
      CYCLE  I=1,1,20*COM_INSPERSEC
      REPEAT 
END ; ! OF HOOT
!
!
!
!------------------------------------------------------------------------
EXTERNALROUTINE  GET PSTB(INTEGERNAME  PSTB0, PSTB1)
! Machine-independent version
! Public segment PST SEG is mapped to the PST itself
RECORDFORMAT  EF(INTEGER  LIM, RA)
RECORD (EF)NAME  E
   E == RECORD(PST VA+PST SEG*8)
! E_LIM gives the size of the PST (bytes)
! for double words, >>3, and this is the top public seg which is
! potentially available. To get the VA limit therefore we <<18.
! we add the top bit and also the bottom 7 bits >>3 and <<18, which
! is the '3C'.
   PSTB0 = ((E_LIM&X'0003FF80')<<15)!X'803C0000'
   PSTB1 = E_RA&X'0FFFFFC0'
END ; ! of GET PSTB
!
!
!
!
!------------------------------------------------------------------------
EXTERNALROUTINE  ITOE ALIAS  "S#ITOE" (INTEGER  AD, L)
INTEGER  J
   J = COM_TRANS
   *LB_L;  *JAT_14,<L99>
   *LDTB_X'18000000';  *LDB_B ;  *LDA_AD
   *LSS_J;  *LUH_X'18000100'
   *TTR_L =DR 
L99:

END ; ! of ITOE
!
!
!
!------------------------------------------------------------------------
EXTERNALROUTINE  ETOI ALIAS  "S#ETOI" (INTEGER  AD, L)
INTEGER  J
   J = COM_TRANS+256
   *LB_L;  *JAT_14,<L99>
   *LDTB_X'18000000';  *LDB_B ;  *LDA_AD
   *LSS_J;  *LUH_X'18000100'
   *TTR_L =DR 
L99:

END ; ! of ETOI
!
!
!
!------------------------------------------------------------------------
EXTERNALROUTINE  OPMESS(STRING (63) MESS)
      OPMESS3(" 0/ ".MESS)
END ; ! of OPMESS
!
!
!
!------------------------------------------------------------------------
                                      ! writes value as two decimal ISO digits
                                        ! into AD and AD+1
ROUTINE  DECWRITE2(INTEGER  VALUE,AD)
      *LSS_VALUE; *IMDV_10
      *USH_8; *IAD_TOS ; *IAD_X'3030'
      *LDA_AD; *LDTB_X'58000002'
      *ST_(DR )
END ; ! of DECWRITE2
!
!
!
!------------------------------------------------------------------------
                                      ! K is days since 1st JAN 1900
                                        ! returns d, m, y   2 digit y only
ROUTINE  KDATE(INTEGERNAME  D,M,Y,INTEGER  K)
!      %INTEGER W
!      K=K+693902;                       ! days since CEASARS bday
!      W=4*K-1
!      Y=W//146097
!      K=W-146097*Y
!      D=K//4
!      K=(4*D+3)//1461
!      D=4*D+3-1461*K
!      D=(D+4)//4
!      M=(5*D-3)//153
!      D=5*D-3-153*M
!      D=(D+5)//5
!      Y=K
      *LSS_K; *IAD_693902
      *IMY_4; *ISB_1; *IMDV_146097
      *LSS_TOS ; *IDV_4; *IMY_4; *IAD_3
      *IMDV_1461; *ST_(Y)
      *LSS_TOS ; *IAD_4; *IDV_4
      *IMY_5; *ISB_3; *IMDV_153
      *ST_(M); *LSS_TOS 
      *IAD_5; *IDV_5; *ST_(D)
      IF  M<10 THEN  M=M+3 ELSE  M=M-9 AND  Y=Y+1
END ; ! of KDATE
!
!
!
!------------------------------------------------------------------------
                                      ! get time of day from real time clock
EXTERNALROUTINE  UPDATE TIME
INTEGER  RTC1,RTC2,JDAY,DD,MM,YY,ISA
LONGINTEGER  WORK
      *RRTC_0; *ST_RTC1
      IF  RTC1&1#RTC2>>31 START ;       ! int pending
         ISA=COM_CLKX
         *LSS_1; *IAD_RTC1; *ST_RTC1
         *LB_ISA; *ST_(0+B );           ! update clock X reg by software
      FINISH 
      RTC2=RTC2<<1;                     ! now in microsecs
      WORK=LONGINTEGER(ADDR(RTC1))//1000000
      JDAY=WORK//86400
      WORK=WORK-86400*LENGTHENI(JDAY)
      IF  0<COM_SECSTOCD<X'7FFFFFFF' THEN  START 
         COM_SECSTOCD=COM_SECSTOCD+COM_SECSFRMN-WORK
         IF  COM_SECSTOCD<1 THEN  COM_SECSTOCD=1
      FINISH 
      COM_SECSFRMN=WORK
!
! Work has seconds from midnight
!
      ISA = ADDR(COM_TIME1)
      *LDTB_X'58000002'
      *LDA_ISA
      *LSS_WORK+4; ! secs from midnight
!
      *IMDV_60; ! %TOS=SECS, ACC=MINS
      *IMDV_60; ! %TOS=MINS, ACC=HRS
!
      *IMDV_10; ! convert hrs to 2 digits and store
      *USH_8
      *IAD_TOS 
      *IAD_X'3030'
      *ST_(DR )
!
      *INCA_3; ! increment DR
      *LSS_TOS ; ! mins
      *IMDV_10
      *USH_8
      *IAD_TOS 
      *IAD_X'3030'
      *ST_(DR )
!
      *INCA_3
      *LSS_TOS ; ! secs
      *IMDV_10
      *USH_8
      *IAD_TOS 
      *IAD_X'3030'
      *ST_(DR )
!
      DISPLAY TEXT(0, 0, 32, STRING(ISA-1))
!
! Check for passing midnight
!
      IF  JDAY#COM_TOJDAY START ;       ! passed midnight amend date
         IF  1<COM_SECSTOCD<X'7FFFFFFF' THEN  C 
            COM_SECSTOCD=COM_SECSTOCD-86400
         KDATE(DD,MM,YY,JDAY)
         COM_TOJDAY=JDAY
         ISA=ADDR(COM_DATE1)
         DECWRITE2(DD,ISA)
         DECWRITE2(MM,ISA+3)
         DECWRITE2(YY,ISA+6)
         DISPLAYTEXT(0,0,22,STRING(ADDR(COM_DATE0)+3))
      FINISH 
END ; ! of UPDATE TIME
!
!
!
!------------------------------------------------------------------------
EXTERNALINTEGERFN  STOI(STRINGNAME  S);!external because used by harvest package
STRING (50) P
INTEGER  SIGN,AD,I,J,HEX
LONGINTEGER  TOTAL
         HEX=0; TOTAL=0; SIGN=1
         AD=ADDR(P)
L1:      ->NULLS IF  S=""
         I=CHARNO(S,1);                 ! first char
         IF  I=' ' THEN  S->(" ").S AND  ->L1;  ! chop leading spaces
         IF  I='-' THEN  S->("-").S AND  SIGN=-1 AND  ->L1
         IF  I='X' THEN  S->("X").S AND  HEX=1 AND  ->L1
         P=S
         UNLESS  S->P.(" ").S THEN  S=""
         I=1
         WHILE  I<=BYTEINTEGER(AD) CYCLE 
            J=BYTE INTEGER(I+AD)
            ->FAULT UNLESS  '0'<=J<='9' OR  (HEX#0 AND  'A'<=J<='F')
            IF  HEX=0 THEN  TOTAL=10*TOTAL ELSE  TOTAL=TOTAL<<4+9*J>>6
            TOTAL=TOTAL+J&15; I=I+1
         REPEAT 
         IF  HEX#0 AND  I>9 THEN  ->FAULT
         J<-TOTAL
         IF  I>1 THEN  RESULT =SIGN*J
FAULT:   S=P." ".S
NULLS:   RESULT =UNASSIGNED
END ; ! of STOI
!
!
!
!------------------------------------------------------------------------
EXTERNALROUTINE  SLAVESONOFF(INTEGER  ONOFF)
!***********************************************************************
!*    Turn off all slaves if ONOFF=0                                   *
!*    Turn on all slaves if ONOFF=-1                                   *
!*    or turn off and on slectively if ONOFF == a bitmask              *
!***********************************************************************
INTEGER  I,J,K,PSTB
      PSTB=COM_PSTB
      I=COM_SLAVEOFF
      J=I>>16; I=I&X'FFFF'
      K=J!!(-1); J=J&(ONOFF!!(-1))
      *LB_I; *LSS_(0+B )
      *AND_K; *OR_J; *ST_(0+B )
      *LB_PSTB; *LSS_(0+B ); *ST_(0+B ); ! clear slaves
END ; ! of SLAVES ON OFF
!

INTEGERFN  SAFE IS OP(INTEGER  READORWRITE,ISAD,INTEGERNAME  VAL)
!************************************************************************
!*    Performs an image store action and catches any system errors     *
!*    result is se parameter or 0                                      *
!************************************************************************
RECORDFORMAT  ISTF(INTEGER  LNB,PSR,PC,SSR,SF,IT,IC,CTB)
RECORD (ISTF) OLDIST
RECORD (ISTF)NAME  IST
INTEGERARRAY  SSSNP1(0:17);             ! TO SAVE SSN+1
INTEGER  MYPORT
INTEGER  I,J,K,ISWORD1,ISWORD2,SSR,SNAD
      *LSS_(3); *USH_-26; *AND_3; *ST_MYPORT
      IST==RECORD(X'80000000'!MYPORT<<18)
      OLDIST=IST;                       ! save syserr IST entry
      *STLN_I; *STSF_J; *JLK_<ERROR>; *LSS_TOS ; *ST_K
      IST_LNB=I
      IST_PC=K;                         ! reset IST in case
      IST_SF=J
      *LSS_(3); *ST_SSR
      IST_SSR=SSR
      SNAD=J&X'FFFC0000'+1<<18
      CYCLE  J=0,1,17
         SSSNP1(J)=INTEGER(SNAD+4*J)
      REPEAT 
      ! inihibit photos (not 2960s) & for duals turn off cross-reporting/BSE
      ! rather unfortunate if these are the target I.S registers!!
      IF  SSERIES=YES START 
         *LSS_(X'6011'); *AND_X'FFFF'; *ST_ISWORD1
         *OR_2; *ST_(X'6011')
         IF  MULTI OCP=YES START 
            *LSS_(X'601D'); *ST_ISWORD2
            *LSS_(16); *USH_-24; *USH_22; *ST_(X'601D')
         FINISH 
      FINISH  ELSE  IF  BASIC PTYPE=4 THEN  START 
         *LSS_(X'4012'); *ST_ISWORD1
         *OR_X'01000000'; *ST_(X'4012')
         IF  MULTI OCP=YES START 
            *LSS_(X'4013'); *ST_ISWORD2
            *AND_X'FFFF7FFB'; *ST_(X'4013')
         FINISH 
      FINISH  ELSE  START ;             ! P2 * P3S
         IF  BASIC PTYPE=3 START 
            *LSS_(X'6011'); *AND_X'FFFF'; *ST_ISWORD1
            *OR_1; *ST_(X'6011')
         FINISH 
         IF  MULTI OCP=YES START 
            *LSS_(X'6009'); *ST_ISWORD2
            *LSS_0; *ST_(X'6009');      ! dont broadcast this se
         FINISH 
      FINISH 
      *LSS_SSR; *AND_-2; *ST_(3);       ! unmask system errors
      IF  READORWRITE=0 START ;         ! image store read
         *LB_ISAD; *LSS_(0+B ); *ST_(VAL)
      FINISH  ELSE  START 
         *LB_ISAD; *LSS_(VAL); *ST_(0+B )
      FINISH 
                                        ! if control gets here it worked
      *LSS_SSR; *ST_(3);                ! restore SSR
      I=0; ->WAYOUT
ERROR:                                  ! comes here if fails
      *JLK_TOS 
      *LSS_TOS ;                        ! discard old SSN
      *LSS_TOS ; *ST_I;                 ! se i parameter
      CYCLE  J=0,1,17
         INTEGER(SNAD+4*J)=SSSNP1(J)
      REPEAT 
WAYOUT:
      IF  SSERIES=YES START 
         *LSS_ISWORD1; *ST_(X'6011')
         IF  MULTI OCP=YES START 
            *LSS_ISWORD2
            *ST_(X'601D')
         FINISH 
      FINISH  ELSE  IF  BASIC PTYPE=4 THEN  START 
         *LSS_ISWORD1; *ST_(X'4012')
         IF  MULTI OCP=YES START 
            *LSS_ISWORD2
            *ST_(X'4013')
         FINISH 
      FINISH  ELSE  START 
         IF  BASIC PTYPE=3 START 
            *LSS_ISWORD1; *ST_(X'6011')
         FINISH 
         IF  MULTI OCP=YES START 
            *LSS_ISWORD2
            *ST_(X'6009')
         FINISH 
      FINISH 
      IST=OLDIST
      RESULT =I
END 
EXTERNALINTEGERFN  SAFE IS WRITE(INTEGER  ISAD,VAL)
      RESULT =SAFEISOP(1,ISAD,VAL)
END 
EXTERNALINTEGERFN  SAFE IS READ(INTEGER  ISAD,INTEGERNAME  VAL)
      RESULT =SAFE IS OP(0,ISAD,VAL)
END 
!
!
!------------------------------------------------------------------------
ROUTINE  RESPOND(INTEGER  SRCE,STRING (40)TXT)
RECORD (PARMF) PP
         PP_SRCE = 0
         PP_DEST = SRCE << 16 ! 7; ! 7 is a conventional dact
         IF  LENGTH(TXT)>23 THEN  LENGTH(TXT)=23
         STRING(ADDR(PP_P1)) = TXT
         PON(PP)
END ; ! OF RESPOND
!
!
!
!------------------------------------------------------------------------
CONSTINTEGER  DIRACT=X'10014',VOLACT=X'20014',SPLACT=X'30014', C 
               MAILACT=X'40014',FTAACT=X'50014',MESSACT=X'5'
EXTERNALROUTINE  PARSE COM(INTEGER  SRCE,STRINGNAME  S)
!***********************************************************************
!*    Transcribe a command to a PON message and PON it                 *
!***********************************************************************
INTEGERFNSPEC  TAPEPLACE(INTEGERNAME  A,B,STRINGNAME  S,INTEGER  F)
INTEGERFNSPEC  DISCPLACE(INTEGERNAME  A,B,STRINGNAME  S,INTEGER  F)
INTEGERFNSPEC  ONOFF(STRING (63)S)
OWNINTEGER  SRCESERV=0
CONSTINTEGER  LIMIT=34
CONSTINTEGER  BMREP = X'3D0000'
IF  SSERIES=YES START 
   CONSTBYTEINTEGERARRAY  PARAMS(1:LIMIT)=2,1,0,0,2,1,0,0,1,0,0,0,1,1(3),0,
                  2,2,0,1,1,2,2,2,0,0,0,0,0,0,0,0,1;
   CONSTSTRING (7)ARRAY  COMMAND(1:LIMIT)="PON ","SRCE ","PLOT ",
                     "PLOD ","DT ","OCP ","UNPLOT ","STARTD",
                     "FEPUP ","DUMP ","PRIME ","OPER ","CINIT ",
                     "INH ","UNINH ","DIRVSN ","P ","XDUMP ",
                     "REP ","DDUMP ","SLAVES ","ISR ","ISW ","KMON ",
                     "SHOW ","DCU ","B ","F ","TRACE ","RESTART","SOFON",
                     "SOFOFF","DCLEAR ","FEDOWN ";
FINISH  ELSE  START 
   CONSTBYTEINTEGERARRAY  PARAMS(1:LIMIT)=2,1,0,0,2,1,0,0,1,0,0,0,1,1(3),0,
                  2,2,0,1,1,2,2,2,0,0,0,0,1,1,1,0,1;
   CONSTSTRING (7)ARRAY  COMMAND(1:LIMIT)="PON ","SRCE ","PLOT ",
                     "PLOD ","DT ","OCP ","UNPLOT ","STARTD",
                     "FEPUP ","DUMP ","PRIME ","OPER ","CINIT ",
                     "INH ","UNINH ","DIRVSN ","P ","XDUMP ",
                     "REP ","DDUMP ","SLAVES ","ISR ","ISW ","KMON ",
                     "SHOW ","GPC ","B ","F ","TRACE ","SAC ","SMAC ",
                     "DAP ","DCLEAR ","FEDOWN ";
FINISH 
CONSTSTRING (3)ARRAY  DOW(0:6)="MON","TUE","WED","THU","FRI","SAT","SUN";
CONSTSTRINGNAME  TIME = X'80C0004B'
CONSTINTEGER  SECSIN24HRS=86400
SWITCH  SWT(1:LIMIT)
RECORDFORMAT  PARMMF(INTEGER  DEST,SRCE,(INTEGER  P1,P2,P3,P4,P5,P6 C 
      OR  STRING (23)MSG))
RECORD (PARMMF) PP
INTEGERARRAY  DATA(1:6)
INTEGER  I,J,K, OP, SSNO, MASK ,WORK, D, M, Y, HR, MIN
LONGINTEGER  L
STRING (63)PRE
STRING (63)P,Q
      IF  LENGTH(S) = 0  THEN  RETURN ; ! ignore null lines
      PP=0
      SSNO = SRCE >> 16
      IF  SSNO = X'32' START ;          ! compute prefixed line for operlog
                                        ! called from an OPER
         OP = 3<<24 ! M'OP0' ! SRCE>>8&7
         PRE = STRING(ADDR(OP))." ".S
      FINISH  ELSE  START ;             ! called from process
         I = (SSNO - RESIDENT) & LAST PROC
         PRE = STRINT(I)
         PRE = " ".PRE IF  I < 10
         PRE = PRE."/ ".S
      FINISH 
!
      IF  S->Q.("0/").P AND  Q="" THEN  S=P
      CYCLE  I=1,1,LIMIT
         ->FOUND IF  S->Q.(COMMAND(I)).P AND  Q=""
      REPEAT 
      OPMESS3(PRE)
      CYCLE  I=2,1,5
         IF  LENGTH(S)>=I AND  CHARNO(S,I)='/' THEN  ->TEXTIN
      REPEAT 
ERR:
      RESPOND(SSNO,"????".S);           ! error response
      RETURN 
FOUND:                                  ! command recognised
      UNLESS  I=17 OR  I=27 OR  I=28 THEN  OPMESS3(PRE); ! dont log S, B or F
      J=PARAMS(I);                      ! (minimum) no of parameters
      K=1
      WHILE  K<=J CYCLE 
         DATA(K)=STOI(P)
         ->ERR IF  DATA(K)=UNASSIGNED;  ! required parameter not given
         K=K+1
      REPEAT 
      PP_DEST = X'240000';              ! bulk mover, nearly always right!
      PP_SRCE = BMREP ! (srce >> 16);   ! likewise
      ->SWT(I)
TEXTIN:                                  ! operator to user process
      S->P.("/").Q
      IF  LENGTH(Q)>23 THEN  ->ERR
      IF  P="D" THEN  PP_DEST=DIRACT+COM_SYNC1DEST<<16 AND  ->ON
      IF  P="V" THEN  PP_DEST=VOLACT+COM_SYNC1DEST<<16 AND  ->ON
      IF  P="S" THEN  PP_DEST=SPLACT+COM_SYNC1DEST<<16 AND  ->ON
      IF  P="M" THEN  PP_DEST=MAILACT+COM_SYNC1DEST<<16 AND  ->ON
      IF  P="F" THEN  PP_DEST=FTAACT+COM_SYNC1DEST<<16 AND  ->ON
      K=STOI(P); IF  K<=0 THEN  ->ERR
!
      K = K << 16 ! MESSACT;            ! DACT = 5 for opmess in
      PP_DEST = K + COM_ASYNCDEST << 16
!
ON:  PP_SRCE=SRCE
      LENGTH(Q)=LENGTH(Q)-1 WHILE  C 
         LENGTH(Q)>0 AND  CHARNO(Q,LENGTH(Q))=' '
     STRING(ADDR(PP_P1))=Q
     ->POUT
SWT(1):                                 ! PON (variable params)
      PP_DEST=DATA(1)<<16!DATA(2)
      CYCLE  K=0,1,5
         I=STOI(P)
         IF  I=UNASSIGNED AND  P#"" AND  CHARNO(P,1)='"' AND  C 
         P->("""").Q.("""").P START 
            STRING(ADDR(PP_P1)+4*K)=Q
            K=K+LENGTH(Q)//4
         FINISH  ELSE  INTEGER(ADDR(PP_P1)+4*K)=I
      REPEAT 
      IF  SRCESERV=0 THEN  PP_SRCE=SRCE ELSE  PP_SRCE=SRCESERV
POUT: PKMONREC(TIME." Command ",PP)
      PON(PP)
      RETURN 
SWT(2):                                 ! SRCE = SRCE serv no for PON
      SRCESERV=DATA(1)
      RETURN 
SWT(3):                                 ! PLOT T F D PGE NPAGES
      ->ERR UNLESS  TAPEPLACE(PP_P2,PP_P3,P,1)=0
      ->ERR UNLESS  DISCPLACE(PP_P4,PP_P5,P,1)=0
      I=STOI(P)
      ->ERR UNLESS  I>0
      PP_P1=X'04020000'+I
      PP_P6=M'PLOT'
      ->POUT
SWT(4):                                 ! PLOD FD FP TD TP NP
      ->ERR UNLESS  DISCPLACE(PP_P2,PP_P3,P,1)=0
      ->ERR UNLESS  DISCPLACE(PP_P4,PP_P5,P,1)=0
      I=STOI(P)
      ->ERR UNLESS  I>0
      PP_P1=X'02020000'+I
      PP_P6=M'PLOD'
      ->POUT
SWT(5):                                 ! DT date time
      WORK=DATA(1);                     ! date
      *LSS_WORK; *IMDV_100; *IMDV_100
      *ST_D;                            ! days
      *LSS_TOS ; *ST_M;                 ! months
      *LSS_TOS ; *ST_Y;                 ! year
      ->ERR UNLESS  1<=D<=31 AND  1<=M<=12 AND  Y>=77
      IF  M>2 THEN  M=M-3 ELSE  M=M+9 AND  Y=Y-1
      J=1461*Y//4+(153*M+2)//5+D+58
      ->ERR UNLESS  P->(DOW(J-(J//7)*7)).Q
!
      WORK=DATA(2);                     ! time
      *LSS_WORK; *IMDV_100
      *ST_HR;                           ! hours
      *LSS_TOS ; *ST_MIN;               ! mins
      ->ERR UNLESS  0<=HR<=23 AND  0<=MIN<60
      *LSS_J; *IMYD_SECSIN24HRS; *ST_L
      L=(L+60*(60*HR+MIN))*1000000;     ! microsecs since Jan 1900
      I=COM_CLKX
      *LB_I; *LSS_L; *ST_(0+B );        ! set clock X register
      I=COM_CLKY; L=L>>1
      *LB_I; *LSS_L+4; *ST_(0+B )
      RETURN 
SWT(6):                                 ! OCP n ONOFF
      IF  MULTIOCP=YES THEN  START 
         PP_P1=1;                       ! for OCP
      FINISH  ELSE  ->ERR
ONOFF:K=ONOFF(P)
      ->ERR IF  K<0
      PP_DEST=17<<16!K
      PP_P1=PP_P1<<16!DATA(1)
      ->POUT
SWT(7):                                 ! UNPLOT discaddr tapeaddr npages
      ->ERR UNLESS  DISCPLACE(PP_P2,PP_P3,P,1)=0
      ->ERR UNLESS  TAPEPLACE(PP_P4,PP_P5,P,1)=0
      I=STOI(P)
      ->ERR UNLESS  I>0
      PP_P1=X'02040000'+I
      PP_P6=M'PLOT'
      ->POUT
SWT(8):                                 ! STARTD. restart "DIRECT" process
      PP_DEST=X'30011'
      PP_SRCE=0
      ->POUT
SWT(9):                                 ! FEPUP n
      I=DATA(1)
      ->ERR UNLESS  0<=I<=9 AND  COM_FEPS&(X'10000'<<I)#0
      Q=TOSTRING(I+'0')
      PP_SRCE=SRCE
      PP_DEST=X'300001';                ! DCU/GPC <text> DEST
      PP_MSG="CDS FE".Q." OFF "
      DPON(PP,1)
      PP_MSG="CDS FE".Q." ON "
      DPON(PP,6)
      PP_DEST=X'390009';                ! allocate FEP in FE adaptr
      PP_P1=I
      DPON(PP,11)
      PP_DEST=DIRACT+COM_SYNC1DEST<<16
      PP_MSG="CONNECTFE ".Q
      DPON(PP,16)
      PP_DEST=PP_DEST+(SPLACT-DIRACT)
      DPON(PP,17)
      PP_DEST=PP_DEST+(FTAACT-SPLACT)
      DPON(PP,17)
      RETURN 
SWT(10):                                ! DUMP T D NPAGES
      ->ERR UNLESS  TAPEPLACE(PP_P4,PP_P5,P,0)=0
      ->ERR UNLESS  DISCPLACE(PP_P2,PP_P3,P,0)=0
      I=STOI(P)
      ->ERR UNLESS  I>0
      PP_P1=X'02040000'+I
      PP_P6=M'DUMP'
      ->POUT
SWT(11):                                ! PRIME T D NPAGES
      ->ERR UNLESS  TAPEPLACE(PP_P2,PP_P3,P,0)=0
      ->ERR UNLESS  DISCPLACE(PP_P4,PP_P5,P,0)=0
      I=STOI(P)
      ->ERR UNLESS  I>0
      PP_P1=X'04020000'+I
      PP_P6=M'PRME'
      ->POUT
SWT(12):                                ! OPER <text>
      PP_DEST=X'0032000C'!SRCE&X'FF00'
      ->DEVTEXT
SWT(13):                                ! CINIT NEWPT OLDPT
      IF  SSERIES=NO START 
         ->ERR UNLESS  0<=DATA(1)<=31
         J=STOI(P)
         UNLESS  J=UNASSIGNED START 
            ->ERR UNLESS  0<=J<=31
            K=J
         FINISH  ELSE  K=DATA(1)
         I=BYTEINTEGER(COM_CONTYPEA+K); ! type of controller
         IF  I=2 THEN  PP_DEST=X'20000A' ELSE  C       { DFC }
            IF  I=3 THEN  PP_DEST=X'30000A' ELSE  C    { GPC }
               ->ERR
         PP_SRCE=SRCE
         PP_P1=DATA(1)
         PP_P2=J
         ->POUT
      FINISH  ELSE  ->ERR
SWT(14):                                ! INH
      INHIBIT(DATA(1)); RETURN 
SWT(15):                                ! UNINH
      UNINHIBIT(DATA(1)); RETURN 
SWT(16):                                ! DIRVSN
      COM_DIRSITE=X'200'+(DATA(1)&3)*64
      COM_DCODEDA=COM_SUPLVN<<24!COM_DIRSITE
      RETURN 
SWT(17):                                 ! S picture screen
      I = STOI(P)
      IF  I = UNASSIGNED START 
         ! Picture not given as numeric
SWT17A:  IF  P#"" AND  CHARNO(P,1)=' ' THEN  P -> (" ").P AND  -> SWT17A
         UNLESS  P -> Q.(" ").P START 
            Q = P
            P = ""
         FINISH 
         PP_P1 = -1
         STRING(ADDR(PP_P3)) = Q
      FINISH  ELSE  START 
         PP_P1 = I
      FINISH 
      I = STOI(P)
      IF  I = UNASSIGNED THEN  I = 0
      PP_P2 = I
      PP_DEST = (SRCE >> 8) << 8 ! 19; ! show picture
      PP_SRCE = 0
      -> POUT
!
!
!
SWT(18):                                ! XDUMP
      DUMPTABLE(32,DATA(1),DATA(2))
      RETURN 
SWT(19):                                ! REP AT WITH
      I=DATA(1)
      *LDTB_X'18000004'; *LDA_I; *VAL_(LNB +1)
      *JCC_7,<ERR>
      J=INTEGER(I); INTEGER(I)=DATA(2)
      RESPOND(SSNO,STRHEX(DATA(2))." REPS ".STRHEX(J))
      RETURN 
SWT(20):                                ! DDUMP discaddr
      PP_P1=X'02050001'
      PP_P6=M'DDMP'
      ->ERR UNLESS  DISCPLACE(PP_P2,PP_P3,P,1)=0
      PP_P4=0; PP_P5=0
      ->POUT
SWT(33):                                ! DCLEAR discaddr
      PP_P1=X'05020001'
      PP_P6=M'DCLR'
      ->ERR UNLESS  DISCPLACE(PP_P4,PP_P5,P,1)=0
      PP_P2=0; PP_P3=0
      ->POUT
SWT(21):                                ! SLAVES ONOFF(0=off)
      SLAVESONOFF(DATA(1))
      RETURN 
SWT(22):                                ! image store read&display
      I=DATA(1)
      IF  SAFE IS READ(I,J)#0 THEN  ->ERR
      RESPOND(SSNO,"IS ".STRHEX(I)."=".STRHEX(J))
      RETURN 
SWT(23):                                ! image store write
      I=DATA(1); J=DATA(2)
      IF  SAFE IS WRITE(I,J)#0 THEN  ->ERR
      RETURN 
SWT(24):                                ! KMON serv onoff
      IF  MONLEVEL&2#0 THEN  START 
         I=DATA(1)
         J=DATA(2)
         ->ERR UNLESS  0<=J<=1
         L=LENGTHENI(1)<<I
         KMON=KMON&(L!!X'FFFFFFFFFFFFFFFF')
         IF  J=1 THEN  KMON=KMON!L
      FINISH 
      RETURN 
SWT(25):                                ! SHOW virtaddr length
      I=DATA(1); J=DATA(2)
      IF  J<=0 OR  J>64 THEN  J=64
      *LDTB_X'18000000'
      *LDB_J; *LDA_I
      *VAL_(LNB +1)
      *JCC_3,<ERR>
      CYCLE 
         RESPOND(SSNO, C 
            HTOS(I,4)." ".HTOS(INTEGER(I),8)." ". C 
            HTOS(INTEGER(I+4),8))       
         I=I+8; J=J-8
      EXIT  IF  J<=0
      REPEAT 
      RETURN 
SWT(26):                                ! GPC/DCU <text>
      PP_DEST=X'300001'
DEVTEXT:                                ! OPER <text> joins here
      ->ERR IF  LENGTH(P)>23
      PP_SRCE = SRCE
      STRING(ADDR(PP_P1))=P
      ->POUT
SWT(27):                              ! B (PGB)
      PP_P1 = -1
      -> SWT28A
SWT(28):                                ! F (PGF)
      PP_P1 = 1
SWT28A:
      I = STOI(P)
      IF  I = UNASSIGNED THEN  I = 0
      PP_P2 = I
      PP_DEST = (SRCE >> 8) << 8 ! 18; ! PGB,F
      PP_SRCE = 0
      -> POUT
SWT(29):                                !trace events
      IF  MONLEVEL&256#0 START 
            TRACER(P)
         RETURN 
      FINISH  ELSE  ->ERR
IF  SSERIES=YES START 
SWT(30):                                ! restart
   UNLESS  COM_USERS=0 START 
      RESPOND(SSNO,"Processes still active!")
      RETURN 
   FINISH 
   UNLESS  COM_SLIPL<0 THEN  COM_SLIPL=COM_SLIPL&X'FFFF'!X'80000000'
                                        ! AUTOSLOAD if set
   PRINTSTRING("RESTART requested
")
   STOP ;                               ! activates into 'RESTART'
   RETURN ;                             ! should not!!
SWT(31):                                ! SOFON mask
   MASK=STOI(P)
   IF  MASK=UNASSIGNED THEN  I=X'810' ELSE  I=X'800'
   *LSS_(X'6011'); *OR_I; *ST_(X'6011'); ! stop on fail on
   UNLESS  MASK=UNASSIGNED START 
      *LSS_MASK; *ST_(X'602A');                    ! selective inh SSR
   FINISH 
   IF  MULTI OCP=YES AND  COM_NOCPS>1 START 
      *LSS_(3); *USH_-26; *AND_3; *ST_K
      IF  K=COM_OCPPORT0 THEN  K=COM_OCP1 SCU PORT ELSE  K=COM_OCP0 SCU PORT
      K=X'400C0000'!K<<22;              ! other OCP
      J=K!X'6011'
      *LB_J; *LSS_(0+B ); *OR_I; *ST_(0+B )
      UNLESS  MASK=UNASSIGNED START 
         J=K!X'602A'; *LB_J; *LSS_MASK; *ST_(0+B )
      FINISH 
  FINISH 
  OPMESS("Stop on fail set")
  RETURN 
SWT(32):                                ! SOFOFF
   *LSS_(X'6011'); *AND_X'F7EF'; *ST_(X'6011');     ! stop on fail off
   *LSS_0; *ST_(X'602A')
   IF  MULTI OCP=YES AND  COM_NOCPS>1 START 
      *LSS_(3); *USH_-26; *AND_3; *ST_K
      IF  K=COM_OCPPORT0 THEN  K=COM_OCP1 SCU PORT ELSE  K=COM_OCP0 SCU PORT
      K=X'400C0000'!K<<22;             ! other OCP addr
      J=K!X'6011'
      *LB_J; *LSS_(0+B ); *AND_X'F7EF'; *ST_(0+B )
      J=K!X'602A'
      *LB_J; *LSS_0; *ST_(0+B )
   FINISH 
   OPMESS("Stop on fail unset")
   RETURN 
FINISH  ELSE  START 
SWT(30):                                ! SAC <N> ONOFF
SWT(31):                                ! SMAC <N> ONOFF
SWT(32):                                ! DAP <N> ONOFF
      IF  RECONFIGURE=YES THEN  START 
         PP_P1=I-28;                    ! 3 for SMAC 2 for SAC
                                        ! 4 for DAP
         ->ONOFF
      FINISH  ELSE  ->ERR
FINISH 
!
SWT(34):                                ! FEDOWN n
      I=DATA(1)
      ->ERR UNLESS  0<=I<=9 AND  COM_FEPS&(X'10000'<<I)#0
      Q=TOSTRING(I+'0')
      PP_SRCE=SRCE
      PP_DEST=X'39000B';                !FE ADAPTOR DEALLOCATE
      PP_P1=I;                          !FEP i
      PON(PP)
      PP_DEST=X'300001';                ! DCU/GPC <text> DEST
      PP_MSG="CDS FE".Q." OFF "
      DPON(PP,5)
      RETURN 
!
INTEGERFN  DISCPLACE(INTEGERNAME  A,B,STRINGNAME  S,INTEGER  FLAG)
!***********************************************************************
!*    Extract a disc no or label from S and set A&B in bulkmover format*
!*    FLAG=0 if no page no expected(when page 0 assumed)               *
!***********************************************************************
INTEGER  I,J,K
STRING (63)P
      I=STOI(S); B=0; K=0
      IF  I>=0 THEN  A=I+M'ED00' AND  ->PAGE
AGN:  RESULT =1 UNLESS  S->P.(" ").S
      ->AGN IF  P=""
      RESULT =1  UNLESS  LENGTH(P)=6
      CYCLE  I=0,1,5
         BYTEINTEGER(ADDR(J)+I)=CHARNO(P,I+1)
      REPEAT 
      A=J; B=K;                         ! 6 char vol label
PAGE: IF  FLAG#0 START 
         I=STOI(S)
         IF  I<0 THEN  RESULT =1
         B=B&X'FFFF0000'+I
      FINISH 
      RESULT =0
END 
INTEGERFN  TAPEPLACE(INTEGERNAME  A,B,STRINGNAME  S,INTEGER  FLAG)
!***********************************************************************
!*    Extract a tape no or label from S and set A&B in bulkmover format*
!*    FLAG=0 if no chap no expected (when 1 is assumed)                *
!***********************************************************************
INTEGER  I,J,K
STRING (63)P
      I=STOI(S); B=1; K=1
      IF  I>=0 THEN  A=X'0031006E'+I AND  ->CHAP
AGN:  RESULT =1 UNLESS  S->P.(" ").S
      ->AGN IF  P=""
      RESULT =1 UNLESS  LENGTH(P)=6
      STRING(ADDR(J))=P
      A=J; B=K
CHAP: IF  FLAG#0 THEN  START 
         I=STOI(S)
         IF  I<0 THEN  RESULT =1
         B=B&X'FFFFFF00'+I&255
      FINISH 
      RESULT =0
END 
INTEGERFN  ONOFF(STRING (63)S)
STRING (63)A,B
      S=A.B WHILE  S->A.(" ").B
      RESULT =0 IF  S="OFF"
      RESULT =1 IF  S="ON"
      RESULT =-1
END 
END ; ! OF PARSE COM
!
!
!
EXTERNALROUTINE  BMREP(RECORD (PARMF)NAME  P)
!***********************************************************************
!*    Translates responses from bulk mover into                        *
!*    text form before passing them back to                            *
!*    the original caller (on DACT 1)                                  *
!***********************************************************************
STRING (23)TXT
      IF  P_P1 = 0 C 
      THEN  TXT = "Load OK" C 
      ELSE  TXT = "Load fails ".STRHEX(P_P1)
      RESPOND(P_DEST,TXT)
END ;                                   ! of BMREP
!------------------------------------------------------------------------
EXTERNALROUTINE  COMREP(RECORD (PARMF)NAME  P)
!***********************************************************************
!*    Translates the error response from de allocate tape in bulk      *
!*    mover and logs it                                                *
!***********************************************************************
         ! Reply from de-allocate tape in move
         UNLESS  P_P2 = 0 START 
            OPMESS3("Dealloc fails:".STRING(ADDR(P_P3)))
         FINISH 
END ; ! OF COMREP
!
!
!
!------------------------------------------------------------------------
EXTERNALINTEGERFN  HANDKEYS
INTEGER  ISA
      ISA=COM_HKEYS
      *LB_ISA
      *LSS_(0+B ); *EXIT_-64
END ; ! OF HANDKEYS
!
!
!
!------------------------------------------------------------------------
EXTERNALSTRING (255)FN  STRSP(INTEGER  N)
STRING (255) S
UNLESS  0<N<=255 THEN  RESULT =""
S=""
S=S." " AND  N=N-1 UNTIL  N=0
RESULT =S
END ; ! OF STRSP
!
!
!
!------------------------------------------------------------------------
EXTERNALINTEGERFN  SYSTEMCALL
INTEGER  PC
      *JLK_<SYSCALLI>
      *LSS_TOS 
      *ST_PC
      INTEGER(X'800000E0')=0;           ! zero software syscall count
      RESULT =PC
SYSCALLI:*JLK_TOS 
!
! This horrible piece of coding deals with system calls. We have a RT call
! with unknown no of parameters set up together with LNB+0-2. 
! LNB +3,4 undefined and usable.Can corrupt XNB & DR (PLI says so).Must
! preserve the others (esp. ACC size!). The reason for doing this here
! is that we appear to the local controller to be the user so we can
! page fault of run out of time etc. If we switch stacks to local
! controller proper we can write in IMP but the value of this is offset
! by having to precheck addresses so as not to have any page or other
! faults. If this sequence fails we restore all regs and use OUT 15
! into the local controller to force a contingency
!
      *ST_TOS ;                         ! save ACC whatever its size
      *STB_TOS ;                        ! save B
      *CPSR_B ; *ADB_16; *STB_TOS ;     ! save ACC size in PSR
      *STD_(LNB +3);                    ! save sys call descriptor
!
! Ready to go--- follow logic of routine sys call
! beware of inward returns. Originally indicated by I=J=0 but in later
! mod levels are indicated by link (E1) descriptor in DR rather than
! the normal system call (E3) descriptor. Code must allow for both
!
      *LCT_X'800000E0';                 ! CTB to IST entry for syscall
      *LSS_(LNB +3); *USH_-24;          ! check descriptor code byte
      *ICP_X'E1'; *JCC_8,<INWARDRET>;   ! take link as inward return
      *LSS_(LNB +3); *AND_X'FFFF'; *ST_B ;   ! I value to B
      *LSS_(CTB +6); *AND_X'FFFF';      ! SCTI limit from IST
      *ICP_B ; *JCC_12,<FAIL0>;         ! limit violated by I
      *MYB_8; *ADB_(CTB +7); *LXN_B ;   ! XNB to SCTI entrty
      *LSS_(XNB +0); *AND_X'FFFF';      ! SCT limit
      *ICP_(LNB +4); *JCC_12,<FAIL1>;   ! limit violated by J
      *LB_(LNB +4); *JAT_12,<inwardret>;! j=0 inward return
      *MYB_16; *ADB_(XNB +1); *LXN_B ;  ! XNB to relevant SCT entry
      *LSS_(XNB +0); *AND_X'F00000';    ! ACR access key
      *SLSS_(LNB +1); *AND_X'F00000';   ! users ACR before syscall
      *ICP_TOS ; *JCC_2,<FAIL2>;        ! user not allowed this call
!      *LB_(%XNB+0)
!      *JAF_14,<OUTWARD>;                ! jump for outward calls
!
! The following if frig to route task calls (top 2 bits 0) as software
! INWARD CALLS INSTEAD OF LAST 2 LINES. THIS ENABLES SOFT PARAMETER CHECKS
!
      *SLSS_(XNB +0)
      *AND_X'C0000000'
      *ST_B 
      *LSS_TOS ;                        ! RESET ACC
      *JAT_13,<OUTWARD>
!
! check that acr is not going to be increase
!
      *SLSS_(XNB +1); *AND_X'F00000';   ! new ACR from SCTE entry
      *ICP_TOS ; *JCC_2,<FAIL33>;       ! new ACR less privileged
!
! Update count (kept in LNB posn in IST) of soft system calls
!
      *LSS_1; *IAD_(CTB +0); *ST_(CTB +0)
!
!
! CHECK THAT THE RIGHT AMOUNT OF APARMS HAVE BEEN PROVIDE. THIS
! IS IN TOP BYTE OF SECOND WORD OF TABLE
!
      *LSS_(XNB +1); *USH_-24; *JAT_4,<NOCH>;! 0= NO CHECKING
      *IAD_2; *ST_B ;                   ! MUST ALLOW FOR VARIABLE ACC
                                        ! STORED ON STACK
      *LSS_TOS ; *ST_TOS ; *AND_3;      ! GET ACS FROM PSR
      *ICP_3; *JCC_7,<NOTQUAD>
      *LSS_4
NOTQUAD:                                ! ACC HAS ACCSIZE IN WORDS
      *IAD_B ; *ST_B ; *MYB_4;          ! B HAS SPACE IN BYTES
      *STSF_TOS ; *LSS_TOS ;            ! STF TO ACC
      *STLN_TOS ; *ISB_TOS 
      *ICP_B ; *JCC_7,<FAIL6>;          ! WRONG PARAMS
NOCH:                                   ! PARAMETER CHECKS NOT NEEDED
! Check validity of SCTE descriptor
!
      *LSS_(XNB +2); *USH_-25; *USH_1;  ! type less BCI bit
      *UCP_X'E0'; *JCC_8,<DESOK>;       ! code descriptor
      *UCP_X'B0'; *JCC_8,<DESOK>;       ! descriptor descriptor
      *UCP_X'30'; *JCC_8,<DESOK>;       ! 64-bit vector descripotr
      *UCP_X'28'; *JCC_7,<FAIL34>;      ! 32-bit vector descriptor
DESOK:                                  ! can make the call
      *LD_(XNB +2);                     ! descriptor to DR
      *LSS_TOS ; *AND_X'FF0F';          ! old PM CC &ACS
      *OR_(XNB +1); *ST_(1);            ! with new ACR & priv->new PSR
      *LB_TOS ;                         ! reset B
      *L_TOS ;                          ! reset ACC at old size
      *J_(DR );                         ! into user code
OUTWARD:                                ! outward call
!
! First check that ACR is not going to be decreased
!
      *SLSS_(XNB +1); *AND_X'F00000';   ! new ACR
      *ICP_TOS ; *JCC_4,<FAIL33>;       ! outward call goes inward
!
! Check for and reject (pro tem) task calls
!
      *LSS_B ; *USH_-30; *JAT_4,<FAIL4>
!
! Validate new stack and copy accross parameters etc
!
      *LSS_(XNB +0); *USH_18; *ST_B ;   ! address of free stack
      *STSF_TOS ; *LSS_TOS ; *USH_-18
      *USH_18; *UCP_B ; *JCC_8,<FAIL3>; ! outward call to same stack
      *LSS_(XNB +0); *AND_X'10000';     ! test "EMAS" bit
      *JAT_4,<ICLST>;                   ! ICL stacks start at word0
      *LDTB_X'28000010'; *LDA_B ;       ! EMAS stacks have stndrd headr
      *VAL_(XNB +1); *JCC_7,<FAIL3>;    ! no access
      *LSS_(DR ); *IAD_3; *AND_-4;      ! find first free word in stack
      *IAD_B ; *ST_B ;                  ! amend B past preloaded stack
ICLST:                                  ! B has new LNB Address
      *STSF_TOS ; *LSS_TOS ;            ! TOS to ACC
      *STLN_TOS ; *ISB_TOS ;            ! bytes of parameters in ACC
      *ST_TOS 
      *LDTB_X'18000000'; *LDB_TOS ;     ! set up byte vector descptr
      *LDA_B ; *VAL_(XNB +1);           ! check can write params
      *JCC_7,<FAIL3>;                   ! stack invalid
      *STLN_TOS ; *LSS_TOS 
      *LUH_X'1800FFFF'; *MV_L =DR ;     ! copy parameters(+temporaries)
!
! Frig up link descriptor to force inward return
!
      *LDTB_X'28000010'; *LDA_B ;       ! 16 word descriptor to new frame
      *LSS_(LNB +3); *ST_(DR +1);       ! syscall 'I' word
      *LSS_0; *ST_(DR +2);              ! J=0 for inward return
!
! Validate SSN+1 must be only 128 bytes long ie known and locked down
! by the local contoller before system call starts
!
      *LSS_B ; *USH_-18; *IAD_1
      *USH_18; *ST_TOS ; *LDA_TOS ;     ! DR to 16 words of new SSN+1
      *VAL_X'00100000'; *JCC_7,<FAIL3>
      *INCA_128; *VAL_X'00100000'
      *JCC_14,<FAIL3>;                  ! more than 128 bytes long
      *INCA_-128;                       ! back to first 16 word
!
! Set up SSN+1 using info from current context & SCTE. Also incorporate
! checks on SCTE descriptor while digging out the new PC
!
      *STB_(DR );                       ! new LNB
      *ISB_X'40000'; *ST_(DR +7);       ! SSN
      *LSS_(XNB +3); *ST_(DR +11);      ! new DR1
      *LSS_(XNB +2); *ST_(DR +10);      ! DR0
      *USH_-25; *USH_1;                 ! type byte less BCI bit
      *UCP_X'B0'; *JCC_8,<VDES>;        ! descriptor= type 2 64 bit
      *UCP_X'30'; *JCC_8,<VDES>;        ! descriptor= type 0 64 bit
      *UCP_X'28'; *JCC_8,<VDES>;        ! descriptor= type 0 32 bit
      *UCP_X'E0'; *JCC_7,<FAIL34>;      ! not code descriptor
      *LSS_(XNB +3); *J_<ALLDES>;       ! PC from code desc
VDES: *STD_TOS ; *LSD_((XNB +2));       ! get PC from vector descptr
      *MPSR_X'11'; *LD_TOS ;            ! get PC lose top 32 bits
ALLDES:  *ST_(DR +2);                   ! new PC
      *LSS_(3); *ST_(DR +3);            ! old SSR
      *LSS_(5);   *ST_(DR +5);          ! transfer interval timer
      *LSS_(6);   *ST_(DR +6);          ! transfer instrn counter
      *LSS_TOS ; *ST_TOS ; *AND_X'FF0F';! get OLD PM CC & ACS
      *OR_(XNB +1); *ST_(DR +1);        ! new PSR
!
! The ACC is difficult. Pick up from TOS force to 128 bits change DR
! and store. New ACS in PSR will discard top portion if necessary
!
      *MPSR_TOS ; *LB_TOS ; *STB_(DR +9);! tranfer old B reg
      *L_TOS ; *MPSR_X'13';             ! ACC to 128 bits
      *LDTB_X'38000004'; *ST_(DR +3);   ! words 12-15
      *LDTB_X'28000010'; *STSF_B 
      *STLN_TOS ; *SBB_TOS ; *ADB_(DR );! add in new LNB
      *STB_(DR +4);                     ! to get new value of SF
!
! New SSN+1 ready for activate. Set up current SSN+1 for subsequent
! inward return. Must inhibit interrupts as a register dump into
! this SSN+1 would be very inconvenient!
!
      *STSF_TOS ; *LSS_TOS ; *USH_-18
      *IAD_1; *USH_18;                  ! current SSN+1 addr in ACC
      *SLSS_X'3FFE'; *LXN_TOS ;         ! XNB to current SSN+1
      *ST_(3);                          ! mask out all int xcept se
      *LSS_(DR +3); *ST_(XNB +3);       ! SSR from new SSN+1 to old
      *LSD_(LNB +1); *ST_(XNB +1);      ! PC &PSR for return
      *LSS_(7); *ST_(XNB +7);           ! SSN(CTB)
      *STLN_(XNB +4);                   ! new SF = current LNB
      *LSS_(LNB +0); *ST_(XNB +0);      ! new LNB= current(LNB+0)
!
! SSN+1 now ready for return except for ACC,ACS CC etc which are not yet
! known. Reactivate on new stack using activate words in process list
! word 4 of IST entry is address of X28000004/adrr descriptor for
! four activate words in process list entry of this (nb! this 
! hence double indirection) process
!
ASSACT:
      *LSS_(DR ); *USH_-18; *USH_18
      *LXN_(CTB +4);                    ! points to descriptor
      *LXN_(XNB +1);                    ! now points to act words
      *ST_(XNB +3);                     ! update last word (=SSN addr)
      *ACT_(XNB +0);                    ! and activate it
!
INWARDRET:                              ! inward return
      *LSS_(LNB +0); *USH_-18; *UAD_1;  ! find SSN+1 to return to
      *USH_18; *ST_B ; *LXN_B ;         ! XNB to SSN+1
      *LDTB_X'28000010'; *LDA_B ;       ! DR to SSN+1
      *VAL_X'00100000'; *JCC_7,<FAIL5>; ! no such SSN+1
      *LSS_(DR ); *UCP_(LNB +0);        ! check LNBs
      *JCC_7,<FAIL5>;                   ! LNBs dont agreee
      *AND_-2; *ST_(DR );               ! remove bottom bit which can
                                        ! be left by precall before *ACT
!
! Copy B,ACC,CC &PM to new context
!
      *LB_TOS ;                         ! MPSR word off stack
      *LSS_TOS ; *ST_(XNB +9);          ! transfer B
      *MPSR_B ; *L_TOS ;                ! restore ACC
      *MPSR_X'13'; *ST_(XNB +12);       ! ACC to new context
      *LSS_B ; *AND_X'FF0F';            ! get PM,CC&ACS
      *SLSS_(XNB +1); *AND_X'FF0000';   ! get ACC&PRIV before owrd call
      *OR_TOS ; *ST_(XNB +1);           ! & combine into new PSR
      *LSS_(5); *ST_(XNB +5);           ! transfer interval timer
      *LSS_(6); *ST_(XNB +6);           ! transfer instrn counter
      *LSS_X'3FFE'; *ST_(3);            ! mask out all int bar  sys err
      *J_<ASSACT>;                      ! and activate on former stack
NOCANDO:                                ! failure off to contingency
      *MPSR_TOS ;                       ! reset ACC size
      *LB_TOS ;                         ! reset B
      *L_TOS ;                          ! reset ACC
      *LD_(LNB +3);                     ! reset sytem call descriptor
      *OUT_15;                          ! stack switch & exit
!
! Failure . Return failure subclass (SYSTEM B compatalble where possible)
! in XNB this being only register available.(nb XNB has only 30 bits!)
!
FAIL0:   *LXN_0; *J_<NOCANDO>
FAIL1:   *LXN_4; *J_<NOCANDO>
FAIL2:   *LXN_8; *J_<NOCANDO>
FAIL3:   *LXN_12; *J_<NOCANDO>
FAIL4:   *LXN_16; *J_<NOCANDO>
FAIL5:   *LXN_20; *J_<NOCANDO>
FAIL6:   *LXN_24; *J_<NOCANDO>
FAIL33:  *LXN_132; *J_<NOCANDO>
FAIL34:  *LXN_136; *J_<NOCANDO>
!***Z
END ; ! of ROUTINE SYSTEMCALL!
!
!
!------------------------------------------------------------------------
EXTERNALROUTINE  BMOVE(RECORD (PARMF)NAME  P)
!***********************************************************************
!*       Called on service 36 to transfers groups of pages between     *
!*       fast devices. Replies are on service 37.                      *
!*       Fast device types are:-                                       *
!*       dev=1 drum     (specified as service & page in amem )         *
!*       dev=2 discfile (specified as [mnemonic or lvn] & page)        *
!*       dev=3 archtape (specified as service(preposnd by VOLUMS))     *
!*       dev=4 tape     (specified as string(6)lab,byte chap no)       *
!*       dev=5 funny    (reads give zero page,writes in hex to lp)     *
!*       dev=6 sink       (throws away input for tape checking)        *
!*                                                                     *
!*       Can handle up to four moves at a time. Each move uses         *
!*       one buffer and apart from clears only has one transfer        *
!*       outstanding at any one time time.                             *
!*       Failure flags (returned in P_P1) are as follows (at least     *
!*       for moves to/from disc):                                      *
!*                                                                     *
!*       P_P1 = RW<<24  !  FAIL<<16  !  RELPAGE                        *
!*                                                                     *
!*       where  RW = 1  means a READ failed                            *
!*                   2  means a WRITE failed.                          *
!*              FAIL = flag from PDISC:                                *
!*                         1 = transferred with errors (i.e. cyclic    *
!*                             check fails)                            *
!*                         2 = request rejected                        *
!*                         3 = transfer not effected (e.g. flagged     *
!*                             track encountered)                      *
!*          and RELPAGE = relative page no of failing page, counting   *
!*                        first page of request as one.                *
!***********************************************************************
INTEGERFNSPEC  CHECK(INTEGERNAME  MNEM, PAGE, INTEGER  RTYEP)
CONSTINTEGER  MAXSTREAMS=8
RECORDFORMAT  BME(INTEGER  DEST, SRCE, STEP, COUNT, FDEV,  C 
      TODEV, L, FDINF1, FDINF2, TODINF1, TODINF2, IDENT, CORE C 
      , READ, CDEX, UFAIL, WTRANS, FVL1, FVL2, TVL1, TVL2)
OWNRECORD (BME)ARRAY  BMS(1:MAXSTREAMS)
RECORD (BME)NAME  BM
OWNINTEGER  MASK=0,BMSEMA=-1
CONSTINTEGER  TRANSIZE=1024*EPAGESIZE;  ! BM TRANSFER SIZE
CONSTINTEGER  TAPE POSN=9, FILE POSN=8, WRITE=2, READ PAGE=1
CONSTINTEGER  WRITETM=10, MAX TRANS=16, REWIND=17, BACK READ=6
CONSTINTEGER  REQSNO=X'240000', PRIVSNO=X'250000', MAXMASK= C 
      (-2)!!X'FFFFFFFF'<<(MAXSTREAMS+1),  C 
      GETPAGE=X'50000', RETURNPAGE=X'60000',  C 
      CLAIM TAPE=X'31000C', RELEASE TAPE=X'310007', COMREP= C 
      X'3E0001', ZEROEPAGEAD=X'804C0000', PDISCSNO=X'210000'
INTEGER  I, INDEX, PAGE, FILE, SNO, FAIL
SWITCH  STEP(1:12)
!
      IF  MONLEVEL&2#0 AND  KMON>>(P_DEST>>16)&1#0  THEN  C 
         PKMONREC("MOVE: ",P)
      IF  P_DEST>>16=PRIVSNO>>16 START ;   !NAME MNEM,PAGEREPLY
         INDEX=P_DEST&255
         IF  1<<INDEX&MASK=0 THEN  START ;   ! THIS SLOT NOT IN USE!
            PKMONREC("MOVE REJECTS :",P)
            RETURN 
         FINISH 
         BM==BMS(INDEX)
         FAIL=P_P2
         ->STEP(BM_STEP)
      FINISH 
!
! THIS THE THE ENTRY FOR A NEW REQUEST
!
      IF  MULTIOCP=YES THEN  START 
         *INCT_BMSEMA
         *JCC_8,<SEMAGOT1>
         SEMALOOP(BMSEMA,0)
SEMAGOT1:
      FINISH 
      CYCLE  INDEX=1,1,MAXSTREAMS
        IF  MASK&1<<INDEX=0 THEN  EXIT 
      REPEAT 
      BM==BMS(INDEX)
      MASK=MASK!1<<INDEX
      IF  MASK=MAXMASK THEN  INHIBIT(REQSNO>>16);! ALL BUFFERS IN USE
      IF  MULTIOCP=YES START ; *TDEC_BMSEMA; FINISH 
      BM_DEST=P_DEST
      BM_SRCE=P_SRCE
      BM_FDEV=P_P1>>24
      BM_TODEV=P_P1>>16&255
      BM_READ=READ PAGE
      IF  P_P1&X'8000'#0 THEN  BM_READ=BACK READ
      BM_L=P_P1&X'7FFF'
      BM_FDINF1=P_P2
      BM_FDINF2=P_P3
      BM_TODINF1=P_P4
      BM_TODINF2=P_P5
      BM_IDENT=P_P6
      BM_COUNT=0; BM_STEP=0
      BM_UFAIL=0; BM_FVL1=0; BM_FVL2=0
      BM_WTRANS=0; BM_TVL1=0; BM_TVL2=0
      IF  BM_L=0 THEN  ->REQFAIL;       ! MOVE 0 PAGES DISALLOWED
      IF  BM_FDEV=2 AND  CHECK(BM_FDINF1,BM_FDINF2,READPAGE)#0 C 
         THEN  ->REQFAIL
      IF  BM_TODEV=2 AND  CHECK(BM_TODINF1,BM_TODINF2,WRITE)#0C 
         THEN  ->REQFAIL
      IF  BM_TODEV=3 AND  (BM_TODINF2>2 OR  BM_TODINF2<0) C 
            THEN  ->REQFAIL;            ! 0,1,OR 2 TMARKS ONLY ALLOWED
!
! PON A CHECK BLOCKS ACTIVE TO ACTIVEMEM. TEMPORARY TO FIND BUG
!
!      %IF BM_TODEV=2 %START
!         P_DEST=X'00080006'
!         %CYCLE   I=0,1,BM_L-1
!            P_P1=BM_TODINF2+I
!            PON(P)
!         %REPEAT
!      %FINISH
      P_DEST=GETPAGE;                  ! REQUEST ONE (EXTENDED) PAGE
      BM_STEP=0
      IF  BM_FDEV>=5 START 
         BM_CDEX=0
         BM_CORE=ZEROEPAGEAD
         ->CORE GOT
      FINISH 
PONIT:P_SRCE=PRIVSNO!INDEX
      BM_STEP=BM_STEP+1
      PON(P)
      RETURN 
STEP(1):                               ! CORE PAGE FROM CORE ALLOT
      BM_CDEX=P_P2;                     ! CORE INDEX NO(FOR RETURNING)
      BM_CORE=P_P4
CORE GOT:                              ! BY HOOK OR BY CROOK
      ->FDEVPOSD UNLESS  BM_FDEV=4; ! UNLESS A MAG TAPE
!
! CODE HERE TO CLAIM THE INPUT TAPE AND PUT ITS SERVICE NO IN INF1
!
      IF  BM_FDINF1>>24#0 START ;       ! TAPE LABEL NOT SERVICE NO
         P_DEST=CLAIM TAPE
         P_P2=X'00040001';              ! TAPE FOR READING
         P_P3=BM_FDINF1; P_P4=BM_FDINF2; P_P6=0
         BM_FVL1=BM_FDINF1; BM_FVL2=BM_FDINF2;! REMEMBER FOR RELEASE
         BM_STEP=1; ->PONIT
STEP(2):                                ! REPLY FROM CLAIM TAPE
         IF  P_P2#0 THEN  ->POSFAIL
         BM_FDINF1=P_P3;                ! SERVICE NO FOR TAPE
         BM_FDINF2=BM_FDINF2&255;       ! CHAPTER NO OF FILE
      FINISH 
      SNO=BM_FDINF1
      BM_STEP=2
      FILE=BM_FDINF2&255
TAPEPOS:                               ! TAPE POSITION TO 'FILE' 
      P_DEST=SNO
      P_P1=FILE;                       ! IDENT FOR LATER
      P_P2=REWIND
      ->PONIT;                      ! SKIP BACK TO BT
STEP(3):                               ! FROM TAPE AT BT
STEP(6):                               ! TO TAPE AT BT
      ->POSFAIL UNLESS  FAIL=4 OR  FAIL=0
      P_DEST=P_SRCE
      P_P2=P_P1<<16!1<<8!TAPE POSN
      ->PONIT;                      ! SKIP FORWARD N FILES
STEP(4):                               ! FROMTAPE AT RIGHT FILE
      ->POSFAIL UNLESS  FAIL=0
!
! THIS BULK MOVER MOVES TAPE CHAPTERS ONLY
!
FDEVPOSD:
      ->POSCOMPLETE UNLESS  BM_TODEV=4;     ! OPUT TAPE NEEDS POSITIONING
!
! CODE HERE TO CLAIM THE OUTPUT TAPE
!
      IF  BM_TODINF1>>24#0 START ;      ! TAPE GIVEN AS LABEL NOT SNO
         P_DEST=CLAIM TAPE
         P_P2=X'00040002';              ! TAPE FOR WRITING
         P_P3=BM_TODINF1; P_P4=BM_TODINF2; P_P6=0
         BM_TVL1=BM_TODINF1; BM_TVL2=BM_TODINF2
         BM_STEP=4; ->PONIT
STEP(5):                                ! REPLY FROM CLAIM OUTPUT TAPE
         IF  P_P2#0 THEN  ->POSFAIL
         BM_TODINF1=P_P3
         BM_TODINF2=BM_TODINF2&255;     ! CHAPTER NO
      FINISH 
      SNO=BM_TODINF1
      FILE=BM_TODINF2&255
      BM_STEP=5
      ->TAPEPOS
STEP(7):                               ! BOTH DEVICES POSITONED
      ->POSFAIL UNLESS  FAIL=0
POSCOMPLETE:
READ PG:
      BM_COUNT=BM_COUNT+1
      IF  BM_FDEV<5 THEN  START ;   ! NOT FROM A ZERO PAGE
         P_DEST=BM_FDINF1
         P_P3=BM_CORE
         IF  BM_FDEV=3 OR  BM_FDEV=4 THEN  START 
            P_P2=TRANSIZE<<16!BM_READ
         FINISH  ELSE  START 
            P_P2=BM_FDINF2-1+BM_COUNT
         FINISH 
         BM_STEP=7
         P_P1=BM_COUNT
         ->PONIT
      FINISH  ELSE  FAIL=0
STEP(8):                               ! PAGE READ
      ->READ FAIL UNLESS  FAIL=0
      IF  BM_TODEV<5 THEN  START 
         CYCLE 
            P_DEST=BM_TODINF1
            P_SRCE=PRIVSNO!INDEX
            BM_STEP=8
            P_P3=BM_CORE
            IF  BM_TODEV=4 OR  BM_TODEV=3 THEN  START 
                  P_P2=TRANSIZE<<16!WRITE
            FINISH  ELSE  START 
               P_P2=BM_TODINF2-1+BM_COUNT
            FINISH 
            P_P1=BM_COUNT
            PON(P)
            BM_STEP=9
            BM_WTRANS=BM_WTRANS+1
            RETURN  IF  BM_FDEV<5 OR  BM_WTRANS>=MAX TRANS OR  C 
               BM_COUNT>=BM_L
            BM_COUNT=BM_COUNT+1
         REPEAT 
      FINISH  ELSE  START 
         BM_WTRANS=BM_WTRANS+1
         DUMPTABLE(34,BM_CORE,TRANSIZE)IF  BM_TODEV=5
      FINISH 
STEP(9):                               ! PAGE WRITTEN
      BM_WTRANS=BM_WTRANS-1
      ->WRITEFAIL UNLESS  FAIL=0
      ->READ PG IF  BM_COUNT<BM_L AND  BM_UFAIL=0
      RETURN  UNLESS  BM_WTRANS=0
!
STEP(10):                              !FIRST TM WRITE
      ->TMFAIL UNLESS  FAIL=0
      P_DEST=BM_TODINF1
      P_P1=M'BMTM'
      P_P2=WRITE TM
      IF  BM_TODEV=3 AND  BM_TODINF2#0 START ;! ARCH TAPE NEEDS TM?
         BM_STEP=BM_STEP+2-BM_TODINF2;  ! ONE OR TWO TMS
         ->PONIT
      FINISH 
      ->PONIT IF  BM_TODEV=4
STEP(11):                              !BOTH TMS WRITTEN
      ->TMFAIL UNLESS  FAIL=0
WAYOUT:                                !DEALLOCATE CORE
      RETURN  UNLESS  BM_WTRANS=0
      P_DEST=RETURN PAGE
      P_SRCE=0;                        ! REPLY NOT WANTED
      P_P2=BM_CDEX
      PON(P) UNLESS  BM_FDEV>=5;       ! RETURN CORE
      P_DEST=RELEASE TAPE
      P_SRCE=COMREP
      IF  BM_FDEV=4 AND  BM_FVL1#0 START 
         P_P2=X'00040000'!BM_FDINF1&X'FFFF'
         P_P3=BM_FVL1; P_P4=BM_FVL2; P_P5=1
         PON(P);                        ! RELEASE FROM TAPE
      FINISH 
      IF  BM_TODEV=4 AND  BM_TVL1#0 START 
         P_P2=X'00040000'!BM_TODINF1&X'FFFF'
         P_P3=BM_TVL1; P_P4=BM_TVL2; P_P5=1
         PON(P);                        ! RELEASE OUTPUT TAPE
      FINISH 
REPLY:                                 !SET UP REPLY
      P_DEST=BM_SRCE
      P_SRCE=REQSNO
      P_P1=BM_UFAIL
      P_P2=BM_IDENT
      PON(P);                       !REPLY TO REQUEST
      IF  MULTIOCP=YES THEN  START 
         *INCT_BMSEMA
         *JCC_8,<SEMAGOT2>
         SEMALOOP(BMSEMA,0)
SEMAGOT2:
      FINISH 
      IF  MASK=MAXMASK THEN  UNINHIBIT(REQSNO>>16)
      MASK=MASK!!1<<INDEX
      IF  MULTIOCP=YES START ; *TDEC_BMSEMA; FINISH 
      RETURN 
REQFAIL:                               ! FAULT WITH REQUEST
      BM_UFAIL=-2
      ->REPLY
POSFAIL:                               ! UNABLE TO POS TAPE
      BM_UFAIL=-3
      ->WAYOUT
TMFAIL:                                 ! TAPE MARK DID NOT WRITE!
      ->ETWONTM IF  FAIL=4
      BM_UFAIL=-4 IF  BM_UFAIL=0
      ->WAYOUT
ETWONTM:                                ! END OF TAPE WARNING
      BM_UFAIL=-5
      ->WAYOUT
!
! The format of the failure flags given below is described in comment at
! the head of this routine.
!
READFAIL:                              ! UNABLE TO READ
      IF  BM_UFAIL=0 THEN  C 
         BM_UFAIL=READPAGE<<24!P_P1!FAIL<<16
      ->WAYOUT
WRITEFAIL:                             ! UNABLE TO WRITE PAGE
      IF  BM_UFAIL=0 THEN  C 
         BM_UFAIL=WRITE<<24!P_P1!FAIL<<16
      ->WAYOUT
!
INTEGERFN  CHECK(INTEGERNAME  MNEM,PAGE,INTEGER  RTYPE)
!***********************************************************************
!*    CHECKS A DISC ID VOR VALIDITY & AVAILABILITY                     *
!***********************************************************************
RECORDFORMAT  DDTFORM(INTEGER  SER, PTS, PROPADDR, STICK, STATS,  C 
      RQA, LBA, ALA, STATE, IW1, IW2, SENSE1, SENSE2, SENSE3,  C 
      SENSE4, REPSNO, BASE, ID, DLVN, MNEMONIC,  C 
      STRING  (6) LAB, BYTEINTEGER  MECH)
RECORD (DDTFORM)NAME  DDT
INTEGER  I,L,V1,V2
      L=6; V1=MNEM; V2=PAGE
      CYCLE  I=0,1,COM_NDISCS-1
         DDT==RECORD(INTEGER(COM_DITADDR+4*I))
         IF  (DDT_MNEMONIC=MNEM OR  STRING(ADDR(L)+3)=DDT_LABOR  C 
            MNEM=DDT_DLVN&X'FFFF') AND  4<=DDT_STATE<=7 THEN  START 
            MNEM=PDISCSNO!RTYPE
            IF  STRING(ADDR(L)+3)=DDT_LAB THEN  PAGE=PAGE&X'FFFF'
            PAGE=PAGE!DDT_DLVN<<24
            RESULT =0
         FINISH 
      REPEAT 
      RESULT =1
END ; ! OF CHECK
!
!
!
END ; ! OF MOVE
!
!
!
ENDOFFILE