.TITLE CMDRV .IDENT /V1/ .IDENT /V2/ .SBTTL CAMAC DRIVER FOR RSX11M ; ;MODIFICATIONS ; ;D.B. Curtis 8/25/76 added BD command status word ;to the second IOSW. Also killed the assembly error that occured. ; ;&.AP ;&.SKIP 5 ;+ ; ; This is a CAMAC driver for RSX11M. It has the following functions: ;.skip 2 ;.literal ; FUNCTION MODIFIER ; ; 0=IO.KIL ; 1=WRITE ; 0=PROGRAMED DATA WRITE ; 1=ENTER LAM RECOGNITION CODE ; THIS IS NOT YET IMPLEMETED ; 2=NON DATA TRANSFER ; 2=READ ; 0=PROGRAMMED DATA READ ; 1=BRANCH DRIVER REGISTER READ ; 3=ATTACH ; 4=DETATCH ; 6=DMA TRANSFER ; 7-31=ILLEGAL ; ;.END LITERAL ;.SKIP 2 ; ; The driver is written for a EGG BD-011 branch driver ;with the extended word count modification. ;It also supports the Jorway branch driver including extended ;memory support. This is selected by defining JORW. ; DMA transfers must be sent to unit 1, non DMA trnasfers must ;be sent to unit 0. If an attempt is made to access a non existant ;module, a select error message will be displayed on the ;terminal. If a device not ready is ever printed out, the ;BD-011 is sick and the computing hardware ;people should be contacted. The only successfull error return is IS.SUC. ; The error returns occure in the first byte of the IOSW the second ;byte is always zero and the third and forth bytes (the second word) ;contain the command status word of the ;branch driver. ;The error returns are ;.ls ;.le;IE.VER which is unrecoverable error and ;occures if there is a BD-011 timeout. (ie the crate ;is offline or there isn't any moudule in the selected station) ;.le;IE.BAD which is bad paramiter and occures if an attempt was ;made to do a DMA to unit 0 or a non DMA to unit 1. ;.le;IE.ONP which is illegal subfunction and occures if the ;subfunctions for function 1 and 2 are incorrect. ;.els ; The rest of this describes the flow of the logic of the driver. ;- ; ;MACRO LIBRARY CALLS ; .MCALL ABODF$,DEVDF$,HWDDF$,PKTDF$,TCBDF$ ABODF$ DEVDF$ HWDDF$ PKTDF$ TCBDF$ ;+ ; The CAMAC function codes have the following nmunonics: ;.ls ; IO.CPW=400 ;.LE;IO.CPW=CAMAC Programmed data Write IO.ELM=401 ;.LE;IO.ELM=Enable LAM recognition (this is currently disalbed) IO.NDT=402 ;.LE;IO.NDT=Non Data Transfer IO.CPR=1000 ;.LE;IO.CPR=Camac Programmed Read IO.CRR=1001 ;.LE;IO.CRR=Camac Register Read IO.CDM=3000 ;.LE;IO.CDM=Camac DMA transfer ; ;.els ; Define the priority of the BD-011 by equating ;PL to the correct priority (i.e. ;PL=PR4). ;- PL=PR4 ; ;& FOR A JORWAY BRANCH DRIVER DEFINE JORW JORW=0 ; ;LOCAL DATA ;+ ; Local data bits and offsets are, ; ;.LS SZADJ=0 ;.LE;SZADJ WHICH ADJUSTS THE SIZE OF THE ;OF THE MODULE TO BE THE SAME REGARDLESS OF THE ASSEMBLY ;PARAMITERS USED. DMA=4 ;.LE;DMA, Which showes that a DMA operation was the last ;operation that completed. LAMEN=2 ;.LE;LAMEN, Which shows that LAMs should be enabled after ;a DMA operation. MD24=40000 ;.LE;MD24, Which is the 24 bit mode of the FNA register. MADR=4 ;.LE;MADR, Which is the offset for the memory address ;register. DATA=2 ;.LE;DATA, Which is the offset for the data register. XTEND=12 ;.LE;XTEND, Which is the offset for the extended ;word count register. FNA=10 ;.LE;FNA, Which is the offset for the function, station, ;and address register. CRAT=6 ;.LE;CRAT, Which is the offset for the crate select. ;.ELS ;- ; CNTBL: .BLKW 1 ;THIS IS USED TO STORE UCB ADDRESS FOR INTERUPT ROUTINE ; ;DRIVER DISPATCH TABLE ; $CMTBL:: .WORD CMINI .WORD CMCAN .WORD CMOUT .WORD CMPWF ; ;+ ; The power fail routine CMPWF is entered at system startup and after ;recovering from a power outage. ;On entry R3-R5 containe information. ; ; R3=CONTROLER INDEX ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ;- ;&The routine will CMPWF: MOV S.CSR(R4),R3 ;GET THE ADDRESS OF THE BD-011 CLR (R3)+ ;&clear CLR (R3)+ ;&all of CLR (R3)+ ;&the CLR (R3)+ ;®isters and CLR (R3)+ ;&clear the CLR @S.CSR(R4) ;&control register again to clean up any junk MOV #1,@S.CSR(R4) ;&and then cause a branch initalize. ;+ ; The only time that a BZ can be done is due to this routine! ;if a crate must be initalized the crate controller function must be used. ;- 1$: TST @S.CSR(R4) ;WAIT FOR THE BZ TO FINISH BPL 1$ RETURN ;AND RETURN ; ;+ ; CMCAN is the routine that is called when an IO.KIL function ;is executed or when the task is aborted. ;on entry the registers contain: ; ; R0=ADDRESS OF CURRENT I/O PACKET ; R1=ADDRESS OF TCB OF CURRENT TASK ; R3=CONTROLLER INDEX ; R4=ADDRESS OF SCB ; R5=ADDRESS OF UCB ;.skip 1 ;CMCAN normally just returns without altering any thing. ;- ; CMCAN: MOV #.CM1+34+2,R0 ; ; MOV #.CM0+32+2,R3 ; 1$: TST (R0) ; BEQ 3$ ; ; ADD #4,R3 ; ; CMP R1,I.TCB(R0) ; ; BNE 1$ ; SUB #2,R0 SUB #4,R3 ; MOV R0,-(SP) ; MOV R3,-(SP) MOV #40,R1 ; CALL $DEACB ; MOV (SP),R3 ; MOV 2(SP),R0 ; 2$: MOV 4(R3),(R3)+ ; MOV 4(R3),(R3)+ ; MOV 2(R0),(R0)+ ; BNE 2$ MOV (SP)+,R3 ; MOV (SP)+,R0 BR 1$ ; ; 3$: RETURN ; ;+ ; CMOUT is entered when a timeout occures. Due to the internal timeouts ;of the BD-011, There is little need for this routine. However during ;debugging of the routine it has come in usefull at times. ;This is because if a gross error is made in the I/O packet and ;the wrong RSX function is given to the CAMAC function, ;this feature will time you out eventually ;and let the task be aborted. ; The registers on entry are: ; ; R0=STATUS CODE ; R3=CONTROLER INDEX ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ;operation is as follows: ;.ls CMOUT: CLRB PS ;.le;lower processor priority to 0 MOV #T.NDNR,R0 ;.le;cause the device not ready ;message to be printed BR DDD ;.els ; DD is jumped to if there is a time out or abort ;error. It causes a device select error message to be printed out on ;the consule. Both CMOUT and DD entrys cause a IE.VER (irrecoverable ;error) status bit to be put in the I/O status block. ; DD: BIC #400,@S.CSR(R4) ;The DD entry also always resets the ABORT bit MOV #T.NDSE,R0 ; DDD: CALL $DVMSG ; MOV #IE.VER&377,R0 ; JMP DON ; ; CMINI is entered from the QIO directive when an I/O request is queued ;and at the end of a prevous I/O operation to propagate the ;execution of the driver. If the controller is not busy, an attempt ;is made to dequeue the next I/O request. If the controller is ;busy, a return to the caller is made. If the dequeue attempt was ;successfull, then the I/O operation is initiated and a return is done. ;On entry, R5= address of the UCB of the proper controller. ; The device dependant paramiters for the CAMAC functions ;are: ;.skip 1 ;.literal ; FUNCTION/SUBFUNCTION PARAMITERS ; ; PDW(1/0) ; NDT(1/2) <0, 0, 0, CRATE SELECT, FNA> ; PDR(2/0) ; BDRR(2/1) ; DMA(6/0) ;.END LITERAL ;.SKIP 1 ;- ; CMINI: CALL $GTPKT ;ATTEMPT TO DEQUEUE A PACKET BCC 1$ ;IF CARRY CLEAR DEQUEUED OK RETURN ;ELSE RETURN ;+ ;On successfull return from $GTPKT, the registers are: ; ; R1=ADDRESS OF I/O PACKET ; R2=PHYSICAL UNIT NUMBER ; R3=CONTROLLER INDEX ; R4=ADDRESS OF SCB ; R5=ADDRESS OF UCB ;- ;& The function dispatching is then done by ; 1$: MOV R5,CNTBL(R3) ;&saving the UCB address for the interupt ;&routines CLR U.CW2(R5) ;&and clearing the device paramiter word MOVB I.FCN+1(R1),R3 ;&Next, the function is put in R3 ASL R3 CLC ;&and the carry bit cleared to assume a ;&non DMA transfer. JMP @DISPAT(R3) DISPAT: .WORD RET ;&If the function is 0 then an immediate ;&return is done. Please note the dispatch to RET ;&is never done as the function should be ;&handled by the QIO routines. .WORD WRI ;&If the function is 1 then a write of some type ;&is assumed. .WORD RED ;&If the function is 2, a read .WORD RET ;&If 3, 4, or 5 the .WORD RET ;&function is immediatly .WORD RET ;&returned. .WORD DMAA ;&If the function is 6 then a DMA ;&is assumed. ; ;& WRI is where you go if the function is one. ; WRI: MOVB I.FCN(R1),R3 ;&The subfuncton is put in R3, CMP R3,#3 ;&and it is checked for blo 1$ ;&legality. BR DON2 ;&If not legal, DON2 will indicat it. 1$: ASL R3 ;&If legal, a word index is generated JMP @DPT1(R3) ;&and the proper function is dispatched. DPT1: .WORD 2$,LAMR,3$ ; 2$: ;& For a programed data write the JSR PC,SETUP ;&BD-011 registers are setup and then MOV I.PRM(R1),DATA(R2) ;&the low 16 bits are written into the ;&data register. Next, the FNA word in the BIT #MD24,I.PRM+10(R1) ;&QIO packet is checked for 24 bit mode BEQ A ;&and if so will write the upper 8 bits. MOV I.PRM+2(R1),DATA(R2) ;&In either case, BR A ;&a branch to A is done. ; ;& For a non data transfer ; 3$: JSR PC,SETUP ;&The registers are setup BR A ;&and a branch to A is done. ; ;& For a READ function ; RED: MOVB I.FCN(R1),R3 ;&the subfunction is checked CMP R3,#2 ;&for legality and if not BLO TICTAC ;&ok IE.ONP is sent to the $IODON DON2: MOV #IE.ONP&377,R0 ;&routine. Otherwise, the subfunction JMP DON TICTAC: ASL R3 ;&is made into a word index JMP @DPT2(R3) ;&and dispatched. DPT2: .WORD 5$,6$ ; ; 5$: JSR PC,SETUP ;& For a programmed data transfer read the 1$: TST (R2) ;&operation is started by a call to SETUP ;&and then wait for the task completion BPL 1$ ;&ready bit to come up. MOV DATA(R2),-(SP) ;&Then the low 16 bits are pushed on CALL $PTWRD ;&the stack and placed in the buffer by a call ;&to $PTWRD. BIT #MD24,I.PRM+10(R1) ;&The FNA word is then checked for BNE 2$ ;&24 bit mode and if not set will CLR -(SP) ;&clear the next location in the users buffer. BR 3$ ;&otherwise, the upper 8 bits are 2$: MOV DATA(R2),-(SP) ;&placed there. 3$: CALL $PTWRD ; BR A ;&Then branch to A of course. ; 6$: MOV R4,-(SP) ;& To read the branch driver registers, MOV S.CSR(R4),R4 ;&get the address of the controller MOV (R4),-(SP) ;&and read each register into the users buffer CALL $PTWRD ;&with the exception of the data buffer ADD #4,R4 ;&whose position in the data buffer will CLR -(SP) ;&be zeroed. CALL $PTWRD MOV (R4)+,-(SP) ; CALL $PTWRD MOV (R4)+,-(SP) ; CALL $PTWRD MOV (R4)+,-(SP) CALL $PTWRD MOV (R4),-(SP) CALL $PTWRD MOV (SP)+,R4 ; BR DON1 ;&As no CAMAC operaton was done a return ;&to DON1 is sufficent to finish this ;&operation. ; ; DMAA: ; ;& The DMA function is specified by calling SETUP with the carry bit ;&set. This will cause the processor priority to be raised to level ;&PL for a short time. ; SEC ;HERE SET THE CARRY MOVB S.ITM(R4),S.CTM(R4) ;&The timeout is also set for this function ;&even if it probably won't be used. JSR PC,SETUP ;NOW CALL SETUP TO FIX THE REGISTERS ; ; ;& Code starting at A is executed after every function/subfunction except ;&the LAM recognition function. ; A: TST @S.CSR(R4) ;&First the status/control register is checked ;&and if busy a branch to B is done. BPL B ;&otherwise, BIT #DMA,U.CW2(R5) ;&the DMA mode bit is checked and BEQ DON1 ;&if off branch to DON1 to finish the operation. ; ;&If set, you are at processor priority PL and have been ;&since the call to SETUP in DMAA. ; BIC #44,@S.CSR(R4) ;&Next, the completion sequencer and ;&interupt enable are cleared as they will ;&be set and an interupt is not nessasary. ; BIC #PR7,PS ;&Now the priority is set back to zero BIC #DMA,U.CW2(R5) ;&and the DMA mode bit cleared. CLRB S.CTM(R4) ;&Also, the timeout is cleared as the operation ;&is complete BIT #LAMEN,U.CW2(R5) ;& The LAM enable mode bit is checked BEQ DON1 ;&and if not set branch to DON1. MOV #10,@S.CSR(R4) ;&Oterwise, the LAM interupt is enabled. ; ;& At DON1, the ; DON1: BIT #10400,@S.CSR(R4) ;&control/status register is checked for ; BEQ 1$ JMP DD ;&abort and timeout and if so jump to DD. 1$: MOV #IS.SUC&377,R0 ;&Otherwise, successfull completion is ;&assumed, also the CAMAC control ;&status word is put into the DON: MOV @S.CSR(R4),R1 ;&second word of the IOSB and a call to ;&$IODON is executed ; CALL $IODON JMP CMINI ;&and then attempt to dequeue another IO packet. ; ; IF THE OPERATION IS NOT COMPLETE WHEN CHECKED IN A:, THEN ; THIS CODE IS EXECUTED TO LOWER THE PROCESSOR PRIORITY AND ALLOW ; THE COMPLETION INTERUPT TO OCCURE. ; B: BIC #PR7,PS ; RET: RETURN ;; ;& $CMIN1 is the task completion interupt entry point. ;&it is entered when an operation was not done when the program jumped to ;&A. ; $CMIN1:: CALL $INTSV,PL ;& First call $INTSV to save the the interupt MOV CNTBL,R5 ;&stuff and then put the UCB address into R5 MOV U.SCB(R5),R4 ;&and put the SCB address in R4. CLRB S.CTM(R4) ;&Clear the timeout MOV S.CSR(R4),R4 ;&and replace R4 with the address of the BD-011 BIC #4,(R4) ;&and clear the task completion enable BIC #DMA,U.CW2(R5) ;&bit and the DMA mode bit. CALL $FORK ;&Now a $FORK is done to produce a system ;&process. BIT #LAMEN,U.CW2(R5) ;& Once the system gets around to it the BEQ 2$ ;&enable LAM bit is checked and if set BIS #10,(R4) ;&will enable LAM interupts. At this point ;&an interupt may occure but since it ;&is after the fork I dont need to have two ;&SCB's. 2$: MOV U.SCB(R5),R4 ;&Now get the UCB address and put it ;&into R4 again and jump JMP DON1 ;&to DON1. ; ; ; ; ;I/O PACKETS FOR LAM RECOGNITION REQUESTS ; ; 13=LOW MASK BITS ; 14=HIGH MASK BITS ; 15=CRATE CODE FOR OPERATION ON LAM ; 16=FNA FOR OPERATION ON LAM ; ; ;THIS FUNCTION SETS UP A LIST OF PERMISSABLE LAMS TO BE ;RECOGNIZED BY THE SYSTEM THE CRATE CODE AND FNA SHOULD BE SETUP ;WITH THE PROPER FUNCTION TO CLEAR THE LAM WHEN IT OCCURES ;THE MASK BITS ARE ANDED WITH THE GRADED L WORDS TO DECIDE ;IF THE SYSTEM RECOGNIZES THE LAM. MULTIPLE TASKS CAN BE INFORMED ;FROM A SINGLE LAM ; ;; LAMR: .IF DF,LAMSV TST I.AST(R1) ; ;********************* ;********************** ;THIS MUST BE CHANGED!!!!! ; ;********************* BEQ CRSH MOV #LAMEN,U.CW2(R5) ; MOV #10,@S.CSR(R4) ; MOV #40,R0 ; CALL $ALOCB ; MOV R0,-(SP) ; MOV R1,-(SP) ; MOV #20,R3 ; 1$: MOV (R1)+,(R0)+ SOB R3,1$ MOV (SP)+,R1 ; CLR I.AST(R1) ; ; ; ; ; ; ; MOV I.PRM+6(R1),@.CM0+32 ; ADD #2,.CM0+32 ; MOV I.PRM+10(R1),@.CM0+32 ; MOV (SP)+,R3 ; MOV R3,@.CM1+34 ; ADD #2,.CM1+34 ; CLR I.LGTH(R3) ; ; ; ; ; ; ; ; ; ; ; ; JMP DON1 ; CRSH: IOT .IFF JMP DON1 .ENDC ; ;; ;CMIN2 IS THE ROUTINE ENTERED WHEN A BRANCH LAM INTERRUPT ;IS SEEN. THE PROGRAM DOES A GRADED LAM ON THE REQUESTING BD-011 ;SCANS THE MASK WORDS LOADED INTO MEMORY BY LAMR FOR A MATCH. ;IF NO MATCH IS FOUND AN ERROR INDICATION IS SENT ;IF A MATCH IS FOUND THE CRATE AND FNA CODES ARE EXECUTED ;OF THE MATCHED LAM PSEUDO I/O PACKET ;THIS IS ONLY DONE ONCE REGARDLESS OF THE NUMBER OF TASKS ;REQUESTING NOTIFICATION OF LAM. ; ; ; ;PSUDO I/O PACKETS ARE SENT TO $IOFIN THEY WILL NOT BE DEALLOCATED ;FROM DYNAMIC MEMORY AS THE BLOCK SIZE PARAMETER IS SET TO ZERO ;THIS ALLOWS ME TO USE THE SAME BLOCKS OVER AND OVER AGAIN TO RESPOND ;TO THE LAMS ; ;; ; ;; $CMIN2:: .IF DF,LAMSV CALL $INTSV,PL MOV CMCTB,R4 BIC #1,(R4) ; 3$: TST (R4) ; BPL 3$ MOVB #101,1(R4) ; 1$: TST (R4) ; BPL 1$ ; MOV DATA(R4),R0 ; MOV DATA(R4),R1 ; MOV .CM0+32,R3 ; MOV #.CM0+32+2,R2 ; SUB R2,R3 ; ASR R3 ; ASR R3 ; MOV R3,-(SP) 2$: BIT (R2)+,R0 BNE 4$ BIT (R2)+,R1 BNE 4$ SOB R3,2$ 4$: SUB R3,(SP) MOV (SP)+,R4 MOV .CM1+34+2(R4),R5 MOV I.UCB(R5),R5 CALL $FORK MOV R4,R3 MOV R4,R1 JSR PC,SETUP MOV #1,R0 CLR R1 BIS #1,S.CSR(R5) CALLR $IOFIN .IFF RTI .ENDC ; ; ;& SETUP is the routine that loads the branch driver's registers with ;&the proper stuff to start an operation. ;&If the cary is clear, a non DMA operation is assumed, other ;&wise a DMA transfer is specified. ; ; ;; SETUP: MOV S.CSR(R4),R2 ;& First put the address of the control ;&status register into R2. BCC 2$ ;&Next check to see if the carry is set CMP R5,#.CM1 ;&and if so check to see that the unit is BNE 4$ ;&CM1: if not indicate an error MOV U.BUF+2(R5),R3 ;&Otherwise, get the address of the BIC #10,(R2) ;&buffer and clear the LAM interupt enable BIS #DMA,U.CW2(R5) ;&Also set the DMA mode bit MOV R3,MADR(R2) ;&Start loading the BDs registers starting MOV I.PRM+6(R1),CRAT(R2) ;&with the address register then the MOV U.CNT(R5),R3 ;&then the crate select. Now get the ASR R3 ;&byte count and place in R3 and set to BIT #MD24,I.PRM+10(R1) ;&word count. The FNA word must be checked ;&for 24 bit transfer and if set devide the ;&word count by two once agine. BEQ 5$ ASR R3 ; 5$: NEG R3 ;&Now the word count is negated BIC #^C7777,R3 ;&extranous bits masked off .IF DF,JORW MOV R3,-(SP) MOV U.BUF(R5),R3 BIC #^C60,R3 SWAB R3 BIS (SP)+,R3 SZADJ=SZADJ+7 .ENDC MOV R3,XTEND(R2) ;&and loaded into the extended word count BIS #PL,PS ;®ister. Now the processor priority ;&is raised so that if the DMA operation ;&finishes before i exit this routine ;&I can disable the pending interupt ;&and thereby remove the need to go ;&through the interupt service code. ;&The trade off is that i must run at the level ;&of the BD till this is done but it only tacks a ;&short time. ; ; BIS #4,@S.CSR(R4) ;&At this time the completion interupt MOV I.PRM+10(R1),FNA(R2) ;&is enabled and the FNA word loaded ;&which causes the operation to start RTS PC ;&which causes the operation to start ; ;& For a non DMA transfer, the unit ; 2$: CMP R5,#.CM0 ;&is checked to be CM0: BEQ 3$ ;&and if not, 4$: MOV #IE.BAD&377,R0 ;&an error functon is sent out ADD #2,SP ;HERE CLEAR OUT THE STACK JMP DON ;AND JUMP TO DONE 3$: MOV I.PRM+6(R1),CRAT(R2) ;&Otherwise, load the crate select MOV I.PRM+10(R1),FNA(R2) ;&and the FNA word RTS PC ;&and return. .BLKW 422-SZADJ ; .PRINT ;THIS SHOULD BE AT 2234 .END