.TITLE PBDRV ; ; LOADABLE DRIVER FOR LK11 PUSHBUTTON BOX ; ; ASSEMBLING PROCEDURES: ; ; PBDRV,PBDRV/-SP=[1,1]EXEMC/ML,[11,10]RSXMC/PA:1,[7,241]PBDRV ; ; BUILDING PROCEDURES: ; ; PBDRV/-HD/-MM,PBDRV/-SP,PBDRV=PBDRV,PBTAB,[1,54]RSX11M.STB/SS ; [1,1]EXELIB/LB ; / ; STACK=0 ; PAR=GEN:120000:4000 ; // ; .MCALL SCBDF$ SCBDF$ ;DEFINE SCB OFFSETS ; LD$PB=1 ;USED BY INTSV$ ; CNTBL: .BLKW 1 ;USED BY INTSV$ FOR UCB ADDRESS ; PBCSR=160060 ;CONTROL STATUS REGISTER OF LK11 PBIN=PBCSR+2 ;INPUT REGISTER OF LK11 PBLAMP=PBCSR+4 ;LAMP REGISTER OF LK11 ; PBSTAT: .WORD 0 ;LOCAL STATUS WORD OF 16 PUSHBUTTONS ;BIT 0-15 -> PB0-PB15 (0=OFF, 1=ON) PBMASK: .WORD 1,2,4,10,20,40,100,200,400,1000,2000,4000,10000,20000,40000 .WORD 100000 ;MASK TABEL UCBTAB: .BLKW 16. ;ALL UCB ADDRESSES, FILLED AT LOAD TIME ; ; ;****************************************************************************** ; ; DRIVER DISPATCH TABEL ; ;****************************************************************************** ; $PBTBL::.WORD PBINI ;DEVICE INITIATOR ENTRY POINT .WORD PBCAN ;CANCEL I/O ENTRY POINT .WORD PBOUT ;TIME OUT ENTRY POINT .WORD PBPWF ;POWER FAIL ENTRY POINT ; ;****************************************************************************** ; ; THIS ROUTINE IS ENTERED FROM THE QIO DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION. ; IF THE SPECIFIED UNIT IS NOT BUSY, THEN AN ATTEMPT IS MADE TO DEQUEUE ; THE NEXT I/O PACKET. ELSE A RETURN TO THE CALLER IS EXECUTED. ; AFTER A SUCCESSFUL DEQUEUE ATTEMPT, THE NEXT I/O OPERATION IS INITIATED. ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O PACKET ; R2=UNIT NUMBER OF THE REQUEST UCB ; R3=CONTROLLER INDEX ; R4=ADDRESS OF SCB ; R5=ADDRESS OF UCB ; ; I/O REQUEST PACKET FORMAT: ; ; WORD 0: I/O QUEUE THREAD WORD ; WORD 1: REQUEST PRIORITY, EVENT FLAG NUMBER ; WORD 2: ADDRESS OF THE TCB OF THE REQUESTOR ; WORD 3: POINTER TO 2ND LUN WORD IN REQUESTOR'S TASK HEADER ; WORD 4: CONTENTS OF 1ST LUN WORD IN REQ. TASK HEADER (UCB) ; WORD 5: I/O FUNCTION CODE ; WORD 6: VIRTUAL ADDRESS OF I/O STATUS BLOCK ; WORD 7: RELOCATION BIAS OF I/O STATUS BLOCK ; WORD 10: I/O STATUS BLOCK ADDRESS ; WORD 11: VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; WORD 12: RELOCATION BIAS OF I/O BUFFER ; WORD 13: BUFFER ADDRESS OF I/O TRANSFER ; WORD 14: NUMBER OF BYTESM TO BE TRANSFERED ; WORD 15: NOT USED ; WORD 16: NOT USED ; WORD 17: NOT USED ; WORD 20: NOT USED ; ;****************************************************************************** ; ; PBINI: CALL $GTPKT ;GET AN I/O PACKET BCS PBOUT ;IF CS CONTROLLER BUSY OR NO REQUEST ASL R2 ;R2 = UNIT NUMBER CMPB I.FCN+1(R1),#IO.RLB/256. ;IS FUNCTION CODE IO.RLB?? BNE IOWLB ;IF NE NO CMPB I.FCN(R1),#TF.RAL ;WAS IT IO.RAL?? BNE NORAL ;IF NE NO MOV PBSTAT,-(SP) ;GET LAMP STATUS BR PUT ;GO TELL REQUESTOR NORAL: CLR -(SP) ;ASSUME LAMP=.FALSE. BIT PBMASK(R2),PBSTAT ;IF BIT = 0, LAMP WAS OFF BEQ PUT ;SO JUMP MOV #-1,(SP) ;ELSE SET VALUE = .TRUE. PUT: CALL $PTWRD ;TRANSFER VALUE TO USER BUFFER MOV #2,R1 ;SET UP BYTE COUNT BR ISSUC ;BRANCH TO SUCCESSFUL COMPLETION ; IOWLB: CMPB I.FCN+1(R1),#IO.WLB/256. ;WAS FUNCTION CODE IO.WLB?? BNE IOCON ;IF NE NO CALL $GTWRD ;GET FIRST WORD OF USER BUFFER MOV (SP)+,R0 ;IS RETURNED ON THE STACK BEQ DARK ;IF 0, CLEAR LAMP BIS PBMASK(R2),PBSTAT ;IF NE 0 SET STATUS BR SETREG ;AND BRANCH TO ACTUAL REGISTER SETTING DARK: BIC PBMASK(R2),PBSTAT ;CLEAR STATUS BIT SETREG: MOV PBSTAT,PBLAMP ;SET ACTUAL STATUS INTO LAMP REGISTER CLR R1 ;# BYTES TRANSFERED BR ISSUC ;BRANCH IOCON: CMPB I.FCN+1(R1),#IO.CON/256. ;WAS FUNCTION CODE IO.CON?? BNE BADER ;IF NE ERROR BIS #1,U.CW2(R5) ;SET UNIT WAITFOR STATE BR PBINI ;IF SO DON'T COMPLETE THIS I/O ;BUT WAIT FOR INTERRUPT OR IO.KIL ;TO DO THAT ISSUC: MOV #IS.SUC&377,R0 ;SET SUCCESS CODE COMEX: CALL $IODON ;AND COMPLETE I/O BR PBINI ;TRY TO DEQUEUE NEXT PACKET ; ; BADER: MOV #IE.BAD&377,R0 ;SET ERROR CODE CLR R1 ;# BYTES TRANSFERED BR COMEX ;BRANCH TO COMMON EXIT ; ; ;****************************************************************************** ; ; THIS ROUTINE IS ENTERED AT LOAD TIME (BECAUSE UC.PWF WAS SET IN UCB), ; AND AT POWER FAIL. ; THE STATUS IS RESTORED INTO THE LAMP REGISTER AND THE INTERRUPTS ARE ; ENABLED. ; THE INPUT REGISTER IS CLEARED, WHICH ALSE CLEARS THE UNIT BITS IN THE ; STATUS REGISTER (BIT 1-4). ; ALL THE UCB ADDRESSES ARE COPIED INTO A BUFFER FOR EASY USE IN INTERRUPT ; CODING. ; ; ARGUMENTS AT THIS POINT: ; ; R3=CONTROLLER INDEX ; R4=ADDRESS OF SCB ; R5=ADDRESS OF UCB ; ;****************************************************************************** ; ; PBPWF: MOV PBSTAT,@#PBLAMP ;RESTORE PB STATUS BIS #40000,@#PBCSR ;ENABLE INTERRUPTS CLR PBIN ;CLEAR INPUT REGISTER AND BIT 1-4 IN CSR MOVB U.UNIT(R5),R3 BIC #177400,R3 ASL R3 MOV R5,UCBTAB(R3) PBOUT: RETURN ;RETURN TO CALLER ; ; ;****************************************************************************** ; ; THIS ROUTINE IS ENTERED WHEN A BUTTON WAS PUSHED. ; THE STATUS OF THE PARTICULAR BUTTON IS CHANGED AND SO IS THE LAMP. ; IF THIS UNIT WAS BUSY, THE I/O COMPLETION IS INITIATED, WHICH CAUSES ; THE EVENT FLAG TO BE SET AND THE AST ROUTINE TO BE CALLED. ; ; OUTPUTS OF INTSV$: ; ; R4=CONTROLLER INDEX ; R5=UCB ADDRESS OF CONTROLLER ; ;****************************************************************************** ; $PBINT:: INTSV$ PB,PR5,1 ;SAVE REGISTERS AND SET PRIORITY BIT PBIN,PBSTAT ;WAS LAMP ON? BNE 1$ ;IF NE YES, SO CLEAR IT BIS PBIN,PBSTAT ;SET STATUS BIT BR 2$ ;AND BRANCH 1$: BIC PBIN,PBSTAT ;CLEAR STATUS BIT 2$: MOV PBSTAT,PBLAMP ;SET LAMP REGISTER MOV PBCSR,R5 ;SAVE CSR CLR PBIN ;AND CLEAR INPUT REGISTER ASR R5 ;RETRIEVE UNIT NUMBER BIC #177760,R5 ASL R5 ;R5=UNIT NUMBER * 2 MOV UCBTAB(R5),R5 ;UCB ADDRESS OF THIS UNIT MOV U.SCB(R5),R4 ;GET SCB ADDRESS BIT #1,U.CW2(R5) ;WAS THIS ONE WAITING?? BEQ 10$ ;IF EQ NO BIC #1,U.CW2(R5) ;CLEAR WAITFOR STATE CALL $FORK ;CREATE SYSTEM PROCESS MOV #IS.SUC&377,R0 ;SET UP SUCCESS CODE CLR R1 ;SET UP BYTE COUNT CALL $IODON ;COMPLETE I/O BR PBINI ;TRY TO DEQUEUE NEXT PACKET 10$: JMP $INTXT ;EXIT FROM INTERRUPT ; ; ;****************************************************************************** ; ; THIS ROUTINE IS ENTERED IF IO.KIL WAS SPECIFIED. ; SEE IF THE TASK WHICH ISSUED THE IO.KIL REQUEST IS THE SAME AS THE ONE ; OF THE CURRENT I/O PACKET. IF NOT, DON'T DO ANYTHING, ELSE COMPLETE I/O ; WITH ERROR CODE. ; ; ARGUMENTS AT THIS POINT: ; ; R5=UCB ADDRESS ; R4=SCB ADDRESS ; R3=CONTROLLER INDEX ; R1=ADDRESS OF TCB OF CURRENT TASK ; R0=ADDRESS OF ACTIVE I/O PACKET ; ;****************************************************************************** ; ; PBCAN: CMP R1,I.TCB(R0) ;WAS THIS TASK THE REQUESTOR? BNE 1$ ;IF NE NO MOV #IE.ABO&377,R0 ;SET UP ERROR CODE CLR R1 ;SET UP BYTE COUNT CALL $IODON ;COMPLETE I/O JMP PBINI ;TRY TO GET NEXT PACKET 1$: RETURN ;RETURN TO CALLER ; ; ; .END