ASMB,Q,C ** RTE-IV EQUIPMENT (UN)LOCKING MODULES ** HED ** EQUIPMENT LOCKING MODULE ** * NAME: EQTRQ * SOURCE: 92067-18478 * RELOC: 92067-16268 * PGMR: AVD * * **************************************************************** * * (C) COPYRIGHT HEWLETT-PACKARD COMPANY 1979. ALL RIGHTS * * * RESERVED. NO PART OF THIS PROGRAM MAY BE PHOTOCOPIED, * * * REPRODUCED OR TRANSLATED TO ANOTHER PROGRAM LANGUAGE WITHOUT * * * THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY. * * **************************************************************** * NAM EQTRQ,6 92067-1X478 REV.2040 800724 * ENT EQTRQ EXT $LIBR,$ERAB,$XEQ,$LIST,$PVCN,$DRAD EXT LUTRU,$CVT3,MESSS,$ELTB,$SCD3,$RNTB * SUP A EQU 0 B EQU 1 * ***************************************************************************** * THE EQUIPMENT LOCK FEATURE ALLOWS A PROGRAM TO LOCK THE EQUIPMENT * (CONTROLLER) ASSOCIATED WITH A GIVEN LU TO THE PROGRAM EXCLUSIVELY. * ANY OTHER PROGRAM IS PUT IN THE WAIT LIST WHEN IT EITHER REQUESTS A LOCK * ON EFFECTIVELY THE SAME EQUIPMENT, REQUESTS A LOCK WHEN THERE IS (TEMPO- * RARILY) NO PLACE TO DOCK THE LOCK (I. E., THE LOCKING TABLE IS FULL), OR * ATTEMPTS I/O THROUGH AN EQUIPMENT THAT IS LOCKED (TO SOMEONE ELSE). * WHEN THE EQUIPMENT IS EVENTUALLY UNLOCKED, ATTEMPT WILL BE MADE TO * SCHEDULE THE WAITING PROGRAM. * WHEN A PROGRAM TERMINATES NORMALLY (I. E., THROUGH AN EXEC 6 CALL WITH * THE NOT SAVING RESOURCES OPTION), ALL EQUIPMENTS LOCKED TO HER WILL BE * RELEASED. IF THE TERMINATION IS A SAVING RESOURCES ONE, EQUIPMENTS * LOCKED TO HER STAY LOCKED TO HER ID SEGMENT ADDRESS (LET'S HOPE SHE CAN * BE RESCHEDULED WITH THE SAME ID SEGMENT ADDRESS). * IF A PROGRAM TERMINATES ABNORMALLY (DEFINED AS THE COMPLEMENT OF THE * MEANING OF "NORMALLY" ABOVE), AND HAD SPECIFIED A LOCK_ON_ABORT OPTION * IN HER LOCKING REQUEST, THE EQUIPMENT STAYS LOCKED--THOUGH NOT TO HER * PER SE. ANOTHER PROGRAM (FATHER? CLONE?? LOVER???) CAN THEN RELOCK IT * TO HIMSELF AND PROCEED TO USE IT. * UNLOCKING OF AN EQUIPMENT IS ALSO DONE WITH THIS SAME CALL, BUT IS * RATHER UNINTERESTING TO DESCRIBE, SO SEE THE DRY E.R.S. BELOW. SKP * * * CALLING SEQUENCE: * * ASSEMBLER: * * EXT EQTRQ * . * . * . * JSB EQTRQ * DEF *+3 * DEF IOPT * DEF LU * RETURN----- * . * . * . * LU DEC LU # WHOSE ASSOCIATED EQT. IS TO BE (UN)LOCKED * IOPT DEC OPTION_WORD (DESCRIBED BELOW) * * * FORTRAN: * * CALL EQTRQ (IOPT, LU) *WITH IOPT BIT 14 CLEAR * RETURN POINT---- * * -OR- * * CALL EQTRQ (IOPT, LU) *WITH IOPT BIT 14 SET * GO TO ERROR ROUTINE * RETURN POINT---- * * * BIT ASSIGNMENTS IN THE OPTION WORD ARE AS FOLLOWS: * * BIT 0 1/0 LOCK/UNLOCK * * NO ABORT ON CALL / * 14 1/0 ERROR, RETURN ASCII / ABORT ON ERROR * CODE IN (A) & (B) / * * IN ADDITION, FOR THE LOCK REQUEST: * * BIT 13 1/0 KEEP EQT. / RELEASE * LOCKED ON / ON * ABORTION / ABORTION * * 15 1/0 WITHOUT WAIT / WITH WAIT SKP * * * (1) THE ABORT ERRORS FOR THIS CALL ARE: * * MNEMONIC MEANING * * EQ00 ILLEGAL LU SPECIFIED * (MAPS INTO SYSTEM CONSOLE EQT) * * EQ01 NON-EXISTENT LU SPECIFIED * (LU SPECIFIED > LUMAX) * * * (2) ON RETURN FROM LOCK_WITHOUT_WAIT: * * (A) = 0 IF SUCCESSFUL, OR EQT. ALREADY LOCKED * TO THIS PROGRAM (LOCKING A BIT BUCKET IS * ALWAYS SUCCESSFUL, AND RESULTS IN A BIG * FAT NOP) ALSO, (B) = LOCKED EQT. #, * * -1 IF EQUIPMENT LOCK TABLE FULL, * * 1 IF EQT. ASSOCIATED WITH SPECIFIED LU LOCKED * TO ANOTHER PROGRAM. * * 2 IF EQT. ASSOCIATED WITH SPECIFIED LU HAS ONE OR * MORE ASSOCIATED LU'S LOCKED TO ANOTHER PROGRAM. * * * (3) ON RETURN FROM THE LOCK_WITH_WAIT REQUEST: * * (A) = 0 AND (B) = LOCKED EQT #. * * IF THE EQUIPMENT SPECIFIED IS LOCKED TO ANOTHER PROGRAM, OR THE * EQUIPMENT LOCK TABLE IS FULL, THE CALLING PROGRAM * IS PUT IN STATE 3 (GENERAL WAIT) UNTIL THE REQUEST * CAN BE FULFILLED. * * * (4) ON RETURN FROM UNLOCK: * * (A) = 0 IF SUCCESSFUL, * * -1 IF EQT. ASSOCIATED WITH SPECIFIED LU WAS NOT * LOCKED TO BEGIN WITH, * * 1 IF EQT. ASSOCIATED WITH SPECIFIED LU LOCKED * TO ANOTHER PROGRAM, * * 2 IF EQT. IS BUSY WITH LOCKER'S I/O. * ******************************************************************** SKP * * EQTRQ NOP * JSB $LIBR PLEASE_MAKE_ME_PRIVILEGED CALL. NOP * CLA CLEAR PRIVILEGED COUNTER SINCE STA $PVCN WE WON'T RETURN VIA $LIBX. * CCA ADA EQTRQ SET CALLING ADDR IN SUSP. WORD XSA XSUSP,I IN CASE OF SUSPENSION. * LDA EQTRQ,I SET RETURN ADDR JSB $DRAD (RESOLVE INDIRECTS FOR FTN CALLS) STA RQRTN IN CASE OF ABORT. * ISZ EQTRQ THIS POINTS EQTRQ TO P+2. LDA EQTRQ,I GET OPTION WORD JSB $DRAD (RESOLVE INDIRECTS FOR FTN CALLS) LDA A,I SPECIFIED IN CALL. RAL,CLE,ELA GET BIT 14 (NO_ABORT) IN E. LDB XEQT GET TO THE STATUS WORD (WORD ADB D15 16 OF THE ID SEGMENT). XLA B,I PICK UP STATUS. RAL,ERA PUT (E) IN BIT 15 XSA B,I OF THE STATUS WORD. SSA AND IF NO_ABORT BIT WAS SET, BUMP THE ISZ RQRTN RETURN ADDR (RTE NO_ABORT MECHANISM). * LDA EQTRQ PICK UP ADA D1 THE LU # LDA A,I SPECIFIED JSB $DRAD (RESOLVE INDIRECTS FOR FTN CALLS) LDA A,I IN CALLING SEQUENCE. STA SELU STORE FOR THE FOLLOWING CALL. JSB LUTRU GET TRUE SYSTEM LU. DEF *+2 DEF SELU LDB D1 PREPARE TO ISSUE "EQ01" ERROR. CPA D1 DID THEY SPECIFY THE SYSTEM CONSOLE? JMP EQT95 YEP--AND THAT'S A NO-NO. * SSA IF TRUE SYSTEM LU IS NEGATIVE, JMP EQT90 GO ISSUE "EQ00" ERROR. * LDB LUMAX GET MAX LU # IN SYSTEM ADB D1 PLUS ONE. CMB,INB TAKE 2'S COMPLE. ADB A ADD SPECIFIED LU #. SSB,RSS IF LU HAS NO ASSOCIATED DRT, JMP EQT90 GO ISSUE "EQ00" ERROR. * CCB GET THE ADA B DRT ENTRY ADA DRT POINTED TO BY LDA A,I SPECIFIED LU #. AND B77 ISOLATE THE EQT #. STA TEMP1 STORE THE EQT # THUS ARRIVED AT. SZA,RSS IS IT LE BITTE BUCKETTE? JMP EQT70 YEP, LOCK/UNLOCK IS A NOP. * LDB D1 PREPARE TO ISSUE "EQ01" ERROR. LDA DRT,I IF SPECIFIED LU MAPS INTO AND B77 THE SAME EQT.# THAT THE CPA TEMP1 SYSTEM CONSOLE MAPS INTO, JMP EQT95 AGAIN ISSUE "EQ01" ERROR. * CLO CLEAR OVERFLOW, TO BE USED AS A FLAG. LDB EQTRQ,I GET OPTION WORD LDA B,I SPECIFIED IN CALL. SLA IF LSB OF (A) IS NONZERO, STO SET LOCK_REQUEST FLAG. * XLA $ELTB GET $ELTB TABLE ADDR. XLB A,I GET HEADER WORD. RBL,CLE,ERB (E)=SIGN, (B)=TABLE_LENGTH. STB TEMP6 KLUDGE #_OF_EMPTIES TO BE NONZERO. ADA D1 GET ADDR OF 1ST EQT. # IN TABLE. STA TEMP3 STORE LOCALLY HERE STA TEMP9 AND HERE. STB TEMP4 ALSO STORE TABLE LENGTH. SEZ,RSS IF TABLE IS EMPTY, JMP EQT40 JUMP. * CMB,INB STORE COMPLE OF STB TEMP5 TABLE LENGTH. CLA INITIALIZE STA TEMP6 #_OF_EMPTIES IN TABLE. EQT30 LDA TEMP3 COMPARE AN EQT. # XLA A,I FROM TABLE SZA,RSS (IF BLANK ENTRY IS ENCOUNTERED, ISZ TEMP6 BUMP #_OF_EMPTIES.) CPA TEMP1 WITH THIS REQUEST'S EQT. #. JMP EQT65 MATCHES, GO SEE IF LOCKED TO HIM. * ISZ TEMP3 GET ADDR OF NEXT EQT. #. ISZ TEMP5 IF TABLE NOT ALL DONE, JMP EQT30 LOOP BACK. * EQT40 CCA MAKE (A) = -1. SOS IF UNLOCK REQUEST, JMP EQT70 RETURN WITH WASN'T_LOCKED RESPONSE. * LDA TEMP6 GET #_OF_EMPTIES IN TABLE. SZA IF AT LEAST ONE EMPTY ENTRY, JMP EQT45 TABLE NOT FULL, GO ADD AN ENTRY. * CCA FIRST SET UP RETURN CODE ( (A) = -1 ) LDB EQTRQ,I GET OPTION WORD LDB B,I SPECIFIED IN CALL. SSB IF REQUEST IS WITHOUT_WAIT, JMP EQT70 RETURN WITH (A) = -1. * XLA $ELTB GET TABLE ADDR AS SEMAPHORE. JMP EQT85 GO SUSPEND CALLER AND RETURN. * EQT45 LDA TEMP9 GET BACK ADDR OF 1ST EQT # IN STA TEMP3 TABLE, AND STORE IT. EQT50 XLA A,I GET AN EQT # FROM TABLE. SZA,RSS IF EMPTY ENTRY, JMP EQT55 USE THE SLOT TO ADD AN ENTRY. ISZ TEMP3 GET NEXT LDA TEMP3 EQT. # ADDR IN A. JMP EQT50 LOOP BACK. * EQT55 NOP ******************************************************** CLB,INB GET MAX LU'S ADB LUMAX IN SYSTEM PLUS 1. CMB,INB NEGATE IT STB TEMP2 AND STORE. CCB GET FWA OF DRT AND ADB DRT PRIME IT FOR THE NEXT BUMP. EQT56 INB GET TO NEXT DRT ENTRY FW. ISZ TEMP2 HAVE WE COMPLETED RSS A PASS THROUGH THE DRT? JMP EQT57 -YES. NO HARM IN ALLOWING EQT LOCK. * LDA B,I GET DRT ENTRY'S FW. AND B77 ISOLATE EQT#. CPA TEMP1 DOES DRT ENTRY POINT TO OUR EQT? RSS JMP EQT56 -NO. CONTINUE SEARCHING OTHER LU LOCKERS. * LDA B,I AGAIN GET DRT ENTRY'S FW. AND B3700 THIS TIME ISOLATE RN TABLE OFFSET * (AKA "LU LOCK FLAG"). SZA,RSS IT'S OUR EQT'S LU, BUT IS IT LOCKED? JMP EQT56 -NO. CONTINUE SEARCHING OTHER LU LOCKERS. * ALF,ALF ROTATE RN TABLE OFFSET RAL,RAL INTO LOW BITS. ADA D$RN ADD BASE ADDRESS. STA TEMPA SAVE ADDRESS IN CASE SUSPENSION NEEDED XLA A,I GET RN TABLE ENTRY. AND B377 ISOLATE LOCKER'S KEYWORD TABLE INDEX * (AKA ID NUMBER). ADA KEYWD AND USE THE ID NUMBER TO LDA A,I GET LU LOCKER'S ID SEGMENT ADDRESS. CPA XEQT DOES IT MATCH OUR CHAP'S? JMP EQT56 -YES. CONTINUE SEARCHING OTHER LU LOCKERS. * LDB EQTRQ,I GET OPTION WORD IN LDB B,I CALLER'S REQUEST. SSB IF CALL IS WITHOUT WAIT, GIVE HIM JMP EQT75 A "2" (SIBLING LU LOCKED TO ANOTHER"). * LDA TEMPA ELSE SUSPEND HIM ON JMP EQT85 LOCKED LU'S RN TABLE ENTRY. * ********************************************************* EQT57 XLB $ELTB FIRST INSURE XLA B,I THAT THE IOR B100K NOT_EMPTY BIT XSA B,I IS SET. LDA TEMP1 GET EQT. # SPECIFIED. LDB TEMP3 STORE IT IN XSA B,I ENTRY WORD 1. ADB TEMP4 GET ADDR OF ENTRY WORD 2. EQT60 LDA EQTRQ,I GET THE LDA A,I OPTION WORD. RAL,RAL PICK UP BIT 13 ELA (LOCK_ON_ABORT) IN (E). LDA XEQT COMBINE CALLER'S ID SEGMENT ADDR RAL,ERA WITH LOCK_ON_ABORT BIT. XSA B,I STORE IT IN 2ND WORD OF ENTRY. LDA TEMP1 STORE LOCKED EQT. # XSA XB,I IN CALLER'S (B). CLA RETURN WITH JMP EQT70 (A) = 0. * EQT65 LDB TEMP3 GET ID ADDR WORD ADB TEMP4 (I. E., WORD2) XLA B,I OF THIS EQT.'S ENTRY. ELA,CLE,ERA GET RID OF THE LOCK_ON_ABORT BIT. CPA XEQT COMPARE WITH CALLER'S ID. RSS JMP EQT80 JUMP IF NOT LOCKED TO CALLER. * SOC IF THIS IS A LOCK REQUEST, JMP EQT60 RELOCK THE EQT. WITH (MAYBE) CHANGED OPTION. * CCA GET ADDR WHERE LOCKER'S ADA TEMP1 I/O REQUESTS MAY STILL BE MPY D15 PENDING (VIZ., EQT ENTRY'S ADA EQTA 1ST WORD). XLA A,I PICK UP REQUEST LIST POINTER. SZA ANY REQUESTS LEFT? JMP EQT75 -YES, CAN'T UNLOCK YET. * JMP EQCL -NO, SO GO UNLOCK THE EQT. * BACK CLA RETURN WITH OK RESPONSE. EQT70 XSA XA,I STICK RETURN CODE IN CALLER'S (A). LDA RQRTN STICK RETURN ADDR XSA XSUSP,I IN SUSP ADDR WORD JMP $XEQ AND RETURN VIA THE DISPATCHER. * EQT75 LDA D2 RETURN WITH 2 ("CAN'T UNLOCK YET" OR JMP EQT70 "SIBLING LU(S) LOCKED TO ANOTHER") * EQT80 LDA D1 RETURN CODE = 1. SOS IF UNLOCK REQUEST, JMP EQT70 RETURN WITH "LOCKED TO ANOTHER" RESPONSE. * LDA B,I GET SPECIFIED EQT.'S ID # SLOT. SZA,RSS IF LOCKED WITHOUT OWNER, JMP EQT60 GO LOCK TO CALLER (FILL ENTRY 2ND WORD). * LDA D1 FIRST SET UP RETURN CODE ( (A) = 1 ). LDB EQTRQ,I GET OPTION WORD LDB B,I SPECIFIED IN CALL. SSB IF REQUEST IS WITHOUT_WAIT, JMP EQT70 RETURN WITH (A) = 1. * LDA TEMP3 GET ENTRY ADDR AS SEMAPHORE. EQT85 XSA XTEMP,I STORE IT IN SUSP. FLAG WORD. JSB $LIST GO PUT CALLER IN OCT 503 GENERAL WAIT LIST JMP $XEQ AND RETURN. * EQT90 CLB MAKE (B) = 0 FOR "EQ00" ERROR. EQT95 LDA ASEQ ISSUE "EQXX" ERROR JMP $ERAB AND EXIT. SKP * * * CONSTANTS, EQUATES, TEMPORARIES, AND SUCH. * ASEQ ASC 1,EQ D1 DEC 1 D2 DEC 2 D15 DEC 15 B77 OCT 77 B377 OCT 377 B3700 OCT 3700 B100K OCT 100000 EQTA EQU 1650B DRT EQU 1652B LUMAX EQU 1653B KEYWD EQU 1657B RQRTN EQU 1677B XEQT EQU 1717B XTEMP EQU 1721B XSUSP EQU 1730B XA EQU 1731B XB EQU 1732B TEMP1 NOP EQT. # TO BE (UN)LOCKED TEMP2 NOP COMPLE OF #-OF-DRT'S-YET-TO-BE-TRAVERSED TEMP3 NOP TABLE ADDR OF NEXT EQT 2 B COMPARED TEMP4 NOP TABLE LENGTH TEMP5 NOP COMPLE OF #-OF-COMPARES-YET-2-B-DONE TEMP6 NOP # OF EMPTIES IN TABLE TEMP9 NOP TABLE ADDR OF 1ST EQT # TEMPA NOP LOCKED LU'S RN TABLE ENTRY ADDR (SEMAPHORE) SELU NOP SESSION LU (USED FOR "LUTRU" CALL) D$RN DEF $RNTB+0 FORCE A DIERCT ADDRESS TO RN TABLE SKP HED ** EQUIPMENT LOCK CLEARING ROUTINE ** * * EQCL CLB LDA TEMP3 FIRST PRESERVE ADDR OF STA TEMP7 ENTRY FOR SEMAPHORING. XSB A,I CLEAR ENTRY'S 1ST WORD. ADA TEMP4 COMPUTE ADDR OF ENTRY'S 2ND WORD. XSB A,I CLEAR 2ND WORD. ADA TEMP4 COMPUTE ADDR OF ENTRY'S 3RD WORD. XLB A,I GET THE 3RD WORD (LIST POINTER), STB TEMP8 AND PRESERVE IT. CLB THEN CLEAR XSB A,I THE 3RD WORD ALSO. * EQEMP ISZ TEMP6 BUMP EMPTIES COUNT FOR 1 CREATED/FOUND. EQNOT ISZ TEMP3 GET ADDR OF NEXT EQT. # IN TABLE. ISZ TEMP5 BUMP #_OF_COMPARES_DONE FOR 1 JUST DONE. RSS IF ALL ENTRIES HAVE BEEN TRAVERSED, JMP EQUNE SKIP COUNTING EMPTIES. * LDA TEMP3 CHECK NEXT ENTRY XLA A,I IN TABLE. SZA,RSS IF IT IS BLANK, JMP EQEMP BUMP EMPTIES COUNT. IN ANY CASE, JMP EQNOT GET TO NEXT ENTRY. * EQUNE LDA TEMP6 GET TOTAL #_OF_EMPTIES IN TABLE. CPA TEMP4 COMPARE WITH TABLE LENGTH. JMP EQCNE TABLE EMPTY, GO CLEAR NOT_EMPTY BIT. * JMP EQCNT ELSE CONTINUE. * EQCNE XLB $ELTB GET THE HEADER XLA B,I WORD OF TABLE. ALR,RAR CLEAR NOT_EMPTY BIT, XSA B,I AND RESTORE. * EQCNT CCA GET ADDR WHERE TO REHANG ANY ADA TEMP1 HUNG $XSIO CALLS FOR SPECIFIED MPY D15 EQUIPMENT NUMBER (VIZ., ITS EQT ADA EQTA ENTRY'S WORD ZERO). LDB TEMP8 GET POINTER TO $XSIO LINKED LIST. SZB,RSS IF THERE IS NO $XSIO PENDING, JMP EQSCD SKIP DRIVER INITIATION. * XSB A,I REHANG $XSIO POINTER ON THE EQT. * DLD UP SET UP THE "UP, " PART DST IBUFA OF THE "UP, XXX" COMMAND. * CCE SET UP TO CONVERT LDA TEMP1 EQT.# INTO ASCII. JSB $CVT3 GO DO IT. * ADA D1 GET TO ADDR OF ASCII NUMBER. DLD A,I PICK UP THE ASCII REPRESENTATION, DST IBUFA+2 AND APPEND IT TO THE "UP, ". *************************************************************************** LDA ADDR SET CALLING ADDR IN SUSP. WORD XSA XSUSP,I SINCE WE WILL BE "SUSPENDED" **************************************($MESS IS AN OPEN ENDED FELLA).****** CALL JSB MESSS NOW SEND THE "UP,XX" COMMAND DEF *+3 SO THAT I/O (I.E., $XSIO) DEF IBUFA MAY BEGIN DEF ICOUN ON THIS EQT. * JSB $LIBR GO PRIVILEGED AGAIN, SINCE THE MESSS NOP CALL MESSED UP OUR PRIVILEGED STATUS. * CLA CLEAR THE PRIVILEGED COUNTER, STA $PVCN SINCE WE WON'T RETURN VIA $LIBX. * EQSCD LDA TEMP7 GET ENTRY ADDR. JSB $SCD3 SCHEDULE WAITERS_FOR_THIS_EQT. XLA $ELTB GET TABLE HEADER ADDR. JSB $SCD3 SCHEDULE WAITERS_FOR_PLACE_TO_DOCK_A_LOCK. JMP BACK AND RETURN TO MOMMY. * * * * * MORE CONSTANTS, EQUATES, TEMPORARIES, AND SUCH. * TEMP7 NOP TABLE ADDR OF EQT.# TO BE UNLOCKED TEMP8 NOP $XSIO LINKED LIST POINTER ADDR DEF CALL UP ASC 4,UP, ICOUN DEC 8 IBUFA ASC 11, END