!* !* GPC/DCU driver !* %CONSTSTRING(26) VSN=".GDC02 - 4th May 1983" %OWNINTEGER IVSN=M'GDC2' !* %RECORDFORMAT PARMF(%INTEGER DEST,SRCE,(%INTEGER P1,P2,P3,P4,P5,P6 %OR %C %STRING(23)TEXT)) !* !* !* 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 !* %EXTERNALINTEGERFNSPEC REALISE(%INTEGER VAD) %EXTERNALROUTINESPEC PON(%RECORD(PARMF)%NAME P) %EXTERNALROUTINESPEC SLAVESONOFF(%INTEGER I) %EXTERNALROUTINESPEC GET PSTB(%INTEGERNAME PSTL,PSTB) %EXTERNALROUTINESPEC SEMALOOP(%INTEGERNAME SEMA,%INTEGER PARM) %EXTERNALROUTINESPEC WAIT(%INTEGER MILLSECS) %EXTERNALROUTINESPEC DUMPTABLE(%INTEGER T,A,L) %EXTERNALROUTINESPEC PKMONREC(%STRING(20)TXT,%RECORD(PARMF)%NAME P) %EXTERNALSTRINGFNSPEC HTOS(%INTEGER I,PL) %EXTERNALSTRINGFNSPEC STRINT(%INTEGER N) %EXTERNALROUTINESPEC OPMESS(%STRING(63)S) %SYSTEMROUTINESPEC MOVE(%INTEGER L,F,T) %IF MULTI OCP=YES %START %EXTERNALROUTINESPEC RESERVE LOG %EXTERNALROUTINESPEC RELEASE LOG %FINISH %IF SSERIES=NO %START %INTEGERFNSPEC GPC INIT(%INTEGER PT,FLAG) %RECORDFORMAT CASEF(%INTEGER SAW0,SAW1,RESP0,RESP1) %RECORDFORMAT CAF(%INTEGER MARK,PAW,PIW0,PIW1,CSAW0,CSAW1,CRESP0,CRESP1, %C %RECORD(CASEF)%ARRAY STREAM(0:14)) %FINISH !* %CONSTINTEGER ABNORMAL TERMINATION=X'00400000' %CONSTINTEGER ATTENTION=X'00100000' %CONSTINTEGER CONTROLLER DETECTED ERROR=X'00410000' %CONSTINTEGER DISCONNECTED=5 %CONSTINTEGER ENDLIST=255 %CONSTINTEGER FE=14 %CONSTINTEGER LOID=X'6E' %CONSTINTEGER LP=6 %CONSTINTEGER MT=5 %CONSTINTEGER MTMASK=X'FFFF30' %CONSTINTEGER NORMAL TERMINATION=X'00800000' %CONSTINTEGER NOT ALLOCATED=0 %CONSTINTEGER OK=0 %CONSTINTEGER OP=8 %CONSTINTEGER QUEUED=4 %CONSTINTEGER READY=1 %CONSTINTEGER REQUEST FIRED=2 %CONSTINTEGER SLOT SIZE=32 %CONSTINTEGER SU=13 %CONSTINTEGER TICK INTERVAL=2 %CONSTINTEGER ZX=11 !* %OWNBYTEINTEGERARRAYFORMAT BIFT(0:1023) %OWNINTEGERARRAYFORMAT IFT(0:1023) !* %OWNINTEGER SETUP=NO %OWNINTEGER GDCT BASE %OWNINTEGER LAST SLOT %OWNINTEGER LOCNO %OWNINTEGER NO OF GDCS %OWNBYTEINTEGERARRAYNAME MECHSLOTS %OWNBYTEINTEGERARRAYNAME CSTRM TO SLOT %OWNBYTEINTEGERARRAYNAME CNO TO GDC %OWNBYTEINTEGERARRAYNAME STRM Q %OWNINTEGERARRAYNAME CAAS %OWNINTEGERARRAYNAME TABLE %OWNINTEGERARRAYNAME STRM SEMAPHORE !* %CONSTINTEGER KMONNING=2 %IF MONLEVEL&KMONNING#0 %START %EXTERNALLONGINTEGERSPEC KMON %FINISH !* %CONSTINTEGER GDC DEST=X'300000' %CONSTINTEGER GDC SNO=GDC DEST>>16 %IF CSU FITTED=YES %START %CONSTINTEGER CSU DEST=X'290000' %FINISH !* %EXTERNALROUTINE GDC(%RECORD(PARMF)%NAME P) !* %IF SSERIES=YES %START; ! DCU specific declarations %EXTERNALROUTINESPEC DISC(%RECORD(PARMF)%NAME P) %EXTERNALROUTINESPEC DCU1 RECOVERY(%INTEGER PARM) %EXTERNALINTEGERSPEC DCU RFLAG; ! reconnect DCU1 streams if non-zero %ROUTINESPEC FIRE IDENTIFY %RECORDFORMAT DEVICE ENTRY F(%INTEGER %C SER, DSSMM, PROPADDR, SECS SINCE, CAA, MYCCBA, %C %BYTEINTEGER MECH,ATTN,SP1,SP2,%INTEGER LAST TCB ADDR, %C X2, RESP0, X3, SENSE1, SENSE2, SENSE3, SENSE4, %C REPSNO, BASE, ID, DLVN, MNEMONIC, %C %STRING (6) LABEL, %BYTE %INTEGER HWCODE, %C %INTEGER ENTSIZE, UCCBA, SENSDAT AD, LOGMASK, TRTAB AD, %C UA SIZE, UA AD, TIMEOUT,PROPS0,PROPS1) %RECORDFORMAT CCBF(%INTEGER COMMAND,STE,LEN,DATA,NTCB,RESP, %C %INTEGERARRAY PREAMBLE,POSTAMBLE(0:3)) %RECORDFORMAT CAF(%INTEGER IAWA,SEMA) %OWNBYTEINTEGERARRAYFORMAT LBIFT(0:2047) %CONSTINTEGER CONNECT TERM=X'00201000' %CONSTINTEGER DISCONNECT TERM=X'00202000' %CONSTINTEGER DISC DEST=X'200000' %CONSTINTEGER EDS100=X'33',FDS640=X'3B' %CONSTINTEGER IDENTIFY FIRED=3 %CONSTINTEGER INIT FAIL=X'00200000' %CONSTINTEGER INVALID ACTIVATE=X'00400000' %CONSTINTEGER MSPC=256; ! max streams/DCU %CONSTINTEGER POST AMBLE VALID=X'00004000' %CONSTINTEGER PRIMITIVE=X'00800000' %CONSTINTEGER RESET STREAM=6 %CONSTINTEGER SENSE FAIL=X'00100000' %CONSTINTEGER START STREAM=2 %CONSTINTEGER STOP STREAM=4 %CONSTINTEGER STREAM ABTERM=X'00000400' %CONSTINTEGER STREAM ATTENTION=X'00004000' %CONSTINTEGER STREAM INT=X'00200000' %CONSTINTEGER STREAM TTERM=X'00008000' %CONSTINTEGER STREAM CTERM=CONNECT TERM!DISCONNECT TERM %CONSTINTEGER STREAM IA=STREAM INT!STREAM ATTENTION %CONSTINTEGER STREAM ITA=STREAM IA!STREAM TTERM %CONSTINTEGER TCB ATTN=X'20000000' %CONSTINTEGER TCB CONT=X'00800000' %CONSTINTEGER TCB FAIL=X'C0000000' %CONSTINTEGER TCB LENGTH=14*4 %INTEGER INTWD %LONGINTEGER L !* I/O control declarations %ROUTINESPEC ACTIVATE(%INTEGER ACTWD,TCBAD,ISAD) %ROUTINESPEC FIRE DCU2(%INTEGER UTAD,TCBAD,ACT) %EXTERNALINTEGERFNSPEC NEW PP CELL %EXTERNALROUTINESPEC RETURN PP CELL(%INTEGER CELL) %EXTERNALLONGINTEGERSPEC PARMDES %RECORDFORMAT QACT F(%INTEGER ACTWD,TCBAD,ISAD,P2,P3,P4,P5,P6,LINK) %RECORD(QACT F)%NAME QACT %RECORD(QACT F)%ARRAYFORMAT PARMAF(0:65535) %OWNRECORD(QACT F)%ARRAYNAME PARM %OWNINTEGER QHEAD=0 %OWNINTEGER ACTS QD=0,MAX Q=0,ACT CYCLES=0 %IF MULTI OCP=YES %START %OWNINTEGER DCU1 SEMA=-1,DCU2 SEMA=-1 %OWNINTEGER RECOVER DCU1S=0 %FINISH %INTEGER ISAD,SINK !* %FINISH %ELSE %START; ! GPC specific declarations %EXTERNALROUTINESPEC CONTROLLER DUMP(%INTEGER CONTYPE,PT) %RECORDFORMAT DEVICE ENTRY F(%INTEGER SER, GPTSM, PROPADDR, %C SECS SINCE, CA A, MYCCBA, LB A, AL A, X2, RESP0, %C RESP1, SENSE1, SENSE2, SENSE3, SENSE4, X3, X4, IDENT %C , X5, MNEMONIC, DEVICE ENTRY S, PAW, U SAW 0, %C U CCB A, SENSE DATA A, LOG MASK, TRTAB AD, UA SIZE, %C UA AD, TIMEOUT, PROPS0, PROPS1) %RECORDFORMAT CCBF(%INTEGER LIMFLAGS,LSTA,LBS,LBA,ALS,ALA,INIT,X1) %RECORDFORMAT ALEF(%INTEGER S,A) %RECORD(CASEF)%NAME STREAM %OWNBYTEINTEGERARRAYFORMAT LBIFT(0:511) %CONSTINTEGER DO STREAM REQUEST=X'01000000' %CONSTINTEGER GET STRM DATA=16 %CONSTINTEGER MSPC=16; ! max streams/GPC %CONSTINTEGER PRIV ONLY=X'4000' %CONSTINTEGER RCB BOUND=32 %CONSTINTEGER SENSE FIRED=3 %STRING(23)WK %INTEGER PAW FN,USAW0,PT,PIW0 !* %FINISH !* %RECORDFORMAT GDCT F(%BYTEINTEGER FLAGS,DEVTYPE,ATTN,LINK, %C (%INTEGER Q %OR %INTEGER X4), %C %INTEGER RESPONSE DEST,DEVICE ENTRY A, %C (%INTEGER CSTATUS,PTSM %OR %INTEGER UTAD,DSSMM), %INTEGER MNEMONIC, %C %BYTEINTEGER MECHINDEX,PROPS03,SERVRT,STATE) !* %RECORD(DEVICE ENTRY F)%NAME DEV %RECORD(GDCT F)%NAME GDCT,GE %RECORD(CCBF)%NAME CCB %RECORD(PARMF) Q %RECORD(CAF)%NAME CA !* %ROUTINESPEC CONNECT STREAM(%INTEGER CNO,CAA,STRM,CONNECT,TIMEOUT) %ROUTINESPEC FAIL TRANSFER(%RECORD(GDCTF)%NAME G,%INTEGER SLOT) %INTEGERFNSPEC FIND(%INTEGER MNEMONIC) %STRINGFNSPEC MTOS(%INTEGER MNEMONIC) %ROUTINESPEC READ STREAM DATA(%RECORD(GDCTF)%NAME G) %ROUTINESPEC REPLY(%INTEGER SRCE,%STRING(23)TEXT) %INTEGERFNSPEC STATE CHECK(%INTEGER MNEMONIC,STATE) %ROUTINESPEC STATUS(%INTEGER SLOT) %INTEGERFNSPEC TRANS MNEMONIC(%STRINGNAME S) !* %CONSTINTEGER LIMIT=3 %CONSTSTRING(4)%ARRAY COMMAND(1:LIMIT)="QS ","CDS ","CDM " %CONSTSTRING(9)%ARRAY STATES(0:5) = "not alloc", "ready", "req fired", "sns fired", "queued", "discncted" !* !* Declarations for CDM !* %CONSTINTEGER CDMDEVLIMIT=6 %CONSTINTEGERARRAY CDMDEV(0:CDMDEVLIMIT)=%C M'FE',M'LP',M'CR',M'CP',M'PR',M'PT',M'SU' %CONSTBYTEINTEGERARRAY CDMDEVTYPE(0:CDMDEVLIMIT)=14,6,4,3,2,1,13 %CONSTINTEGERARRAY CDMDEVTIMEOUT(0:CDMDEVLIMIT)=%C X'01FF0003',60,300,600,60,60,10; ! top of FEP word is logmask !* %EXTERNALINTEGER LP ILLCHAR=X'07'; ! ERCC value (also used by GROPE) !* !* LP repertoire addresses and lengths for each of 16 cartidge settings !* %OWNINTEGERARRAY REPERTOIRE A(0:15) %OWNINTEGERARRAY REPERTOIRE S(0:15) !* !%CONSTINTEGERARRAY LP96REP(0:23)=c !%CONSTINTEGERARRAY LP384REP(0:95)=c !%CONSTBYTEINTEGERARRAY LCLETTS(1:26)=c %ENDOFLIST %CONSTINTEGERARRAY LP96REP(0:23)=%C X'F0F1F2F3',X'F4F5F6F7',X'F8F94B60',X'7B6B614E',X'C1C2C3E9', X'C4E4E2E3',X'C7C57DC8',X'D1D2D85C',X'D4D5D6D7',X'D9C9C6D3', X'E5E6E7E8',X'7E4D505D',X'4C6D3F6E',X'5B7A7C4F',X'6C5E7F6F', X'4AE05F5A',X'A8A979F0',X'81828384',X'85868788',X'89919293', X'94959697',X'9899A2A3',X'A4A5A6A7',X'C06AA1D0' !* %CONSTINTEGERARRAY LP384REP(0:95)= %C X'F0F1F2F3',X'F4F5F6F7',X'F8F94B9C',X'7B6B614E', X'C1C2C3E9',X'C4E4E2E3',X'C7C57DC8',X'D1D2D85C', X'D4D5D6D7',X'D9C9C6D3',X'E5E6E7E8',X'7E4D505D', X'6C5E7F6F',X'4AE05F5A',X'4C6D3F6E',X'5B7A7C4F', X'81828384',X'85868788',X'89919293',X'F0F1F2F3', X'F4F5F6F7',X'F8F94B60',X'94959697',X'9899A2A3', X'A4A5A6A7',X'A8A979F0',X'9EADEFCA',X'7B6B614E', X'C1C2C3E9',X'C4E4E2E3',X'C7C57DC8',X'D1D2D85C', X'D4D5D6D7',X'D9C9C6D3',X'E5E6E7E8',X'7E4D505D', X'6C5E7F6F',X'4AB7A05A',X'F0F1F2F3',X'F4F5F6F7', X'F8F94B60',X'4CF08B6E',X'5B7A7C4F',X'C06AA1D0', X'9A6D749B',X'FCEAAFED',X'ACAB8F8E',X'8DB5B4B3', X'787776DC',X'DDDEDFB8',X'B9BABBB0',X'7B6B614E', X'C1C2C3E9',X'C4E4E2E3',X'C7C57DC8',X'D9C9C6D3', X'D1D2D85C',X'F0F1F2F3',X'F4F5F6F7',X'F8F94B60', X'D4D5D6D7',X'E5E6E7E8',X'7E4D505D',X'6C5E7F6F', X'4AE05F5A',X'4CF08B6E',X'5B7A7C4F',X'A8A979F0', X'81828384',X'85868788',X'89919293',X'94959697', X'9899A2A3',X'A4A5A6A7',X'B1B2FAFB',X'C1C2C3E9', X'F0F1F2F3',X'F4F5F6F7',X'F8F94B60',X'7B6B614E', X'C4E4E2E3',X'C7C57DC8',X'D9C9C6D3',X'D1D2D85C', X'D4D5D6D7',X'E5E6E7E8',X'7E4D505D',X'6C5EDBCB', X'4AB7A05A',X'4CF08B6E',X'5B7A7C4F',X'EBBC75BD', X'8CAEBFBE',X'B6AAFDFE',X'9DEE80DA',X'C06D6AD0' !* %CONSTBYTEINTEGERARRAY LCLETTS(1:26)= %C X'81',X'82',X'83',X'84',X'85',X'86',X'87',X'88',X'89', X'91',X'92',X'93',X'94',X'95',X'96',X'97',X'98',X'99', X'A2',X'A3',X'A4',X'A5',X'A6',X'A7',X'A8',X'A9' %LIST !* %SWITCH GDC COMMAND(1:LIMIT) %SWITCH ACT(1:12) !* %STRING(23)TEXT %STRING(15)MNEMOS !* %BYTEINTEGERNAME QHD %BYTEINTEGERARRAYNAME REP,TRTAB !* %INTEGER DACT,SRCE,FLAG %INTEGER SLOT,STATE,GDCNO,FLAGS %INTEGER MNEMONIC,MNEMONIC1,MNEMONIC2 %INTEGER STRM,CAA,UCCBA,CNO,SEMA %INTEGER RESP0,RESP1 %INTEGER MECH %INTEGER I,J !* %IF MONLEVEL&KMONNING#0 %AND KMON>>GDC SNO&1#0 %START %IF SSERIES=YES %THEN PKMONREC("DCU :",P) %ELSE PKMONREC("GPC :",P) %FINISH DACT=P_DEST&X'FFFF' ->ACT(DACT) !* ACT(2): ! initialise %RETURN %UNLESS SETUP=NO SETUP=YES %IF SSERIES=YES %THEN PARM==ARRAY(INTEGER(ADDR(PARMDES)+4),PARMAF) J=P_P1; ! GDC table address TABLE==ARRAY(J,IFT); ! 1024 words TABLE(42)=P_P2; ! process picture %IF SSERIES=NO %THEN STRM SEMAPHORE==ARRAY(J+TABLE(40)<<2,IFT) !* ! protem for S series use CA_SEMA - need extra fields in ENTFORM !* GDCT BASE=J+TABLE(1)<<2; ! slot table address LASTSLOT=TABLE(2) NO OF GDCS=TABLE(3) !* reminders ! ! STRMQ addressed as 1) GDCNO<<4!STRM (was GPCNO<<4!STRM) ! or 2) GDCNO<<8!STRM (was DCUNO<<8!STRM) ! where GDCNO is logical GPC/DCU no. ! and got from:- ! ! CNO TO GDC as 1) CNO-LOCNO (was PT TO GPC(PT-LOPT)) ! or 2) CNO-LOCNO (was PT TO GPC(h/w DCU no.-LOPT)) ! ! CSTRM TO SLOT as 1) (PT-LOCNO)<<4!STRM (was PTS TO SLOT((PT-LOPT)<<4!STRM)) ! or 2) ((CNO-LOCNO)<<8!STRM) (was h/w/DCU no.-LOPT)<<8!STRM) !* STRMQ==ARRAY(J+TABLE(4)<<2,LBIFT); ! 1 byte per stream CSTRM TO SLOT==ARRAY(J+TABLE(5)<<2,LBIFT); ! ditto CNO TO GDC==ARRAY(J+TABLE(6)<<2,BIFT); ! CNO is pt for GPC, H/W DCU no. for DCU MECHSLOTS==ARRAY(J+TABLE(7)<<2,BIFT) CAAS==ARRAY(ADDR(TABLE(8)),IFT) LOCNO=255 %FOR J=0,1,NO OF GDCS-1 %CYCLE I=TABLE(16+J) %IF I>4; ! logical OPER no P=0 P_P1=GDCT_MNEMONIC P_P2=X'320005'!(I<<8); ! where we want OPER interrupts P_DEST=X'30000B'; ! allocate P_SRCE=X'320002'!(I<<8); ! allocate response to OPER PON(P) %FINISH %ELSE %IF GDCT_DEVTYPE=FE %START P=0 P_P1=GDCT_MNEMONIC P_P2=X'390005'; ! where we want FE interrupts P_DEST=X'30000B'; ! allocate P_SRCE=X'390002'; ! allocate response to FE adaptor PON(P) %FINISH %ELSE %IF GDCT_DEVTYPE=MT %START %IF GDCT_PTSM&15=0 %START; ! 1 call per cluster P=0 P_DEST=X'00310004' P_SRCE=X'00300000' P_P1=GDCT_MNEMONIC PON(P) %FINISH %FINISH %ELSE %IF CSU FITTED=YES %AND GDCT_DEVTYPE=SU %START P=0 P_DEST=CSU DEST; ! CSU initialise P_P1=GDCT_MNEMONIC PON(P) %FINISH %REPEAT %IF SSERIES=YES %AND COM_NDISCS>0 %START P=0 P_DEST=DISC DEST; ! initialise DISC PON(P) %FINISH !* PRINTSTRING(VSN) NEWLINE PRINTSTRING("GDC's tables:-") DUMPTABLE(0,ADDR(TABLE(0)),TABLE(0)<<2+4) !* P_DEST=X'A0001'; ! interval timer P_SRCE=0 P_P1=GDC DEST!6 P_P2=TICK INTERVAL PON(P) %RETURN !* !* ACT(11): ! allocate device %UNLESS FIND(P_P1)<0 %START %IF GDCT_STATE=NOT ALLOCATED %START FLAG=0 DEV==RECORD(GDCT_DEVICE ENTRY A) %IF GDCT_DEVTYPE=OP %START; ! extra info for OPERs I=GDCT_MECHINDEX>>4 DEV_SER=TABLE(I+32)&X'FFFF'; ! buffer size DEV_X2=DEV_CAA+TABLE(I+32)>>16; ! buffer address DEV_RESP0=GDCT_MECHINDEX&15; ! screens %FINISH %ELSE %IF GDCT_DEVTYPE=LP %THEN DEV_SER=GDCT_RESPONSE DEST; ! & LPs GDCT_STATE=READY GDCT_RESPONSE DEST=P_P2 P_P2=LOID+SLOT P_P3=ADDR(DEV) P_P6=GDCT_MNEMONIC %FINISH %ELSE FLAG=2 %FINISH %ELSE FLAG=1 ->ACKNOWLEDGE !* ACT(8): ! special forced allocate (CALL not PON) %UNLESS FIND(P_P1)<0 %START %UNLESS P_P1=M'LP' %AND GDCT_STATE=DISCONNECTED %START FLAG=0 GDCT_STATE=READY GDCT_RESPONSE DEST=P_P2 P_P2=LOID+SLOT P_P3=GDCT_DEVICE ENTRY A P_P6=GDCT_MNEMONIC %FINISH %ELSE FLAG=2 %FINISH %ELSE FLAG=1 P_P1=FLAG %RETURN ACT(5): ! deallocate %UNLESS P_P1=M'LP' %START %UNLESS FIND(P_P1)<0 %START STATE=GDCT_STATE %IF STATE=READY %OR (SSERIES=YES %AND STATE=IDENTIFY FIRED) %START %IF P_SRCE<<1>>17>63 %START;! from user process %IF 0>16<64 %THEN FLAG=4 %AND ->FALL; ! prohibit %FINISH %IF SSERIES=YES %AND STATE=IDENTIFY FIRED %THEN %C STRMQ(GDCT_DSSMM>>24<<8!(GDCT_DSSMM>>8)&255)=ENDLIST; ! clear identify GDCT_STATE=NOT ALLOCATED GDCT_FLAGS=0 P_P3=GDCT_DEVICE ENTRY A FLAG=0 %FINISH %ELSE FLAG=STATE<<16!3 %FINISH %ELSE FLAG=2 %FINISH %ELSE FLAG=1 FALL: ->ACKNOWLEDGE ACT(6): ! clocktick %IF SSERIES=YES %AND MULTI OCP=YES %AND RECOVER DCU1S#0 %START ! DCU1 recovery required in controlling OCP *LSS_(3); *USH_-26; *AND_3; *ST_I %IF I=COM_OCPPORT0 %START I=RECOVER DCU1S RECOVER DCU1S=0 DCU1 RECOVERY(I) OPMESS("DCU1 recovery initiated") %FINISH %ELSE %START P_SRCE=M'STIK' PON(P); ! try for other OCP %FINISH %RETURN %FINISH %IF SSERIES=YES %AND DCU RFLAG#0 %START ! reconnect of DCU1 streams required P_SRCE=0 P_P1=DCU RFLAG DCU RFLAG=0 ->RECON %FINISH %FOR SLOT=0,1,LASTSLOT %CYCLE GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) %IF GDCT_STATE=REQUEST FIRED %OR %C (SSERIES=YES %AND GDCT_STATE=IDENTIFY FIRED) %OR %C (SSERIES=NO %AND GDCT_STATE=SENSE FIRED) %START DEV==RECORD(GDCT_DEVICE ENTRY A) DEV_SECS SINCE=DEV_SECS SINCE+TICK INTERVAL %IF DEV_SECS SINCE>DEV_TIMEOUT %START %IF SSERIES=YES %AND GDCT_UTAD=0 %START ! recover any 'dead' DCU1s CA==RECORD(DEV_CAA) ISAD=CA_IAWA %IF MULTI OCP=YES %START *INCT_DCU1 SEMA *JCC_8, SEMALOOP(DCU1 SEMA,0) TSEMAG: %FINISH %FOR I=1,1,COM_INSPERSEC*2 %CYCLE; ! approx 20 millisecs *LB_ISAD; *LSD_0; *L_(0+%B); *STUH_SINK *JAT_4, %REPEAT ! activate word not cleared so assume DCU1 has died CNO=GDCT_DSSMM>>16&255 %IF MULTI OCP=YES %START *TDEC_DCU1 SEMA *LSS_(3); *USH_-26; *AND_3; *ST_I %UNLESS I=COM_OCPPORT0 %START RECOVER DCU1S=CNO; ! recover DCU1 in controlling OCP %RETURN %FINISH %FINISH DCU1 RECOVERY(CNO) OPMESS("DCU1 recovery initiated") %RETURN TOK: %IF MULTI OCP=YES %START; *TDEC_DCU1 SEMA; %FINISH %FINISH OPMESS(MTOS(GDCT_MNEMONIC)." timed out") !* !* diagnose & reset stream etc. !* %IF MULTI OCP=YES %START %IF SSERIES=YES %START CA==RECORD(DEV_CAA) SEMA=ADDR(CA_SEMA) %FINISH %ELSE SEMA=ADDR(STRM SEMAPHORE(GDCT_PTSM>>24!GDCT_PTSM>>4&15)) *LXN_SEMA; *INCT_(%XNB+0); *JCC_8, SEMALOOP(INTEGER(SEMA),0) TSEMAGOT: %FINISH FAIL TRANSFER(GDCT,SLOT) %IF SSERIES=YES %THEN STRMQ(GDCT_DSSMM>>24<<8!GDCT_DSSMM>>8&255)=ENDLIST %C %ELSE STRMQ(GDCT_PTSM>>16<<4!GDCT_PTSM>>4&15)=ENDLIST %IF GDCT_DEVTYPE=MT %START; ! fail Q'ed MT requests aussi %CYCLE I=GDCT_LINK %EXIT %IF I=ENDLIST GDCT_LINK=ENDLIST GDCT==RECORD(GDCT BASE+I*SLOT SIZE) FAIL TRANSFER(GDCT,I) %REPEAT %FINISH %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH %FINISH %FINISH %REPEAT %RETURN ACT(12): ! execute request SLOT=P_P2&X'FFFF'-LOID %IF 0<=SLOT<=LASTSLOT %START; ! valid slot GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) %IF SSERIES=YES %START I=0; *INCT_I; ! clear operand slaves GDCNO=GDCT_DSSMM>>24 STRM=GDCT_DSSMM>>8&255 %FINISH %ELSE %START GDCNO=GDCT_PTSM>>16 PT=GDCT_PTSM>>8&255 STRM=GDCT_PTSM>>4&15 PAW FN=(P_P3&X'F0')<<20!STRM USAW0=(P_P3&15)<<28!RCB BOUND %FINISH DEV==RECORD(GDCT_DEVICE ENTRY A) UCCBA=P_P1 %IF SSERIES=YES %START %UNLESS UCCBA&7=0 %AND UCCBA>>18=DEV_UA AD>>18 %START FLAG=M'BTCB' P_P3=UCCBA ->ACKNOWLEDGE ! bad TCBs can cause havoc !!! %FINISH %FINISH CA==RECORD(DEV_CAA) %IF MULTI OCP=YES %START %IF SSERIES=YES %THEN SEMA=ADDR(CA_SEMA) %ELSE %C SEMA=ADDR(STRM SEMAPHORE(GDCNO<<4!STRM)) *LXN_SEMA; *INCT_(%XNB+0); *JCC_8, SEMALOOP(INTEGER(SEMA),0) SSEMAGOT: %FINISH %IF GDCT_STATE=READY %START %IF SSERIES=YES %THEN QHD==STRMQ(GDCNO<<8!STRM) %ELSE %C QHD==STRMQ(GDCNO<<4!STRM) %IF QHD=ENDLIST %START; ! ok to fire I/O GDCT_LINK=ENDLIST QHD=SLOT GDCT_STATE=REQUEST FIRED %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH %IF SSERIES=YES %START %IF GDCT_UTAD=0 %THEN ACTIVATE(X'01000000'!STRM,UCCBA,CA_IAWA) %C %ELSE FIRE DCU2(GDCT_UTAD,UCCBA,START STREAM) ! *** put code in-line for speed *** %FINISH %ELSE %START STREAM==CA_STREAM(STRM) %IF CA_PAW#0 %THEN PRINTSTRING("GPC--PAW not cleared - PT". %C HTOS(PT,2).",PAW = ".HTOS(CA_PAW,8)." ") *LXN_CA+4; *INCT_(%XNB+0); *JCC_8, SEMALOOP(CA_MARK,2) CAAG: CA_PAW=PAW FN STREAM_SAW0=USAW0 STREAM_SAW1=UCCBA CA_MARK=-1 I=X'40000800'!PT<<16 *LB_I; *LSS_1; *ST_(0+%B) %FINISH %FINISH %ELSE %IF GDCT_DEVTYPE=MT %START I=QHD; ! Q MT request %UNTIL I=ENDLIST %CYCLE GE==RECORD(GDCT BASE+I*SLOTSIZE) I=GE_LINK %REPEAT GDCT_LINK=ENDLIST GE_LINK=SLOT GDCT_STATE=QUEUED %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH %FINISH %ELSE ->STRM BUSY %IF SSERIES=YES %START %FINISH %ELSE %START %IF P_P3&X'100'=0 %THEN GDCT_FLAGS=0 %ELSE %C GDCT_FLAGS=GET STRM DATA DEV_USAW0=USAW0 DEV_PAW=PAW FN DEV_RESP1=0 %FINISH DEV_UCCBA=UCCBA DEV_SECS SINCE=0 P_P1=0 ->OUT %FINISH %ELSE %START %IF SSERIES=YES %AND GDCT_STATE=IDENTIFY FIRED %AND GDCT_Q=0 %START !* Q request 'till identify terminates I=NEW PP CELL GDCT_Q=I QACT==PARM(I) %IF GDCT_UTAD=0 %START QACT_ACTWD=X'01000000'!STRM QACT_ISAD=CA_IAWA %FINISH %ELSE QACT_ACTWD=GDCT_UTAD QACT_TCBAD=UCCBA QACT_P2=M'IDWT' P_P1=0 %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH ->OUT %FINISH STRM BUSY: %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH FLAG=2 P_P3=ADDR(DEV) P_P6=P_P4 %FINISH %FINISH %ELSE FLAG=1 ->ACKNOWLEDGE !* !* !* ACT(3): ! interrupt %IF SSERIES=YES %START *INCT_I; ! clear operand slaves INTWD=P_P1 STRM=INTWD&255 CNO=INTWD>>24&15 GDCNO=CNO TO GDC(CNO-LOCNO) %IF INTWD&PRIMITIVE#0 %START; ! DCU gone primitive (or similar) PKMONREC("DCU gone primitive!",P) !* dump DCU ? %IF MULTI OCP=YES %THEN RECOVER DCU1S=CNO %ELSE %START DCU1 RECOVERY(CNO) OPMESS("DCU1 recovery initiated") %FINISH ->OUT %FINISH %UNLESS CONNECT TERM#INTWD&STREAM CTERM#DISCONNECT TERM %START ! i.e if INTWD&CTERM = CONNECT or DISCONNECT PKMONREC("DCU control term",P) %IF INTWD&DISCONNECT TERM=DISCONNECT TERM %START ! DCU1s only (DCU2s give a simulated connect term) CAA=CAAS(GDCNO) CA==RECORD(CAA) ACTIVATE(X'03000000'!STRM,0,CA_IAWA); ! reconnect %FINISH ->OUT %FINISH QHD==STRMQ(GDCNO<<8!STRM) %IF INTWD&STREAM ITA=STREAM IA %START ! attention & no TCB termination SLOT=CSTRM TO SLOT((CNO-LOCNO)<<8!STRM) %IF SLOT=ENDLIST %THEN ->SURPRISE GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) DEV==RECORD(GDCT_DEVICE ENTRY A) %IF MULTI OCP=YES %START CA==RECORD(DEV_CAA) SEMA=ADDR(CA_SEMA) *LXN_SEMA; *INCT_(%XNB+0); *JCC_8, SEMALOOP(INTEGER(SEMA),0) ASEMAGOT: %FINISH TRYNMT: %IF GDCT_STATE=READY %START %IF QHD=ENDLIST %START FIRE IDENTIFY QHD=SLOT %FINISH %ELSE %START; ! MT request on another slot GDCT==RECORD(GDCT BASE+QHD*SLOT SIZE) GDCT_ATTN=1 %FINISH %FINISH %ELSE %START %IF GDCT_STATE=NOT ALLOCATED %OR GDCT_STATE=DISCONNECTED %START %IF GDCT_DEVTYPE=MT %START ! must be careful not to lose an attention when ! 1st n decks of a cluster are not allocated etc. SLOT=SLOT+1 %IF SLOT<=LASTSLOT %START GDCT==RECORD(GDCT BASE+SLOT*SLOTSIZE) DEV==RECORD(GDCT_DEVICE ENTRY A) %IF GDCT_DSSMM>>24=GDCNO %AND %C GDCT_DSSMM>>8&255=STRM %THEN ->TRYNMT; ! next deck %FINISH %FINISH %UNLESS GDCT_DEVTYPE=FE %START ! dont report spurious FE attentions lest FE in a twist ! & we thus swamp the mainlog BYTEINTEGER(ADDR(P_P3))=GDCT_STATE PKMONREC("DCU attention?:",P) %FINISH %FINISH %ELSE GDCT_ATTN=1; ! identify on termination %FINISH %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH ->OUT %FINISH SLOT=QHD %IF SLOT=ENDLIST %THEN ->SURPRISE GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) DEV==RECORD(GDCT_DEVICE ENTRY A) %IF GDCT_STATE=IDENTIFY FIRED %THEN CCB==RECORD(DEV_MYCCBA) %ELSE %C CCB==RECORD(DEV_UCCBA) %WHILE CCB_RESP&TCB CONT#0 %CYCLE; ! find 'stopped' TCB CCB==RECORD(CCB_NTCB) %REPEAT %IF GDCT_STATE=REQUEST FIRED %START %IF INTWD&INVALID ACTIVATE#0 %START PKMONREC("DCU1 invalid act:",P) RESP0=CONTROLLER DETECTED ERROR RESP1=INTWD INTWD=0 DEV_LAST TCB ADDR=ADDR(CCB) %FINISH %ELSE %START %IF CCB_RESP&TCB ATTN#0 %THEN GDCT_ATTN=1 ! the above is for DCU2s - is there a better way? RESP0=CCB_RESP>>24<<8; ! primary status RESP1=CCB_RESP&X'FFFF'; ! RBC %IF INTWD&STREAM ABTERM=0 %START RESP0=RESP0!NORMAL TERMINATION %FINISH %ELSE %START %IF DEV_LOGMASK>>8#0 %START PRINTSTRING("DCU--Abnormal termination - ". %C MTOS(GDCT_MNEMONIC)."(".HTOS(GDCT_DSSMM>>8&255,3). %C ") TCB RESP = ".HTOS(CCB_RESP,8)." ") DUMPTABLE(0,DEV_UCCBA,14*4*2) %FINISH DEV_LAST TCB ADDR=ADDR(CCB) RESP0=RESP0!(CCB_RESP&INIT FAIL)>>4!ABNORMAL TERMINATION ! primary status + init fail + abterm RESP0=RESP0!(((ADDR(CCB)-DEV_UCCBA)//TCB LENGTH)&255) ! failing TCB Q_P4=(CCB_COMMAND&POST AMBLE VALID)>>7!!(CCB_RESP&SENSE FAIL)>>13 ! X'80' if succesful sense done by DCU ! tho' not for discs?? %IF Q_P4#0 %THEN DEV_SENSDAT AD=ADDR(CCB_POSTAMBLE(0)) %FINISH %FINISH %FINISH %ELSE %IF GDCT_STATE=IDENTIFY FIRED %START %IF INTWD&INVALID ACTIVATE#0 %OR CCB_RESP&TCB FAIL#0 %START PRINTSTRING("DCU identify fails - parm = ".HTOS(INTWD,8). %C " TCB_RESP = ".HTOS(CCB_RESP,8)." ") INTWD=0; ! 'lest identify loop ->MORE REQUESTS %FINISH %ELSE %START %IF GDCT_DEVTYPE=MT %AND DEV_MECH&7#GDCT_DSSMM&7 %START I=MECHSLOTS(GDCT_MECHINDEX+DEV_MECH&7) GE==RECORD(GDCT BASE+I*SLOT SIZE) %UNLESS GE_STATE=NOT ALLOCATED %OR GE_STATE=DISCONNECTED %START ! allocated decks only Q_DEST=GE_RESPONSE DEST Q_SRCE=GDC DEST!3 Q_P1=(I+LOID)<<24!ATTENTION!DEV_ATTN<<8 Q_P2=0 Q_P3=GE_DEVICE ENTRY A PON(Q) %FINISH ->MORE REQUESTS %FINISH RESP0=ATTENTION!DEV_ATTN<<8 RESP1=0 %FINISH %FINISH %ELSE ->SURPRISE %FINISH %ELSE %START PT=P_P1 GDCNO=CNO TO GDC(PT-LOCNO) CAA=CAAS(GDCNO) CA==RECORD(CAA) *LXN_CAA *INCT_(%XNB+0) *JCC_8, SEMALOOP(INTEGER(CAA),2) CGOT1: PIW0=CA_PIW0 CA_PIW0=0 CA_MARK=-1 MORE INTS: *LSS_PIW0 *JAT_4,; ! no (more) interrupts *SHZ_STRM PIW0=PIW0!!X'80000000'>>STRM STREAM==CA_STREAM(STRM) *LXN_CAA *INCT_(%XNB+0) *JCC_8, SEMALOOP(INTEGER(CAA),2) CGOT2: RESP0=STREAM_RESP0 RESP1=STREAM_RESP1 STREAM_RESP0=0 STREAM_RESP1=0 CA_MARK=-1 %IF RESP0&ATTENTION#0 %START SLOT=CSTRM TO SLOT((PT-LOCNO)<<4!STRM) %IF SLOT=ENDLIST %THEN ->SURPRISE GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) %IF GDCT_DEVTYPE=MT %START SLOT=MECHSLOTS(GDCT_MECHINDEX+RESP0>>24&15) GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) %FINISH %IF GDCT_STATE=NOT ALLOCATED %THEN ->SURPRISE ->RESPOND %FINISH %ELSE SLOT=STRMQ(GDCNO<<4!STRM) %IF SLOT=ENDLIST %THEN ->SURPRISE GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) DEV==RECORD(GDCT_DEVICE ENTRY A) %IF GDCT_STATE=REQUEST FIRED %START DEV_RESP0=RESP0 DEV_RESP1=RESP1 %IF RESP0&ABNORMAL TERMINATION#0 %AND GDCT_RESPONSE DEST>>16<65 %START %IF RESP0&X'FF0000'=CONTROLLER DETECTED ERROR %OR %C DEV_LOGMASK>>8#0 %START PRINTSTRING("GPC--Abnormal termination - ".MTOS(GDCT_MNEMONIC). %C "(".HTOS(PT<<4!STRM,3).") RESP0 = ".HTOS(RESP0,8)." ") !*** read stream status etc %IF GDCT_DEVTYPE=FE %AND RESP0&X'FF0000'=CONTROLLER DETECTED ERROR %C %THEN CONNECT STREAM(PT,CAA,STRM,1,0) %FINISH %IF GDCT_FLAGS&GET STRM DATA#0 %START !*** read controller status ->SET SENSE %FINISH %IF CA_PAW#0 %THEN PRINTSTRING("GPC--PAW not cleared - PT". %C HTOS(PT,2).",PAW = ".HTOS(CA_PAW,8)." ") *LXN_CA+4; *INCT_(%XNB+0); *JCC_8, SEMALOOP(CA_MARK,2) CAG: CA_PAW=DO STREAM REQUEST!STRM STREAM_SAW0=X'10000020' STREAM_SAW1=DEV_MYCCBA CA_MARK=-1 I=X'40000800'!PT<<16 *LB_I; *LSS_1; *ST_(0+%B) GDCT_STATE=SENSE FIRED ->MORE INTS %FINISH %FINISH %ELSE %IF GDCT_STATE=SENSE FIRED %START SET SENSE: %IF DEV_LOGMASK&BYTEINTEGER(ADDR(DEV_SENSE1))#0 %START %IF MULTI OCP=YES %THEN RESERVE LOG PRINTSTRING("GPC--device entry after sense:") DUMPTABLE(0,ADDR(DEV),DEV_DEVICE ENTRY S) %IF MULTI OCP=YES %THEN RELEASE LOG %FINISH Q_P4=RESP0>>16 Q_P5=GDCT_CSTATUS RESP0=DEV_RESP0 RESP1=DEV_RESP1 %FINISH %ELSE ->SURPRISE %FINISH RESPOND: ! tell allocatee Q_DEST=GDCT_RESPONSE DEST Q_SRCE=GDC DEST!3 Q_P1=RESP0 BYTEINTEGER(ADDR(Q_P1))=SLOT+LOID Q_P2=RESP1 Q_P3=GDCT_DEVICE ENTRY A PON(Q) %IF SSERIES=NO %AND RESP0&ATTENTION#0 %THEN ->MORE INTS !* MORE REQUESTS: %IF MULTI OCP=YES %START %IF SSERIES=YES %THEN CA==RECORD(DEV_CAA) %AND SEMA=ADDR(CA_SEMA) %ELSE %C SEMA=ADDR(STRM SEMAPHORE(GDCNO<<4!STRM)) *LXN_SEMA; *INCT_(%XNB+0); *JCC_8, %IF SSERIES=YES %THEN SEMALOOP(INTEGER(SEMA),0) %C %ELSE SEMALOOP(INTEGER(SEMA),2) SSEMAG: %FINISH %IF SSERIES=YES %AND GDCT_Q#0 %START; ! fire waiting I/O I=GDCT_Q GDCT_Q=0 QACT==PARM(I) GDCT_STATE=REQUEST FIRED %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH DEV_SECS SINCE=0 DEV_UCCBA=QACT_TCBAD %IF GDCT_UTAD=0 %THEN ACTIVATE(QACT_ACTWD,QACT_TCBAD,QACT_ISAD) %C %ELSE FIRE DCU2(QACT_ACTWD,QACT_TCBAD,START STREAM) RETURN PP CELL(I) ->OUT %FINISH %IF SSERIES=YES %AND (INTWD&STREAM ATTENTION#0 %OR GDCT_ATTN#0) %START FIRE IDENTIFY %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH ->OUT %FINISH GDCT_STATE=READY %IF SSERIES=NO %THEN QHD==STRMQ(GDCNO<<4!STRM); ! already mapped for S series %UNLESS GDCT_DEVTYPE=MT %START QHD=ENDLIST %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH %IF SSERIES=YES %THEN ->OUT %ELSE ->MORE INTS %FINISH QHD=GDCT_LINK GDCT_LINK=ENDLIST %IF QHD#ENDLIST %START; ! request to go SLOT=QHD GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) DEV==RECORD(GDCT_DEVICE ENTRY A) CA==RECORD(DEV_CAA) GDCT_STATE=REQUEST FIRED %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH %IF SSERIES=YES %START %IF GDCT_UTAD=0 %THEN ACTIVATE(X'01000000'!STRM,DEV_UCCBA,CA_IAWA) %C %ELSE FIRE DCU2(GDCT_UTAD,DEV_UCCBA,START STREAM) %FINISH %ELSE %START STREAM==CA_STREAM(STRM) %IF CA_PAW#0 %THEN PRINTSTRING("GPC--PAW not cleared - PT". %C HTOS(PT,2).",PAW = ".HTOS(CA_PAW,8)." ") *LXN_CA+4; *INCT_(%XNB+0); *JCC_8,; SEMALOOP(CA_MARK,2) CAAGOT: CA_PAW=DEV_PAW STREAM_SAW0=DEV_USAW0 STREAM_SAW1=DEV_UCCBA CA_MARK=-1 I=X'40000800'!PT<<16 *LB_I; *LSS_1; *ST_(0+%B) %FINISH %FINISH %ELSE %IF MULTI OCP=YES %START; *LXN_SEMA; *TDEC_(%XNB+0); %FINISH %IF SSERIES=YES %THEN ->OUT %ELSE ->MORE INTS !* SURPRISE: ! unexpexted interrupt %IF SSERIES=YES %START PRINTSTRING("DCU--Surprise interrupt - parm = ".HTOS(INTWD,8)." ". %C HTOS(P_P2,8)." ") ->OUT %FINISH %ELSE %START PRINTSTRING("GPC--Surprise interrupt on ".HTOS(PT<<4!STRM,3)."/".HTOS(RESP0,8)." ") ->MORE INTS %FINISH %RETURN !* %IF SSERIES=YES %START ACT(10):RECON: ! reconnect streams ! P_P1 = DCU1 H/W no. or -1 for all DCU1s %FOR SLOT=0,1,LASTSLOT %CYCLE GDCT==RECORD(GDCT BASE+SLOT*SLOTSIZE) %IF GDCT_UTAD=0 %AND (P_P1=-1 %OR GDCT_DSSMM>>16&255=P_P1) %START %CONTINUE %IF GDCT_DEVTYPE=ZX %CONTINUE %IF GDCT_DEVTYPE=MT %AND GDCT_DSSMM&15>0 DEV==RECORD(GDCT_DEVICE ENTRY A) CA==RECORD(DEV_CAA) ACTIVATE(X'03000000'!GDCT_DSSMM>>8&255,0,CA_IAWA) WAIT(10) %FINISH %REPEAT ->ACK1 %FINISH %ELSE %START ACT(7): ! entry from reconfigure routine ! P_P1=IDENT,P_P2=SAC I=P_P2 P_P2=0 %FOR SLOT=0,1,LASTSLOT %CYCLE GDCT==RECORD(GDCT BASE+SLOT*SLOTSIZE) %IF GDCT_PTSM>>12&15=I %AND GDCT_STATE&15#DISCONNECTED %START; ! SAC in use P_P2=3<<24!GDCT_MNEMONIC %EXIT %FINISH %REPEAT ->ACK1 ACT(9): ! entry from SHUTDOWN routine ! P_P1 = pt %IF COM_NSACS=1 %AND COM_SACPORT0#P_P1>>4 %THEN ->ACK1; ! SAC gone %FOR SLOT=0,1,LAST SLOT %CYCLE GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) PT=GDCT_PTSM>>8&255 %IF PT=P_P1 %START DEV==RECORD(GDCT_DEVICE ENTRY A) CCB==RECORD(DEV_MYCCBA) STRM=GDCT_PTSM>>4&15 CA==RECORD(DEV_CAA) STREAM==CA_STREAM(STRM) %IF GDCT_DEVTYPE=MT %START CCB_LIM FLAGS=X'C000' I=CCB_INIT&X'FF' I=3 %IF I=0 CCB_INIT=MECH<<24!I %FINISH %ELSE CCB_LIM FLAGS=PRIV ONLY INTEGER(CCB_LBA)=X'80F01800' LONGINTEGER(CCB_ALA)=X'5800000481000000' CCB_LBS=4 CCB_ALS=8 *LXN_CA+4; *INCT_(%XNB+0); *JCC_8, SEMALOOP(CA_MARK,2) GOT1: CA_PAW=DO STREAM REQUEST!STRM CA_PIW0=0 STREAM_SAW0=3<<28!RCB BOUND STREAM_SAW1=ADDR(CCB) STREAM_RESP0=0 STREAM_RESP1=0 CA_MARK=-1 I=X'40000800'!PT<<16 *LB_I; *LSS_1; *ST_(0+%B) WAIT(10) %FINISH %REPEAT WAIT(100) ->ACK1 ACT(10): ! Reinit GPC ! P_P1 = PT ! P_P2 = OLD PT IF >=0 PT=P_P1 %IF P_P2>=0 %AND PT#P_P2 %START; ! SAC switch ! *** not implemented protem - grope table requires extension *** OPMESS("Cannot switch GPCs") ->ACK1 %FINISH %IF 0<=PT<=X'1F' %AND BYTEINTEGER(COM_CONTYPEA+PT)=3 %START I=GPC INIT(PT,0); ! reinitialise GPC %IF I=0 %THEN WK=" reinitialised" %ELSE WK=" reinit fails" OPMESS("GPC ".HTOS(PT,2).WK) %FINISH %ELSE OPMESS("Cannot reinit GPC ".HTOS(PT,2)) ->ACK1 %FINISH !* ACT(*): %IF SSERIES=YES %THEN PKMONREC("DCU bad DACT:",P) %ELSE PKMONREC("GPC bad DACT:",P) %RETURN !* ACKNOWLEDGE: P_P1=FLAG ACK1: %IF P_SRCE>0 %START; ! PON reply P_DEST=P_SRCE P_SRCE=GDC DEST!DACT PON(P) %FINISH OUT: %IF SSERIES=YES %AND QHEAD#0 %START %IF MULTI OCP=YES %START *INCT_DCU1SEMA *JCC_8, SEMALOOP(DCU1 SEMA,0) DCU1SEMAGOT: %FINISH %WHILE QHEAD#0 %CYCLE QACT==PARM(QHEAD) L=LENGTHENI(QACT_TCBAD)<<32!QACT_ACTWD ISAD=QACT_ISAD %FOR I=1,1,COM_INSPERSEC %CYCLE *LB_ISAD; *LSD_0; *L_(0+%B); *STUH_SINK *JAT_4, %REPEAT ->NOTOK OK: *LSD_L; *ST_(0+%B) I=QHEAD QHEAD=QACT_LINK RETURN PP CELL(I) %REPEAT NOTOK: %IF MULTI OCP=YES %START; *TDEC_DCU1SEMA; %FINISH %FINISH %RETURN !* ACT(1): ! command (CDS etc) SRCE=P_SRCE<<1>>1 TEXT=P_TEXT %IF SSERIES=YES %AND TEXT="DIAGS" %START REPLY(SRCE,"DCU ACTs Q'd = ".STRINT(ACTS QD)) REPLY(SRCE,"DCU ACT cycs = ".STRINT(ACT CYCLES)) REPLY(SRCE,"DCU max Q'd = ".STRINT(MAX Q)) %RETURN %FINISH %IF TEXT="?" %THEN ->GC4 %FOR J=1,1,LIMIT %CYCLE %IF TEXT->(COMMAND(J)).TEXT %THEN ->FOUND %REPEAT ERR: %IF SSERIES=YES %THEN REPLY(SRCE,"DCU ??".P_TEXT) %ELSE %C REPLY(SRCE,"GPC ??".P_TEXT) %RETURN FOUND: ! QS,CDS or CDM %UNLESS TEXT->MNEMOS.(" ").TEXT %START ->ERR %UNLESS J=1; ! must be QS MNEMOS<-TEXT %FINISH MNEMONIC=TRANS MNEMONIC(MNEMOS); ! to integer %IF FIND(MNEMONIC)<0 %THEN ->ERR; ! not found DEV==RECORD(GDCT_DEVICE ENTRY A) ->GDC COMMAND(J) GDC COMMAND(1): ! QS dev PRSTATUS: STATUS(SLOT) %RETURN GDC COMMAND(2): ! CDS dev ON/OFF LENGTH(TEXT)=LENGTH(TEXT)-1 %WHILE CHARNO(TEXT,LENGTH(TEXT))=' ' STATE=GDCT_STATE&15 %IF TEXT="OFF" %START %IF STATE CHECK(MNEMONIC,STATE)=OK %START %IF SSERIES=YES %START ! disconnect DCU1 stream ! (but note that stream is reconnected on disconnect term.) ! no disconnect on DCU2, stream is reset by CDS ON etc. %IF GDCT_UTAD=0 %START CA==RECORD(DEV_CAA) ACTIVATE(X'02000000'!GDCT_DSSMM>>8&255,0,CA_IAWA) %FINISH %FINISH %ELSE CONNECT STREAM(GDCT_PTSM>>8&255,DEV_CAA,GDCT_PTSM>>4&15,0,0) %IF MNEMONIC>>16=M'M' %START; ! MT cluster I=GDCT BASE %FOR J=0,1,LASTSLOT %CYCLE GDCT==RECORD(I) %IF GDCT_MNEMONIC&MTMASK=MNEMONIC %THEN GDCT_STATE=STATE<<4!DISCONNECTED I=I+SLOT SIZE %REPEAT %FINISH %ELSE GDCT_STATE=STATE<<4!DISCONNECTED %FINISH ->PRSTATUS %FINISH %IF TEXT="ON" %START %IF STATE=DISCONNECTED %THEN ->CDS ON ->PRSTATUS %FINISH ->ERR GDC COMMAND(3): ! CDM dev1 dev2 MNEMONIC1=MNEMONIC MNEMONIC2=TRANS MNEMONIC(P_TEXT) J=SLOT; ! save 1st slot %UNLESS FIND(MNEMONIC2)<0 %THEN ->ERR; ! already exists GDCT==RECORD(GDCT BASE+J*SLOTSIZE); ! remap target slot %IF MNEMONIC1>>8=M'ZX' %START; ! introduce device I=MNEMONIC2>>8 %FOR J=0,1,CDMDEVLIMIT %CYCLE %IF I=CDMDEV(J) %THEN ->IDEV %REPEAT ->ERR; ! invalid for CDM IDEV: GDCT_MNEMONIC=MNEMONIC2 GDCT_DEVTYPE=CDMDEVTYPE(J) DEV_MNEMONIC=MNEMONIC2 %IF CDMDEVTYPE(J)=LP %START DEV_UA SIZE=DEV_UA SIZE-256; ! TRTAB space DEV_TRTAB AD=DEV_UA AD+DEV_UA SIZE %FINISH DEV_TIMEOUT=CDMDEVTIMEOUT(J)&X'FFFF' DEV_LOGMASK=CDMDEVTIMEOUT(J)>>16 %IF CDMDEVTYPE(J)=FE %THEN COM_FEPS=COM_FEPS!1<<(16+MNEMONIC2&15) ! FEP map %FINISH %ELSE %START; ! take out device %UNLESS MNEMONIC2>>8=M'ZX' %THEN ->ERR %UNLESS GDCT_STATE=DISCONNECTED %THEN ->ERR I=MNEMONIC1>>8 %FOR J=0,1,CDMDEVLIMIT %CYCLE %IF I=CDMDEV(J) %THEN ->TOUT %REPEAT ->ERR TOUT: %IF CDMDEVTYPE(J)=FE %THEN COM_FEPS=COM_FEPS&(\(1<<(16+MNEMONIC1&15))) %IF CDMDEVTYPE(J)=LP %START DEV_UA SIZE=DEV_UA SIZE+256; ! recover TRTAB space DEV_TRTAB AD=0 %FINISH GDCT_MNEMONIC=MNEMONIC2 GDCT_DEVTYPE=ZX %FINISH ->PRSTATUS GC4: ! ? %FOR SLOT=0,1,LASTSLOT %CYCLE STATUS(SLOT) %REPEAT %RETURN !* CDS ON: %BEGIN %IF SSERIES=YES %START; ! only on same DSS protem CA==RECORD(DEV_CAA) STRM=GDCT_DSSMM>>8&255 %IF GDCT_UTAD=0 %THEN ACTIVATE(X'03000000'!STRM,0,CA_IAWA) %C %ELSE FIRE DCU2(GDCT_UTAD,0,RESET STREAM) WAIT(10) %IF GDCT_DEVTYPE=FE %START; ! FEP needs send propcodes to wake it up CCB==RECORD(DEV_MYCCBA) CCB_COMMAND=X'2F40400E'; ! send propcodes CCB_RESP=0 %IF GDCT_UTAD=0 %START; ! DCU1 L=LENGTHENI(ADDR(CCB))<<32!X'01000000'!STRM J=CA_IAWA %FOR I=1,1,COM_INSPERSEC %CYCLE *LB_J; *LSD_0; *L_(0+%B); *STUH_SINK *JAT_4, %REPEAT ->RESET CCB; ! fire fails so report not found CDSOK: *LSD_L; *ST_(0+%B) %FINISH %ELSE %START; ! DCU2 FIRE DCU2(GDCT_UTAD,ADDR(CCB),START STREAM) %FINISH SLAVES ON OFF(0); ! slaves off %FOR I=1,1,COM_INSPERSEC*20 %CYCLE %EXIT %IF CCB_RESP#0 %REPEAT SLAVES ON OFF(-1); ! back on RESETCCB: CCB_COMMAND=X'2F00400A'; ! identify %IF CCB_RESP=0 %START REPLY(SRCE,"DCU: ".MTOS(MNEMONIC)." not found") ->RETURN %FINISH %FINISH GDCT_STATE=GDCT_STATE>>4 OPMESS("DCU: ".MTOS(MNEMONIC)." now on DSS ".HTOS(GDCT_DSSMM>>8,3)) RETURN: %FINISH %ELSE %START %INTEGERFNSPEC FIND BYTE(%INTEGER BYTE,ADDR,LEN) %RECORD(ALEF)%ARRAYFORMAT ALEFF(0:3) %RECORD(ALEF)%ARRAYNAME XALE %RECORD(CCB)%NAME XCCB %RECORD(CAF)%NAME XCA %RECORD(CASEF)%NAME XSTREAM %OWNINTEGERARRAY XLBE(0:7)=%C X'00F10900',X'04F10800',X'04F00E00',X'00F00402', X'80F02504',X'80F00106',X'82F00500',X'80F00106' %OWNINTEGERARRAY X(0:117)=0(*); ! needs to be %OWN for I/O (stack not 'fixed'!) %SWITCH CDS(0:7) %INTEGER XPT,XGPTSM,XPTS %INTEGER XSTRM,XA,XSLOT,XMNEMONIC,XDEVTYPE,XGDC,XCAA,XSTATE,XSRCE %INTEGER XCART,XSTYLE,XLEN,XS XA=ADDR(X(0)); ! set up CCB etc. XCCB==RECORD(XA) XCCB_LIMFLAGS=X'4000'; ! trusted chain XCCB_LSTA=0 XCCB_LB S=32 XCCB_AL S=32 XCCB_AL A=XA+32 XALE==ARRAY(XCCB_AL A,ALEFF) XALE(0)_S=8 XALE(0)_A=XA+64; ! propsdata XALE(1)_S=12 XALE(1)_A=XA+72; ! sense data XALE(2)_S=384 XALE(2)_A=XA+84; ! LP repertoire XALE(3)_S=4 XALE(3)_A=XA+468; ! LP initword ! remember what we're looking for! XSRCE=SRCE XSLOT=SLOT XMNEMONIC=MNEMONIC XDEVTYPE=GDCT_DEVTYPE XPTS=GDCT_PTSM>>4&X'FFF' XGDC=0 GLOOP: XPT=TABLE(16+XGDC) %IF RECONFIGURE=YES %START; ! SAC may be configured out %IF COM_NSACS=1 %START %UNLESS XPT>>4=COM_SACPORT0 %THEN ->SKIPG; ! SAC gone %FINISH %FINISH XCAA=TABLE(8+XGDC) XCA==RECORD(XCAA) XSTRM=0 SLOOP: XSTATE=-1; ! nothing fired SLOT=CSTRM TO SLOT((XPT-LOCNO)<<4!XSTRM) %IF SLOT=255 %THEN ->CONNECT GDCT==RECORD(GDCT BASE+SLOT*SLOTSIZE) %UNLESS GDCT_STATE&15=DISCONNECTED %THEN ->SKIP CONNECT: ! now found a strm that either has no slot ! associated with it or has a slot which ! has been disconnected XSTREAM==XCA_STREAM(XSTRM) X(16)=0 XSTATE=1; ! connect ->XFIRE ! response from connect CDS(1): %IF X(16)>>24>0 %START ! first byte of props data gives devtype, ! zero if no device %IF X(16)>>24=XDEVTYPE %START ! dev of right type ! if MT, next byte gives cluster id ! if FE, next byte gives FE no. ! if SU, next byte gives SU no. %UNLESS (XDEVTYPE=MT %AND XMNEMONIC&X'F00'#X(16)>>12 %C &X'F00') %OR (XDEVTYPE=FE %C %AND XMNEMONIC&15#X(16)<<8>>24) %OR %C (XDEVTYPE=SU %AND XMNEMONIC&15#X(16)<<8>>24) %THEN ->XFOUND %FINISH ! if found a device of wrong type, disconnect it XSTATE=0; ! disconnect ->XFIRE %FINISH ! response from disconnect CDS(0): SKIP: %UNLESS XSTRM=14 %THEN XSTRM=XSTRM+1 %AND ->SLOOP SKIPG: %UNLESS XGDC=NO OF GDCS-1 %THEN XGDC=XGDC+1 %AND ->GLOOP REPLY(XSRCE,"GPC: ".MTOS(XMNEMONIC)." not found") ->RETURN XFOUND: REPLY(XSRCE,"GPC: ".MTOS(XMNEMONIC)." now on pts ".HTOS( %C XPT<<4!XSTRM,3)) CSTRM TO SLOT(XPTS-(LOCNO<<4))=255 CSTRM TO SLOT((XPT-LOCNO)<<4!XSTRM)=XSLOT XGPTSM=(XGDC<<16)!(XPT<<8)!(XSTRM<<4) %FOR SLOT=0,1,LASTSLOT %CYCLE GDCT==RECORD(GDCT BASE+SLOT*SLOTSIZE) %IF (GDCT_PTSM>>4)&X'FFF'=XPTS %START ! move everything on this PTS DEV==RECORD(GDCT_DEVICE ENTRY A) DEV_GPTSM=XGPTSM!(DEV_GPTSM&15) GDCT_PTSM=DEV_GPTSM DEV_CAA=XCAA GDCT_STATE=GDCT_STATE>>4 %FINISH %REPEAT %UNLESS XDEVTYPE=LP %THEN ->XOUT ! first build a translate table in ! the device entry to filter out invalid characters XCART=(X(17)>>16)&15 XA=REPERTOIRE A(XCART) REP==ARRAY(XA,BIFT) XS=REPERTOIRE S(XCART) TRTAB==ARRAY(DEV_TRTAB AD,BIFT) %FOR I=0,1,255 %CYCLE; TRTAB(I)=I; %REPEAT %UNLESS XCART=0 %START %FOR I=0,1,255 %CYCLE %IF FIND BYTE(I,XA,XS)<0 %START ! not in rep %IF FIND BYTE(I,ADDR(LCLETTS(1)),26)<0 %START TRTAB(I)=LP ILLCHAR %FINISH %ELSE %START TRTAB(I)=I!X'40'; ! make uc letter %FINISH %FINISH %REPEAT TRTAB(37)=X'15' TRTAB(21)=X'15' TRTAB(12)=X'0C'; ! newline TRTAB(13)=X'0D' TRTAB(64)=X'40'; ! space %FINISH ! X(16) has bytes 0-3 of LP properties ! X(17) has bytes 4-5 ! bottom 4 bits of byte 5 has cartridge number set on front of LP. ! if cartridge number is set zero, we don't load any rep if ! there's one already loaded, else we load the 64-char rep ! (being the first 64 chars of the 96-char rep above). ! if the cartridge number is : ! 2 we load the 48-char rep ! 3 we load the 384-char rep for the Bush estate 2980 ! 4 we load the 64-char rep ! 5 we load the 96-char rep for the ERCC-KB 2972s XSTYLE=X(16)&255 XLEN=(XSTYLE>>4)*10+XSTYLE&15 XLEN=66 %IF XLEN=0 XLBE(6)=(XLBE(6)&(\255))!(XLEN-1) %FOR I=0,XS,384-XS %CYCLE MOVE(XS,XA,ADDR(X(21))+I) %REPEAT X(117)=LP ILLCHAR; ! back '?' for ERCC, autothrow not set XSTATE=5; ! initialise outwards ->XFIRE CDS(5): ! resp from init %IF XCART=0 %AND X(17)&X'100000'=0 %THEN ->CDS4 XSTATE=4; ! loadrep outwards ->XFIRE CDS(4):CDS4: ! resp from load rep X(117)=X'0000FC10' XSTATE=7; ! another init ->XFIRE CDS(7): ! resp from second init %IF XSTYLE=X'99' %THEN ->XOUT XSTATE=6; ! write control ->XFIRE CDS(6):XOUT: ! resp from write control ->RETURN XFIRE: ! needs XCAA, XSENT, XPT, XSTRM setting up outside ! uses XSTATE to select required command %IF XCA_PAW#0 %START PRINTSTRING("GPC--PAW not cleared - PT". %C HTOS(XPT,2).",PAW = ".HTOS(XCA_PAW,8)." ") CONTROLLER DUMP(3,XPT) ->SKIPG; ! give up on this GPC %FINISH XCCB_LBA=ADDR(XLBE(XSTATE)) SLAVES ON OFF(0); ! slaves off *LXN_XCAA *INCT_(%XNB+0) *JCC_8, SEMALOOP(INTEGER(XCAA),2) XGOT: XCA_PAW=DO STREAM REQUEST!XSTRM XSTREAM_SAW0=X'30000020' XSTREAM_SAW1=ADDR(XCCB) XSTREAM_RESP0=0 XCA_MARK=-1 I=X'40000800'!XPT<<16 *LB_I; *LSS_1; *ST_(0+%B) %FOR I=1,1,COM_INSPERSEC*150 %CYCLE; ! wait about 1 sec %EXIT %IF XSTREAM_RESP0#0 %REPEAT XCA_PIW0=XCA_PIW0&(\(X'80000000'>>XSTRM));! no surprise ints. XSTREAM_RESP0=0 SLAVES ON OFF(-1); ! back on ->CDS(XSTATE); ! process response RETURN: %INTEGERFN FIND BYTE(%INTEGER BYTE,ADDR,LEN) %INTEGER I %FOR I=0,1,LEN-1 %CYCLE %IF BYTE=BYTEINTEGER(ADDR+I) %THEN %RESULT=I %REPEAT %RESULT=-1 %END %FINISH %END !* %ROUTINE CONNECT STREAM(%INTEGER CNO,CAA,STRM,CONNECT,TIMEOUT) %END !* %ROUTINE FAIL TRANSFER(%RECORD(GDCTF)%NAME GDCT,%INTEGER SLOT) %RECORD(DEVICE ENTRY F)%NAME DEV %RECORD(PARMF) Q %INTEGER I %IF SSERIES=NO %OR (SSERIES=YES %AND (GDCT_STATE=REQUEST FIRED %OR %C GDCT_STATE=QUEUED %OR GDCT_Q#0)) %START Q_DEST=GDCT_RESPONSE DEST Q_SRCE=GDC DEST!6 Q_P1=ABNORMAL TERMINATION BYTEINTEGER(ADDR(Q_P1))=SLOT+LOID Q_P2=-1; ! timeout Q_P3=GDCT_DEVICE ENTRY A PON(Q) %FINISH %IF SSERIES=YES %START GDCT_Q=0 %UNLESS GDCT_STATE=QUEUED %START %IF GDCT_UTAD#0 %START FIRE DCU2(GDCT_UTAD,0,RESET STREAM) %FINISH %ELSE %START DEV==RECORD(GDCT_DEVICE ENTRY A) CA==RECORD(DEV_CAA) ACTIVATE(X'02000000'!GDCT_DSSMM>>8&255,0,CA_IAWA) %FINISH %FINISH %FINISH GDCT_STATE=READY %END !* %INTEGERFN FIND(%INTEGER DEV) %INTEGER PTR AGN: PTR=GDCT BASE %FOR SLOT=0,1,LAST SLOT %CYCLE GDCT==RECORD(PTR) %IF DEV=LOID+SLOT %OR DEV=GDCT_MNEMONIC %C %OR (SSERIES=YES %AND DEV=GDCT_DSSMM&X'FFFFF') %OR %C (SSERIES=NO %AND DEV=GDCT_PTSM&X'FFFF') %C %OR (DEV=M'LP' %AND GDCT_MNEMONIC>>8=M'LP' %C %AND GDCT_PROPS03&X'80'=0 %AND GDCT_STATE=NOT ALLOCATED) %C %THEN %RESULT=0 PTR=PTR+SLOT SIZE %REPEAT %IF DEV=M'LP' %THEN DEV=M'LP0' %AND ->AGN %RESULT=-1 %END !* %STRING(4)%FN MTOS(%INTEGER M) %INTEGER I,J %IF M>>24=0 %THEN J=M<<8!X'20' %ELSE J=M %IF SSERIES=YES %THEN I=4 %ELSE I=3 %RESULT=STRING(ADDR(I)+3) %END !* %ROUTINE READ STREAM DATA(%RECORD(GDCTF)%NAME G) %END !* %ROUTINE REPLY(%INTEGER SRCE,%STRING(23)TEXT) %RECORD(PARMF) Q Q=0 Q_DEST=SRCE Q_TEXT=TEXT PON(Q) %END !* %INTEGERFN STATE CHECK(%INTEGER MNEMONIC,STATE) %RECORD(GDCT)%NAME G %INTEGER I,PTR %IF MNEMONIC>>16=M'M' %START; ! check whole cluster %UNLESS MNEMONIC&255=M'0' %START %IF SSERIES=YES %THEN REPLY(SRCE,"DCU: must be MN0") %ELSE %C REPLY(SRCE,"GPC: must be MN0") %RESULT=1 %FINISH PTR=GDCT BASE %FOR I=0,1,LAST SLOT %CYCLE G==RECORD(PTR) %IF G_MNEMONIC&MTMASK=MNEMONIC %START %UNLESS G_STATE=NOT ALLOCATED %START %IF SSERIES=YES %THEN REPLY(SRCE,"DCU: ".MTOS(G_MNEMONIC)." state?") %C %ELSE REPLY(SRCE,"GPC: ".MTOS(G_MNEMONIC)." state?") %RESULT=1 %FINISH %FINISH PTR=PTR+SLOT SIZE %REPEAT %RESULT=0 %FINISH %RESULT=0 %IF STATE=NOT ALLOCATED %IF SSERIES=YES %THEN REPLY(SRCE,"DCU: ".MTOS(MNEMONIC)." state?") %C %ELSE REPLY(SRCE,"GPC: ".MTOS(MNEMONIC)." state?") %RESULT=1 %END !* %ROUTINE STATUS(%INTEGER SLOT) GDCT==RECORD(GDCT BASE+SLOT*SLOT SIZE) %IF SSERIES=YES %START REPLY(SRCE,"DCU: ".MTOS(GDCT_MNEMONIC)." ".HTOS(GDCT_DSSMM>>8&X'FFF',3). %C " ".STATES(GDCT_STATE&15)) %FINISH %ELSE %START REPLY(SRCE,"GPC: ".MTOS(GDCT_MNEMONIC)." ".HTOS(GDCT_PTSM&X'FFF',3). %C " ".STATES(GDCT_STATE&15)) %FINISH %END !* %INTEGERFN TRANS MNEMONIC(%STRINGNAME S) %INTEGER M,N N=0 %IF LENGTH(S)=3 %START STRING(ADDR(N))=S BYTEINTEGER(ADDR(N))=0 %FINISH %ELSE %IF LENGTH(S)=4 %START STRING(ADDR(M)+3)=S %FINISH %RESULT=N %END %IF SSERIES=YES %START %ROUTINE ACTIVATE(%INTEGER ACTWD,TCBAD,ISAD) %INTEGERNAME LINK %INTEGER I %IF MULTI OCP=YES %START *INCT_DCU1SEMA *JCC_8, SEMALOOP(DCU1SEMA,0) SEMAGOT: %FINISH %IF QHEAD=0 %START; ! no I/Os waiting to go *LB_ISAD; *LSD_0; *L_(0+%B); *STUH_SINK *JAT_4, %FOR I=1,1,COM_INSPERSEC %CYCLE; ! 10 millisecs approx *LB_ISAD; *LSD_0; *L_(0+%B); *STUH_SINK *JAT_4, %REPEAT ->NOT OK OKW: ACT CYCLES=ACT CYCLES+1 *LB_ISAD OK: *LSS_ACTWD; *LUH_TCBAD; *ST_(0+%B) %IF MULTI OCP=YES %START; *TDEC_DCU1SEMA; %FINISH %RETURN %FINISH NOTOK: ACTS QD=ACTS QD+1 I=1 LINK==QHEAD %WHILE LINK#0 %CYCLE QACT==PARM(LINK) LINK==QACT_LINK I=I+1 %REPEAT %IF MAX Q SEMALOOP(DCU2SEMA,0) SEMAGOT: %FINISH *PRCL_4 *LSS_ACT *SLSS_TCBAD; *LUH_X'2800000E'; *ST_%TOS *LDTB_X'B0000001'; *LDA_UTAD *RALN_8 *CALL_(%DR) *ST_I %IF MULTI OCP=YES %START; *TDEC_DCU2SEMA; %FINISH %UNLESS I=0 %START %IF MULTI OCP=YES %THEN RESERVE LOG PRINTSTRING("DCU2 fire fails - resp = ".STRINT(I)." act = ".STRINT(ACT)." Unit table:") DUMPTABLE(0,UTAD,64) PRINTSTRING("TCB:") DUMPTABLE(0,TCBAD,14*4) %IF MULTI OCP=YES %THEN RELEASE LOG %FINISH %END %ROUTINE FIRE IDENTIFY; ! GDCT & DEV mapped %RECORD(CCBF)%NAME CCB GDCT_ATTN=0 GDCT_STATE=IDENTIFY FIRED CCB==RECORD(DEV_MYCCBA) CCB_RESP=0 CA==RECORD(DEV_CAA) %IF GDCT_UTAD=0 %THEN ACTIVATE(X'01000000'!STRM,ADDR(CCB),CA_IAWA) %C %ELSE FIRE DCU2(GDCT_UTAD,ADDR(CCB),START STREAM) DEV_SECS SINCE=0 %END %FINISH %ELSE %START !* !* %FINISH !* %END; ! of GDC !* %IF SSERIES=NO %START %EXTERNALINTEGERFN GPC INIT(%INTEGER PT,FLAG) %RECORDFORMAT CA0F(%INTEGER MARK,PAW,PIW0,PIW1,CSAW0,CSAW1,CRESP0,CRESP1) %RECORDFORMAT INIF(%INTEGER PSTL,PSTB,CAA,SOE) %CONSTINTEGER REAL0AD=X'81000000' %CONSTRECORD(CA0F)%NAME CA0=REAL0AD %RECORD(CAF)%NAME CA %RECORD(INIF) INI %CONSTINTEGER DO CONTROLLER REQUEST=X'04000000' %CONSTINTEGER INIT CONTROLLER=X'32000010' %CONSTINTEGER LOAD MICROPROGRAM=X'08000000' !* !* GPC microprogram follows as %OWNINTEGERARRAY GPCMPROG(0:511) !* Program C03 patch level 5 %ENDOFLIST %OWNINTEGERARRAY GPCMPROG(0:511)= %C X'F160F161',X'482049E0',X'4022802C',X'E80AF0C9', X'000AD009',X'80054265',X'9320BE0A',X'100A8005',X'C213CAB3', X'8025CA33',X'8223CA53',X'8275CAD3',X'8005CA93',X'80C2CA73', X'8005CB34',X'8005CAF3',X'82FACAD4',X'80788005',X'C273C2D3', X'80298005',X'C2B38213',X'8210182E',X'93088007',X'4820E00C', X'740C500B',X'930FB725',X'F9C0F16C',X'DEEB21CC',X'EB4BE008', X'29E82C8C',X'61CC2CAC',X'61EC4C6B',X'7968B795',X'F9C00CCC', X'610CFC00',X'61ECFC00',X'70CC0825',X'818F8070',X'48400825', X'C2D4CA93',X'804AA2D4',X'BC091005',X'CAD48059',X'C27383DC', X'9062805F',X'B21AA27A',X'A29A82D9',X'B80983DF',X'10054989', X'C2D48068',X'B2F4A2D4',X'C2F4B2F4',X'EA131013',X'C6732013', X'98019205',X'98020835',X'C2738005',X'A2F44282',X'498C9205', X'8005A83D',X'A9D4F3AC',X'DCAC200C',X'4BC0700E',X'090C4042', X'B3ACE80E',X'240C5006',X'C00680B0',X'782CB795',X'F9C0A335', X'AED45017',X'500C0C17',X'C073A9F4',X'F48C501F',X'640E080C', X'500EC873',X'AAF40D15',X'500C4FE0',X'68972CF5',X'12E1EA57', X'E017C274',X'80A6B795',X'F9C0A673',X'1059C033',X'80ACF800', X'90BAC008',X'BA0ACAF4',X'80054065',X'80DC4BE0',X'BC0A100A', X'4BC0C883',X'81229341',X'8180E41F',X'1122A150',X'C813A011', X'A2D39320',X'BA0AF800',X'98019308',X'BC0A100A',X'A83D9316', X'782CB795',X'F9C0A735',X'5017500C',X'0C17C073',X'AE93501F', X'930F0D15',X'68972D15',X'12E1C033',X'80DCF800',X'90BAC008', X'BA0AAB74',X'A2739341',X'82E1E006',X'5826EFF4',X'50085826', X'32A82768',X'C014AEF4',X'9012ABF2',X'5826F177',X'F168FC00', X'91972C37',X'C1A83C37',X'61770835',X'E40C6908',X'DFEC2173', X'58260CF5',X'501F9341',X'82E1E018',X'5826F177',X'AEB49197', X'58262C37',X'C1DAFC00',X'501F9341',X'82E1E419',X'6077A2B4', X'F573F9C0',X'C21481B4',X'C1F4C9D4',X'82E10835',X'0C06C01F', X'B3B7B01D',X'A15DA17D',X'A1B04298',X'A3144D81',X'10050905', X'8180DEF3',X'200CEB6C',X'E00CF168',X'DDE321C8',X'486829E8', X'2D4C632C',X'0C2C7B8C',X'0C2C70CC',X'0C0DC00E',X'4D00117D', X'0C4C70AC',X'4920F56E',X'117D0C4C',X'70AC0C25',X'70C88180', X'0C2C708C',X'48408170',X'0C2C70AC',X'0C257AC8',X'814B4840', X'0C2C790C',X'920B817D',X'640F0815',X'F575117D',X'09150C1F', X'C006920B',X'817D5C26',X'5004EBA4',X'E004920B',X'817D5C26', X'9002ABE2',X'920B817D',X'5C26500D',X'EBADE01F',X'93478180', X'E00D920B',X'81315406',X'500C49C0',X'C00C49E0',X'81314B20', X'920B817D',X'4B00C0E3',X'817A6E2F',X'08104716',X'117D5E2F', X'50108178',X'4840A500',X'11854840',X'9205A120',X'A1E0A2E4', X'0C07C101',X'DDE321C0',X'4BE0C053',X'A011A3E9',X'A6D31005', X'48409205',X'A2E4B160',X'A1E00C0B',X'C0C083E2',X'EB532418', X'C01F541F',X'501DEBDD',X'42229801',X'C0FD9802',X'E00CA8EC', X'DDF36A8C',X'EF5D200C',X'034C0CB5',X'732C28B5',X'EB5D2418', X'C01F541F',X'501DC8FD',X'980126D3',X'119C0855',X'C9F48287', X'C9D482B9',X'919782E1',X'0835F16C',X'DCFD21CC',X'C1FD81D7', X'C23482E1',X'292CB67A',X'F9A0F17B',X'0C2C612C',X'FC006ACC', X'498842A2',X'A21A4D8F',X'11D1498D',X'09B5A354',X'A233BC0A', X'100A82E1',X'0855282C',X'CA3481E3',X'2CAC628C',X'2C2C62CC', X'2C6C630C',X'FC00634C',X'C0DD81EA',X'A01FA03F',X'B3F70D75', X'11FE0835',X'EB5D075A',X'C00CC7FD',X'706CC2B4',X'82E12419', X'C00C582C',X'0C555017',X'500CA774',X'501F9341',X'82E1E41F', X'60F74284',X'4983A754',X'10112895',X'2D1512E1',X'EA15E00C', X'DCF5686C',X'E0159801',X'2887C007',X'98020887',X'9801B795', X'F9C08217',X'DE5221D5',X'AB55A375',X'A315A335',X'906282F6', X'82E3C053',X'A0110C13',X'C1D0A190',X'BA099801',X'B715F9C0', X'AA33CA5A',X'A2F3CB54',X'8252CB14',X'8238C334',X'823FC2D3', X'8232A633',X'10050855',X'AB34C29A',X'82F082F6',X'82F00835', X'AB149242',X'82D92A35',X'ADB011B4',X'0835A735',X'12F6EA3B', X'E01BF56C',X'689BC09D',X'AA9ADB7A',X'F55DC16C',X'DC6C216C', X'C61A686C',X'CAF49801',X'9802C87D',X'921CAB54',X'924282D9', X'C09D825F',X'C23AC19D',X'82ABA1D4',X'A69310C2',X'C0BD82D7', X'C23AC19D',X'8266A693',X'10C2EB53',X'E00CCA3A',X'082C0C2C', X'C1D3D9F3',X'1C2C200C',X'034C2D35',X'708C2CB5',X'11B982E1', X'C87D921C',X'AA53C19D',X'827DA1F4',X'A69310C2',X'DDF3200C', X'EB4C0753',X'C00C2DD5',X'708C0CB5',X'12E10833',X'919782E1', X'0895C0DD',X'8293A01F',X'A03FB3F7',X'498B0955',X'A7541011', X'EB5D075A',X'C00CC7FD',X'706CC2B4',X'82E12419',X'C00C582C', X'0C555017',X'500CA774',X'501F9341',X'82E1E41F',X'60B7498B', X'A7541011',X'2D1512E1',X'EB53E00C',X'CA3A082C',X'0C2CC1D3', X'D9F31C2C',X'200C034C',X'2D35786C',X'82E128B5',X'919782E1', X'C87D921C',X'C09D82CE',X'C19D82C4',X'A1D4A693',X'10C2DDF3', X'200CEB4C',X'0753C00C',X'0CB5706C',X'82E10C33',X'12B809D5', X'C0BD82D7',X'C19D82D5',X'A69310C2',X'AE3A1266',X'A51012DB', X'A130A2F4',X'EA3BE411',X'F9000C1A',X'C1B082E8',X'498D9205', X'CA138213',X'A2F4A130',X'A1F00C13',X'C1D0C053',X'A011AA73', X'BA09A6D3',X'1011B170',X'0C1AC0F0',X'DCFA21B0',X'82EA9205', X'A170A5F0',X'12DAAAF3',X'CAF48022',X'F17DF17F',X'B3D74284', X'A33483D8',X'8005B715',X'F9C00C75',X'12F64BC0',X'740E5008', X'C8089802',X'4BE08801',X'F08C640E',X'080C540E',X'500C4BE0', X'98014043',X'B7AC131D',X'F3ACDCAC',X'200C090C',X'E80E200C', X'98019316',X'084C540C',X'50061C4E',X'68669308',X'98016C2C', X'0810640C',X'08114067',X'E00C540C',X'5006B806',X'640C0806', X'930FB809',X'AAD3F170',X'C8114880',X'F1719803',X'229F283F', X'A81FD83F',X'09159802',X'EA37E017',X'C43D62B7',X'4137413A', X'EFB4787F',X'EBA40835',X'07BFC008',X'EFBF60A8',X'E4087088', X'9801E008',X'0835A808',X'DFC82008',X'EE92787F',X'EA822008', X'5C28500C',X'5008EE3F',X'900BC374',X'8368DEEC',X'787DDB6C', X'E008EB74',X'0368B708',X'78689801',X'08353828',X'F0CCAA94', X'C82CA294',X'EA3F2637',X'C0082828',X'C9A89801',X'EA28022C', X'AFEB786C',X'98010835',X'C06B8385',X'C02B9801',X'A3EB540B', X'900B837D',X'0835CA94',X'8395C02B',X'9801EA3F',X'C83DEA28', X'E01FB34C',X'382CF1EB',X'D83F0875',X'328B9802',X'08354063', X'2855C02B',X'98010875',X'E81FC83D',X'E008B2AC',X'382CF07F', X'EA37241F',X'C00CABEB',X'F17EDD28',X'21DEEA8B',X'201E282C', X'F168DD2C',X'21C8D928',X'2017B108',X'E8080017',X'B2A8E808', X'000CFC00',X'716C583E',X'C03D285E',X'040C9016',X'C0369801', X'FC007ACC',X'541E9008',X'C0289801',X'C81783CA',X'085EC83D', X'289E200C',X'B12BE80B',X'0017EA88',X'E008A048',X'D82CC03D', X'D83F32C8',X'08359802',X'A273F57A',X'F8604D8A',X'1005C334', X'80058059',X'CAD4A274',X'8005AC53',X'118A0000',X'00000000'(9), X'0000F2B2',X'B80AA213',X'498D9800',X'0C030005',X'F621BEA3' %LIST !* %INTEGER ISA,I ISA=X'40000800'!PT<<16 *LB_ISA; *LSS_2; *ST_(0+%B); ! master clear WAIT(50) %IF FLAG=0 %THEN SLAVES ON OFF(0); ! FLAG=1 if called from chopsupe CA0=0 CA0_PAW=LOAD MICROPROGRAM CA0_CSAW1=REALISE(ADDR(GPC MPROG(0))) CA0_MARK=-1 *LB_I; *LSS_1; *ST_(0+%B) I=100*COM_INSPERSEC; ! 1 sec approx I=I-1 %UNTIL (CA0_CRESP0#0 %AND CA0_MARK=-1) %OR I<=0 %IF CA0_CRESP0&NORMAL TERMINATION=0 %THEN %RESULT=1<<24!CA0_CRESP0 WAIT(50) CA0=0 CA0_PAW=DO CONTROLLER REQUEST CA0_CSAW0=INIT CONTROLLER CA0_CSAW1=REALISE(ADDR(INI)) GET PSTB(INI_PSTL,INI_PSTB) INI_CAA=CAAS(CNO TO GDC(PT-LOCNO)) INI_SOE=0 CA==RECORD(INI_CAA) CA=0 CA_MARK=-1 CA0_MARK=-1 *LB_ISA; *LSS_1; *ST_(0+%B); ! initialise I=100*COM_INSPERSEC I=I-1 %UNTIL (CA_CRESP0#0 %AND CA_MARK=-1) %OR I<=0 %IF FLAG=0 %THEN SLAVES ON OFF(-1) %IF CA_CRESP0&NORMAL TERMINATION=0 %START %IF MULTI OCP=YES %THEN RESERVE LOG PRINTSTRING("GPC--INIT fails CA0:") DUMPTABLE(0,REAL0AD,32) PRINTSTRING("CA:") DUMPTABLE(0,INI_CAA,272) PRINTSTRING("INI:") DUMPTABLE(0,ADDR(INI),16) %IF MULTI OCP=YES %THEN RELEASE LOG %IF CA_CRESP0=0 %THEN I=2<<24!CA0_CRESP0 %C %ELSE I=3<<24!CA_CRESP0 %FINISH CA_CRESP0=0 CA_MARK=-1 %RESULT=I %END %FINISH !* %IF CSU FITTED=YES %START %EXTERNALROUTINE CSU(%RECORD(PARMF)%NAME P) %RECORDFORMAT DEVICE ENTRY F(%INTEGER SER, GPTSM, PROPADDR, %C SECS SINCE, CA A, MYCCBA, LB A, AL A, X2, RESP0, %C RESP1, SENSE1, SENSE2, SENSE3, SENSE4, X3, X4, IDENT %C , X5, MNEMONIC, DEVICE ENTRY S, PAW, U SAW 0, %C U CCB A, SENSE DATA A, LOG MASK, TRTAB AD, UA SIZE, %C UA AD, TIMEOUT, PROPS0, PROPS1) %RECORD(PARMF) Q %RECORD(DEVICE ENTRY F)%NAME DEV %SWITCH ACT(0:10) %OWNINTEGERARRAY DTODA(0:9)=NOT ALLOCATED(*) %CONSTINTEGER CSU SNO=CSU DEST>>16 %IF KMONNING=YES %AND KMON>>CSU SNO&1#0 %THEN PKMONREC("CSU :",P) ->ACT(P_DEST&255) ACT(0): ! initialise call from GDC Q=0 Q_DEST=GDC DEST!11; ! allocate Q_SRCE=P_DEST!1 Q_P1=P_P1 Q_P2=P_DEST!5; ! interrupts to ACT 5 PON(Q) %RETURN ACT(1): ! reply from allocate %UNLESS P_P1=0 %START; ! failed BYTEINTEGER(ADDR(P_P6))=3 OPMESS(STRING(ADDR(P_P6))." alloc fails ".HTOS(P_P1,1)) %RETURN %FINISH DEV==RECORD(P_P3) DTODA(P_P6&255-'0')=P_P3 %RETURN ACT(2): ! deallocate %RETURN ACT(3): ! deallocate reply %RETURN ACT(5): ! interrupt from GDC %RETURN ACT(6): ! switch device %RETURN ACT(7): ! switch controller %RETURN %END %FINISH %ENDOFFILE