TITLE D60SER -- UUO AND INTERRUPT SERVICE FOR THE DL11 AND DTE-20 DN60 SERIES - V032 SUBTTL ED FORTMILLER/EGF and JOHN SAUTER/JBS 17 NOV 87 SEARCH F,S $RELOC $HIGH ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION ; 1976,1977,1978,1979,1980,1982,1984,1986,1988. ;ALL RIGHTS RESERVED. .CPYRT<1976,1988> XP V60SER,032 ;VERSION NUMBER ENTRY D60SER D60SER: ;DEFINE THE DN60 FUNCTION CODES ; F6.RD==:1 ;READ DATA F6.WD==:2 ;WRITE DATA F6.RDS==:3 ;READ DEVICE STATUS F6.WDC==:4 ;WRITE DEVICE STATUS F6.RLS==:5 ;READ LINE STATUS F6.WLC==:6 ;WRITE LINE COMMAND F6.R6S==:7 ;READ DN60 STATUS F6.W6C==:^D8 ;WRITE DN60 COMMAND F6.QMX==:^D8 ;LARGEST FUNCTION ALLOWED IN ; .QUE11 FUNCTION F6.EXM==:^D9 ;EXAMINE PDP11 MEMORY F6.DEP==:^D10 ;DEPOSIT INTO PDP11 MEMORY F6.MAX==:^D10 ;LARGEST FUNCTION CODE ;BIT DEFINITIONS IN THE (LH) OF DLXCEU ;DEFINE A BIT THAT GETS SET IN THE (LH) OF DLXCEU TO ; INDICATE THAT THE .C11UQ FUNCTION IS THE ONE BEING DONE ; D6.Q11==:1 ;.C11QU FUNCTION IN PROGRESS ;DEFINE A BIT WHICH WHEN SET IN THE (LH) OF DLXCEU INDICATES ; THAT THE JOB WAS LOCKED BEFORE ISSUING THE CAL11. UUO. THIS ; BIT WILL NOT BE SET FOR EXM/DEP AS WE DON'T SET NSHF OR NSWP ; IN THIS CASE. ; D6.ALK==:2 ;SET IF JOB LOCKED PRIOR TO ; DOING .C11QU ;D60TMO ROUTINE TO SEE IF THE CALL11 HAS TIMED OUT ;CALL W := POINTER TO BASE TABLE ;RETURN CPOPJ ;NOT TIMED OUT YET ; CPOPJ1 ;TIMED OUT, D60WAK HAS BEEN CALLED. D60TMO::SKIPN T2,DLXTIM##(W) ;SEE IF TIMING (NON 0) POPJ P, ;NOT TIMING SKIPE T1,DLXCEU##(W) ;CAL11. UUO BEING USED? CAMLE T2,SYSUPT## ;SEE IF WE TIMED OUT? POPJ P, ;NOT TIMED OUT YET SETZM DLXTIM##(W) ;CLEAR OUT TIME PUSHJ P,D60WAK ;GET THE JOB OUT OF EW AND EXIT RETSKP ;SIGNAL A TIME-OUT HAS HAPPENED ;HERE TO FINISH THE SETUP WHEN THE PDP11 IS FIRST ; RECOGNIZED AS BEING A PDP11. ; ; CALL: JRST D60SUP ;W POINTS TO THE BASE TABLE ; D60SUP::SETZM DLXCEU##(W) ;CLEAR CAL11. USERS JOB NUMBER MOVE T1,[XWD MC11FN,C11FTB] MOVEM T1,DLXCAL##(W) ;CAL11. POINTER PUSH P,J ;PRESERVE J MOVE J,DLXFEK##(W) ;GET THE FEK ADDRESS JUMPE J,JPOPJ## ;IF NO FEK, MUST BE A KS-10 MOVSI T1,FK.ONL ;GET THE ONLINE BIT IORB T1,FEKBLK(J) ; AND MARK THE FEK AS ONLINE JRST JPOPJ## ; AND RETURN SUBTTL CAL11. UUO ;COME HERE ON CAL11. UUO FROM COMDEV. ;CALLING SEQUENCE IS: ; MOVE AC,[XWD LENGTH,BLOCK] ; CAL11. AC, ; ERROR RETURN ; OK RETURN ;BLOCK: EXP FUNCTION CODE ; ARGUMENT (1) ... ; ;ENTER FROM COMDEV WITH DL10 BASE IN W, LENGTH OF BLOCK IN T3. ;COMDEV DOES THE DISPATCH BASED ON THE FOLLOWING TABLE. THE ; HIGH ORDER BIT, IF SET, INDICATES THAT THE USER MUST HAVE ; THE "POKE" PRIV. C11FTB::XWD 400000,DEP11 ;(0) DEPOSIT TO -11 XWD 400000,EXAM11 ;(1) EXAMINE THE -11 XWD 400000,QUE11 ;(2) PERFORM A DN60 FUNCTION XWD 0,NAME11 ;(3) RETURN NAME OF PGM IN 11 XWD 0,DOWN11 ;(4) IS PORT UP OR DOWN? XWD 400000,ECOD2## ;(5) SEND XWD 400000,ECOD2## ;(6) RECEIVE XWD 0,TYP11 ;(7) TYPE MC11FN==:.-C11FTB ;LENGTH OF TABLE ; VALUES OF BITS IN DLXSWD: D60.DP==:1 ;DEPOSIT D60.EX==:2 ;EXAMINE D60.ER==:4 ;ADDRESS ERROR SUBTTL CAL11. UUO ERROR CODES COMMENT \ CODE MEANING ---- ------- 1 Caller does not have POKE privledges 2 The function is undefined on this type of front end 3 Invalid DL10 port number 4 CAL11. facility in use, try again later 5 No answer from the front end after 1-2 seconds 6 Queue entry too short (DC76 only) 7 Not enough arguments 10 Examine/Deposit address was invalid (more than 16 bits or the front end flagged it as invalid), or the deposit data was more than 16 bits 11 In QUE11, Illegal function code, Address check, Illegal byte size, Byte offset is outside the buffer or the buffer is too large (requires more than 16 DL10 byte pointers) 12 DTESER couldn't get any free core 13 DTE - reload bit set or primary protocol is not running. 14 DTE - there never will be enough EVM \ ;SUBROUTINE TO EXAMINE OR DEPOSIT PDP11 MEMORY ; ; CALL: MOVE T3,+LENGTH ; MOVEI W,ADDRESS OF THE BASE TABLE ; DEP11: SOJLE T3,ECOD7## ;MUST HAVE 2 ARGS (ADDR & DATA) PUSHJ P,GET1WD ;GET THE ADDRESS TO DEPOSIT INTO MOVE T3,T1 PUSHJ P,GET1WD ;GET THE WORD TO DEPOSIT SKIPL T4,T1 ;MAKE SURE DEPOSIT DATA IS CAILE T4,177777 ; IN THE RANGE OF 0-177777 PJRST ECOD10## ;**ERROR-10** BECAUSE DEPOSIT ; DATA TO LARGE. HRLI T4,-1 ;FLAG ITS A DEPOSIT MOVEI T1,D60.DP ;DEPOSIT FUNCTION JRST DEPEXM ;NOW GO ATTEMPT TO DO THE DEPOSIT EXAM11: JUMPLE T3,ECOD7## ;MUST HAVE AN ARG. PUSHJ P,GET1WD ;GET THE ADDRESS TO EXAMINE MOVE T3,T1 SETZ T4, ;ZERO THE DATA WORD AND FLAG EXAMINE MOVEI T1,D60.EX ;EXAMINE FUNCTION DEPEXM: SKIPL T3 ;SEE IF ADDRESS IS IN THE CAILE T3,177777 ; RANGE OF 0-177777 PJRST ECOD10## ;**ERROR-10** BECAUSE OF ILLEGAL ADDRESS JSP T2,CHKCEU ;SEE IF ANYONE USING CAL11 ; **ERROR-4** IF SO MOVEI P1,D6F.ED ;GET THE EXAMINE/DEPOSIT FUNCTION JRST @DLXCEV##(W) ; AND LET THE DRIVER DO THE REST ;SUBROUTINE TO RETURN THE TYPE OF PDP11 ; TYP11: MOVE T1,DLXTYP##(W) ;GET TYPE CODE FOR DN60 PJRST STOTC1## ;RETURN DN60 TYPE ;REMOVE ENTIRE GETADR ROUTINE ;[EDIT 023] ;HERE TO GET AN EXAMINE/DEPOSIT ADDRESS ; ; CALL: JSP T4,GETADR ;T3 CONTAINS THE LENGTH ; RETURN ;UNLESS LENGTH TOO SHORT, THEN ; ; GIVE ERROR-7 TO THE USER. ON ; ; NON ERROR RETURN: ; ; AC (W) IS SAVED ON THE PDL ; ; AC (T3) CONTAINS THE ADDRESS ; GETADR: SOJL T3,ECOD7## ;**ERROR-7** IF NOT ENOUGH ARGS PUSH P,W ;SAVE AC (W) PUSHJ P,GETWD1## ;GET THE ADDRESS TO EXAMINE/DEPOSIT MOVE T3,T1 ;COPY ADDRESS HERE JRST (T4) ;RETURN TO THE CALLER ;HERE TO PERFORM .C11QU (2) FUNCTION ; ; CALL: MOVE T3,+LENGTH ; MOVEI W,ADDRESS OF THE BASE TABLE ; QUE11: SUBI T3,5 ;SEE IF ENOUGH ARGS SUPPLIED PJUMPL T3,ECOD7## ;**ERROR-7** BECAUSE NOT ENOUGH ARGS JSP T2,CHKCEU ;SEE IF ANYONE USING THE CAL11. UUO ; **ERROR-4** IF SO PUSHJ P,GET1WD ;GET LINE NUMBER,,DEVICE NUMBER MOVE P2,T1 ;SAVE LINE NUMBER,,DEVICE NUMBER PUSHJ P,GET1WD ;GET NUMBER OF BYTES,,FUNCTION CODE HRRZ P4,T1 ;REMEMBER THE FUNCTION CODE CAIL P4,1 ;RANGE CHECK THE FUNCTION CAILE P4,F6.QMX ; FOR A RANGE OF 1-10. PJRST ECOD11## ;**ERROR-11** ILLEGAL FUNCTION CODE HLL P4,T1 ;REMEMBER TOTAL NUMBER OF BYTES MOVSS P4 ;FUNCTION CODE,,NUMBER OF BYTES PUSHJ P,GET1WD ;GET LENGTH OF BUFFER,,BUFFER ADDRESS MOVE P3,T1 ;REMEMBER LENGTH,,BUFFER ADDRESS PUSHJ P,ADRCHK ;ADDRESS CHECK THE BUFFER PJRST ECOD11## ;**ERROR-11** BECAUSE OF ADDRESS CHECK HLRZ T4,P3 ;GET THE LENGTH OF THE BUFFER ANDI P3,-1 ;LEAVE ONLY THE BUFFER ADDRESS PUSHJ P,GET1WD ;GET NUMBER OF BYTES PER WORD(12 BITS), ; POSITION OF FIRST BYTE (24 BITS) MOVE F,T1 ;GET THE POSITION IN HERE TLZ F,777700 ;KEEP ONLY POSITION OF THE FIRST BYTE LSH T1,-^D24 ;KEEP ONLY THE NUMBER OF BYTES PER WORD ;%%% MOVEI S,4 ;ASSUME MIN NUMBER OF BYTES PER ;%%% ; WORD FOR A DTE ;%%% SKIPL P1 ;BUT ARE WE TALKING TO A DTE? MOVEI S,3 ;NO SET MIN NUMBER OF BYTES PER ; WORD FOR A DL10 CAML T1,S ;RANGE CHECK BYTE SIZE CAILE T1,6 ; FOR A RANGE OF (3-6 FOR A DL10) ; AND (4-6 FOR A DTE) PJRST ECOD11## ;**ERROR-11** ILLEGAL BYTE SIZE MOVE S,T1 ; AND REMEMBER IT. ; ;TO COMPUTE THE FIRST ADDRESS USING IN THE BUFFER ; ; (BYTE POSITION)/(BYTE SIZE)+(BUFFER ADDRESS) ; AC(U) IS USED TO REMEMBER THE REMAINDER FROM ; (BYTE POSITION)/(BYTE SIZE) FOR LATER USE ; MOVE T1,F ;GET BYTE POSITION IDIV T1,S ;(BYTE POSITION)/(BYTE SIZE) MOVE U,T2 ;REMEMBER THE REMAINDER ADD T1,P3 ;PRESTO, THE FIRST ADDRESS ; ;TO COMPUTE THE LAST ADDRESS USED IN THE BUFFER ; ; (((BYTE POSITION)+(NUMBER OF BYTES)-1)/(BYTE SIZE))+(BUFFER ADDRESS) ; MOVE T2,F ;GET POSITION OF THE FIRST BYTE ADDI T2,-1(P4) ;ADD IN THE NUMBER OF BYTES - 1 IDIV T2,S ;NOW DIVIDE BY THE BYTE SIZE ADD T2,P3 ;ADD THE BUFFER ADDRESS AND ; PRESTO THE LAST ADDRESS USED. MOVE T3,P3 ;GET THE BUFFER ADDRESS ADDI T3,-1(T4) ; AND ADD THE LENGTH-1 CAMLE T2,T3 ;SEE IF COMPUTED BUFFER ; IS WITHIN THE REAL BUFFER PJRST ECOD11## ;**ERROR-11** BECAUSE OF ADDRESS CHECK ; ;TO COMPUTE THE WORD COUNT ; ; (LAST ADDRESS)-(FIRST ADDRESS)+1 ; SUBI T2,-1(T1) ;COMPUTE LENGTH OF BUFFER WHICH ; WE'LL REFER TO AS "WORD COUNT" MOVEI P1,D6F.QU ;GET THE QUEUE11 FUNCTION CODE JRST @DLXCEV##(W) ; AND LET THE DRIVER TO THE REST ;COME HERE TO RETURN THE NAME OF THE PDP-11 PROGRAM. ; IN THE CASE OF A PDP11 ON A DL10 THE NAME RETURNED ; WILL BE THE NAME THE PDP11 GAVE US BUT ON A DTE ; THE NAME WILL BE RETURNED FROM THE BASE TABLE. ; ; CALL: PUSHJ P,NAME11 ;W POINTS TO THE BASE TABLE ; NAME11: MOVE T1,DLXNMT##(W) ;PICK UP NAME PJRST STOTC1## ;SKIP RETURN, GIVING NAME ;COME HERE TO TELL THE STATUS OF THE PDP-11 PROGRAM. ; RETURN A 1 TO THE USER IF THE PDP11 IS UP ; OR 0 IF ITS DOWN. ; ;W POINTS TO THE BASE TABLE DOWN11: MOVEI P1,D6F.UD ;FUNCTION IS UP/DOWN PUSHJ P,@DLXCEV##(W) ;CALL THE DRIVER SPECIFIC CODE TDZA T1,T1 ;PDP-11 IS DOWN MOVEI T1,1 ;UP. PJRST STOTC1## ;SKIP RETURN. ;THIS ROUTINE IS CALLED TO PUT A JOB INTO ; THE EVENT WAIT STATE. ; ; CALL: PUSHJ P,EVWAIT ;W POINTS TO THE BASE TABLE ; RETURN ;ALWAYS ; D60EVW::PUSH P,M ;SAVE "M" JRST D60EV2 ;SEE IF A MSG CAME UNEXPECTEDLY D60EV1: MOVEI T1,EV.D60 ;THE EVENT WAIT CODE FOR THE DN60 MOVE J,.CPJOB## ;GET THE JOB NUMBER PUSHJ P,FSLEEP## ;PUT JOB INTO EVENT WAIT D60EV2: SKIPE DLXTIM##(W) ;SEE IF A DN60 WAKE JRST D60EV1 ;NO, IT WAS SOME OTHER CLOWN ; SO GO WAIT SOME MORE. IFE FTKS10,< ;KS FREES IT BY ITSELF SETZM DLXCEU##(W) ;FREE UP THE CAL11. UUO > PJRST MPOPJ## ;RESTORE "M" AND RETURN TO ; THE CALLER ;THIS ROUTINE IS CALLED TO GET A DN60 JOB OUT OF ; EVENT WAIT ; ; CALL: PUSHJ P,D60WAK ;T1 CONTANS JOB NUMBER ; ;W POINTS TO THE BASE TABLE ; RETURN ;WITH DLXTIM = 0 ; D60WAK::PUSH P,J ;SAVE J SETZM DLXTIM##(W) ;FLAG WE GOT THE JOB OUT OF EW PUSHJ P,D60LKC ;SEE IF WE ARE TO UNLOCK HIM ; ALSO RETURNS JOB NUMBER IN T1 PUSHJ P,D60ULJ ;YES, WE LOCKED HIM SO UNLOCK HIM POP P,J ;RESTORE J PJRST EWAKE## ;GO GET HIM OUT OF EW ;THIS ROUTINE IS CALLED TO PUT THE TIME IN ; THE BASE TABLE THAT THE JOB TIMES OUT AT. ; ; CALL: PUSHJ P,SETTIM ;T1 CONTAINS NUMBER OF SECONDS ; ;W POINTS TO THE BASE TABLE ; RETURN ;ALWAYS ; D60TIM::IMUL T1,TICSEC## ;CONVERT TO JIFFYS ADD T1,SYSUPT## ;ADDING THIS MAKES THE TIME ; THAT WE TIME-OUT AT. MOVEM T1,DLXTIM##(W) ;SAVE SO ONCE-A-SECOND CODE ; WILL KNOW THE TIME-OUT TIME POPJ P, ;RETURN TO CALLER ;SUBROUTINE TO GET 1 WORD FROM THE USERS BLOCK ; ; CALL: PUSHJ P,GET1WD ; ; RETURN ;T1 HAS THE WORD ; GET1WD: PUSH P,W ;MUST PRESERVE AC(W) PUSHJ P,GETWD1## ;GET A WORD FROM USER BLOCK PJRST WPOPJ## ;RESTORE AC(W) ; AND RETURN WITH WORD IN AC(T1) ;SUBROUTINE TO CHECK IF THE CAL11. UUO IS IN USE ; ; CALL: JSP T2,CHKCEU ; ; RETURN ;IF NOT IN USE, IF IN ; ; USE GIVE **ERROR-4** ; CHKCEU: HRRZ S,DLXCEU##(W) ;GET JOB NUMBER FROM BASE TABLE CAMN J,S ;IS THIS THE USER WHO IS WAITING? SETZM DLXCEU##(W) ;YES, MUST HAVE USED ^C SKIPE DLXCEU##(W) ;SEE IF ANY USER WAITING PJRST ECOD4## ;**ERROR-4** BECAUSE UUO IS BEING USED PJRST (T2) ;RETURN TO THE CALLER ;SUBROUTINE TO UNLOCK THE JOB ; ; CALL: PUSHJ P,D60ULJ ;WITH JOB NUMBER IN T1 ; CALL: PUSHJ P,D60UNL ;IF JOB NUMBER UNKNOWN (UUO LEVEL) ; RETURN ;T1 PRESERVED, J CONTAINS JOB NUMBER ; D60ULJ::SKIPA J,T1 ;GET JOB NUMBER FROM T1 D60UNL::MOVE J,.CPJOB## ;GET THE JOB NUMBER PUSH P,T1 ;SAVE THIS MOVSI T1,NSHF!NSWP ;THE LOCK BITS ANDCAM T1,JBTSTS##(J) ;CLEAR THE JOB PJRST TPOPJ## ;RESTORE T1 AND RETURN ;SUBROUTINE TO DETERMINE IF THE JOB IS TO BE UNLOCKED ; BEFORE RETURNING THE TO USER ; ; CALL: PUSHJ P,D60LKC ;W POINTS TO THE BASE TABLE ; RETURN ;IF NEED TO UNLOCK AND T1 CONTAINS JOB NUMBER ; RETURN ;IF NOT TO UNLOCK JOB AND T1 ; ; CONTAINS JOB NUMBER ; D60LKC::MOVE T1,DLXCEU##(W) ;GET BITS,,JOB NUMBER TLZN T1,D6.Q11 ;QUE11 FUNCTION? PJRST CPOPJ1## ;NO, EXM/DEP TLZN T1,D6.ALK ;YES, WAS HE LOCKED BEFORE CAL11. ? POPJ P, ;NO, WE MUST UNLOCK HIM PJRST CPOPJ1## ;YES, DON'T UNLOCK HIM ;SUBROUTINE TO VERIFY THAT THE REQUIRED PAGES ARE ; VALID AND IN CORE. IF VM IF THE PAGE(S) ARE NOT IN ; CORE ATTEMPT TO BRING THEM IN. ; ; CALL: PUSHJ P,ADRCHK ;P3 CONTAINS XWD LENGTH,START ADDRESS ; RETURN ;IF ANY ADDRESS ERRORS ; RETURN ;IF BUFFER IS IN CORE ; ADRCHK: HRRZ T1,P3 ;LOW ADDRESS OF BUFFER HLRZ T2,P3 ;THE LENGTH OF THE BUFFER ADDI T2,-1(P3) ;LAST ADDRESS OF THE BUFFER PUSH P,T2 ;SAVE THE LAST ADDRESS ADRC1: PUSHJ P,IADRCK## ;MAKE SURE VALID ADDRESS PJRST T2POPJ## ;BAD ADDR, CLEAN PDL, NON-SKIP RETURN PJRST UUOFLT## ;PAGE FAULT - CALL THE PFH ADDI T1,PAGSIZ ;GO TO THE NEXT PAGE CAMGE T1,(P) ; BEYOND THE END OF OUR BUFFER JRST ADRC1 ;NO, CHECK THIS PAGE POP P,T1 ;GET THE LAST ADDRESS OF THE BUFFER PUSHJ P,IADRCK## ;CHECK THE LAST ADDRESS POPJ P, ;BAD ADDRESS PJRST UUOFLT## ;PAGE FAULT - CALL THE PFH JRST CPOPJ1## ;SUCCESS $HIGH $LIT D60END::END