; THIS COMMAND FILE GENERATES DATA STRUCTURES AND SKELETON DRIVER CODE ; FOR A SPECIFIED DEVICE. ; PLEASE PARDON REDUNDANT ENTRY OF INFORMATION. THIS IS IMPOSED BY ; CERTAIN RESTRICTIONS ON THE USE OF INDIRECT COMMAND FILES. ; .ASKS UIC GIVE THE DEVICE/UIC SPEC FOR THE OUTPUT FILES .ASKS DEV WHAT IS THE DEVICE MNEMONIC .ENABLE SUBSTITUTION .ASKS VER WHAT IS THE VERSION NUMBER OF THE DRIVER .ASKS AUTH WHO IS THE AUTHOR OF THE DRIVER .ASKS DATE WHAT IS THE DATE AND TIME OF CREATION .SETS SP "" .ASK SP1 DO YOU WISH TO SPOOL LIST AND MAP FILES .IFF SP1 .SETS SP "/-SP" .ASKS PAR WHAT PARTITION IS THE DRIVER TO RUN IN .ASKS PRI WHAT IS THE DEVICE PRIORITY .ASKS UNIT HOW MANY CONTROLLERS ARE THERE .SETN NUNIT 'UNIT' .SETN ZERO 0 .SETN FLAG 0 .ASKS LOW WHAT IS THE LOWEST UNIT NUMBER .SETN LOWN 'LOW' .ASKS HIGH WHAT IS THE HIGHEST UNIT NUMBER .SETN HIGHN 'HIGH' .ASKS MSKLL WHAT IS THE LEGAL FUNCTION 0-15 MASK WORD .ASKS MSKLH WHAT IS THE LEGAL FUNCTION 16-31 MASK WORD .ASKS MSKCL WHAT IS THE CONTROL FUNCTION 0-15 MASK WORD .ASKS MSKCH WHAT IS THE CONTROL FUNCTION 16-31 MASK WORD .ASKS MSKAL WHAT IS THE ACP FUNCTION 0-15 MASK WORD .ASKS MSKAH WHAT IS THE ACP FUNCTION 16-31 MASK WORD .ASKS MSKNL WHAT IS THE NOOP FUNCTION 0-15 MASK WORD .ASKS MSKNH WHAT IS THE NOOP FUNCTION 16-31 MASK WORD .ASK MULINT IS THIS A MULTI-INTERRUPT DRIVER .OPEN 'UIC''DEV'TAB.MAC .ENABLE DATA .TITLE 'DEV'TAB .IDENT /'VER'/ ; THIS FILE CONTAINS THE NECESSARY DATA STRUCTURES FOR THE ; LOADABLE DRIVER FOR DEVICE 'DEV': ; VERSION 'VER' ; AUTHOR:'AUTH' ; DATE:'DATE' $'DEV'DAT:: ;START OF LOADABLE DRIVER ;DATABASE ; DEVICE CONTROL BLOCK 'DEV'DCB: .WORD 0 ;D.LNK - POINTER TO NEXT DCB .WORD .'DEV''LOW' ;D.UCB - POINTER TO FIRST UCB .ASCII /'DEV'/ ;D.NAM - DEVICE NAME .BYTE 'LOW','HIGH' ;D.UNIT - LOW UNIT, HIGH UNIT .WORD 'DEV'ND-'DEV'ST ;D.UCBL - LENGTH OF A UCB .WORD $'DEV'TBL ;D.DSP - POINTER TO DRIVER ; DISPATCH TABLE .WORD 'MSKLL' ;D.MSK - FUNCTION MASK .WORD 'MSKCL' ; .WORD 'MSKAL' ; .WORD 'MSKNL' ; .WORD 'MSKLH' ; .WORD 'MSKCH' ; .WORD 'MSKAH' ; .WORD 'MSKNH' ; .WORD 0 ;D.PCB - POINTER TO LOADABLE DRIVER ; PCB ; UNIT CONTROL BLOCKS .'DEV'0:: 'DEV'ST: .DISABLE DATA .UCBLP: .ENABLE DATA .WORD 0 ;LOGIN UIC - MULTIUSER PROTECTION .WORD 0 ;OWNER TERMINAL .WORD 'DEV'DCB ;U.DCB - POINTER BACK TO UCB .WORD .-2 ;U.RED - POINTER TO REDIRECT UCB .BYTE 0 ;U.CTL - CONTROL FLAG .BYTE 0 ;U.STS - UNIT STATUS .BYTE 0 ;U.UNIT - PHYSICAL UNIT NUMBER .BYTE 0 ;U.ST2 - UNIT STATUS EXTENSION .WORD DV.REC ;U.CW1 - FIRST DEVICE CHAR WORD .WORD 0 ;U.CW2 .WORD 0 ;U.CW3 .WORD 0 ;U.CW4 .DISABLE DATA .ASKS CNTRL WHAT IS THE CONTROLLER NUMBER FOR THE NEXT 'DEV' .ENABLE DATA .WORD $'DEV''CNTRL' ;U.SCB - SCB ADDRESS .WORD 0 ;U.ATT - TCB ADDRESS OF ATTACHED TASK .BLKW 2 ;U.BUF - CURRENT BUFFER ADDR DBLWORD .WORD 0 ;U.CNT - CURRENT REQUEST BYTE COUNT .WORD 0 ;U.ACP - ADDR OF TCB OF ACP .WORD 0 ;U.VCB - ADDR OF VOL. CNTRL BLOCK .WORD 0 ;U.CBF - CONTROL BUFFER RELOCATION .WORD 0 ;U.UIC - UIC OF A TERMINAL .DISABLE DATA .IF FLAG EQ ZERO .DATA 'DEV'ND=. .SETN FLAG 1 .INC LOWN .IF LOWN LE HIGHN .GOTO UCBLP .ENABLE DATA ; STATUS CONTROL BLOCKS .DISABLE DATA .SCBLP: .ASKS CNTRL GIVE THE NEXT CONTROLLER NUMBER .ASKS CSR WHAT IS ITS CSR ADDRESS .ASKS VEC WHAT IS ITS VECTOR ADDRESS .ASKS TIM WHAT IS ITS TIMEOUT COUNT .ENABLE DATA $'DEV''CNTRL':: .WORD 0 ;S.LHD - I/O QUEUE LISTHEAD .WORD .-2 ;LAST ENTRY IN I/O QUEUE .BYTE PR'PRI' ;S.PRI - DEVICE PRIORITY .BYTE 'VEC'/4 ;S.VCT - INTERRUPT VECTOR /4 .BYTE 0 ;S.CTM - CURRENT TIMEOUT COUNT .BYTE 'TIM' ;S.ITM - TIMEOUT COUNT .BYTE 0 ;S.CON - CONTROLLER INDEX .BYTE 0 ;S.STS - CONTROLLER STATUS .WORD 'CSR' ;S.CSR - CSR ADDRESS .WORD 0 ;S.PKT - ADDRESS OF CURRENT I/O PACKET .BLKW 4 ;S.FRK - FORK BLOCK .WORD 0 ;FORK DRIVER RELOCATION BASE .DISABLE DATA .DEC NUNIT .IF NUNIT GT ZERO .GOTO SCBLP .ENABLE DATA $'DEV'END:: .END .DISABLE DATA .CLOSE .OPEN 'UIC''DEV'ASM.CMD .ENABLE DATA 'UIC''DEV'TAB,'UIC''DEV'TAB'SP'=[1,1]EXEMC/ML,[200,200]RSXMC/PA:1,'UIC''DEV'TAB 'UIC''DEV'DRV,'UIC''DEV'DRV'SP'=[1,1]EXEMC/ML,[200,200]RSXMC/PA:1,'UIC''DEV'DRV .DISABLE DATA .CLOSE .OPEN 'UIC''DEV'DRVBLD.CMD .ENABLE DATA 'UIC''DEV'DRV/-HD/-MM,'UIC''DEV'DRV'SP','UIC''DEV'DRV= 'UIC''DEV'DRV,'DEV'TAB [1,54]RSX11M.STB/SS [1,1]EXELIB/LB / STACK=0 PAR='PAR':120000:4000 // .DISABLE DATA .CLOSE .OPEN 'UIC''DEV'DRV.MAC .ENABLE DATA .TITLE 'DEV'DRV .IDENT /'VER'/ .ENABL LSB ; ; VERSION 'VER' ; ; 'AUTH' ; ; 'DATE' ; ; SKELETON DRIVER CODE FOR 'DEV': ; .MCALL HWDDF$,PKTDF$,DEVDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET DEFINITIONS DEVDF$ ;DEFINE DEVICE TABLE OFFSETS ; ; LOCAL DATA STRUCTURES ; ; ************************************************************ ; * * ; * THIS IS WHERE INFORMATION LOCAL TO A SPECIFIC * ; * CURRENT REQUEST WOULD APPEAR. AS CREATED, * ; * THIS DRIVER STORES UCB ADDRESSES IN THIS AREA * ; * * ; ************************************************************ CNTBL: .BLKW 'UNIT' ;UCB ADDRESSES OF CURRENT REQUEST ; DEFINE NECESSARY SYMBOL FOR LOADABLE DRIVER LD$'DEV'=0 ; DRIVER DISPATCH TABLE $'DEV'TBL::.WORD 'DEV'INI ;DEVICE INITIALIZATION .WORD 'DEV'CAN ;DEVICE I/O CANCELLATION .WORD 'DEV'TMO ;DEVICE TIMEOUT ENTRY .WORD 'DEV'PWR ;POWER FAIL RECOVERY ROUTINE .PAGE .SBTTL DRIVER INITIATION CODE ; THIS SECTION IS CALLED WHEN A PACKET IS QUEUED TO THIS ; DEVICE, AND THE DRIVER SHOULD RETURN HERE WHEN A REQUEST ; IS FINISHED, IN ORDER TO SERVICE ANY PENDING REQUESTS 'DEV'INI: CALL $GTPKT ;GET AN I/O PACKET BCC 10$ ;IF CC THERE IS A PACKET RETURN ;NO PACKET OR CONTROLLER BUSY ; CONTROL PASSES HERE WHEN A PACKET HAS BEEN SUCCESSFULLY ; REMOVED FROM THE I/O QUEUE WITH THE FOLLOWING ARGUMENTS ; GIVEN: ; R1 = ADDRESS OF THE I/O PACKET ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3 = CONTROLLER INDEX (CONTROLLER NUMBER TIMES 2) ; R4 = ADDRESS OF THE SCB ; R5 = ADDRESS OF THE UCB 10$: MOV R5,CNTBL(R3) ;SAVE UCB ADDRESS ; ************************************************************ ; * * ; * THE FOLLOWING IS A SAMPLE CODE SEQUENCE * ; * WHICH ASSUMES A DRIVER WITH ONLY READ AND * ; * WRITE FUNCTIONS. THE DRIVER ENABLES TIMEOUTS * ; * ON OUTPUT FUNCTIONS, TURNS ON INTERRUPTS * ; * FOR EITHER CASE, AND DOES A RETURN TO EXIT * ; * THIS AREA SHOULD PROBABLY BE CHANGED FOR * ; * YOUR TAILORED DRIVER. * ; * * ; ************************************************************ CMPB #IO.RLB/256.,I.FCN+1(R1) ; READ LOGICAL ? BEQ 20$ ;IF EQ YES MOVB S.ITM(R4),S.CTM(R4) ;INITIALIZE TIMEOUT COUNTER 20$: BIS #100,@S.CSR(R4) ;ENABLE INTERRUPTS RETURN ;EXIT FROM DRIVER .PAGE .SBTTL INTERRUPT SERVICE ROUTINES ; INPUT INTERRUPT SERVICE ROUTINE $'DEV'INP::INTSV$ 'DEV',PR'PRI','UNIT' ;;; ; ************************************************************ ; * * ; * THIS IS WHERE CODE RELEVANT TO SERVICING INPUT * ; * INTERRUPTS SHOULD BE PUT. THIS EXAMPLE MERELY * ; * MOVES ONE BYTE OF DATA TO A USER BUFFER AND * ; * PERFORMS NECESSARY FINISH OPERATIONS IF THE * ; * BUFFER IS EMPTY. UPON ENTRY TO THIS SECTION: * ; * R5 = UCB ADDRESS * ; * * ; ************************************************************ MOV U.SCB(R5),R4 ;;;POINT TO SCB MOV S.CSR(R4),R4 ;;;POINT TO CSR MOVB 2(R4),-(SP) ;;;GET INPUT CHARACTER CALL $PTBYT ;;;STORE THE CHARACTER IN USER BUFFER DEC U.CNT(R5) ;;;DECREMENT REQUEST LENGTH BEQ DONE ;;;FINISH PROCESSING FOR REQUEST CALLR $INTXT ;;;EXIT FROM INTERRUPT ; OUTPUT INTERRUPT SERVICE ROUTINE $'DEV'OUT::INTSV$ 'DEV',PR'PRI','UNIT' ;;; ; ************************************************************ ; * * ; * THIS IS WHERE CODE RELEVANT TO THE PROCESSING * ; * OF OUTPUT INTERRUPTS SHOULD BE PLACED. * ; * THE EXAMPLE MERELY PUTS ANOTHER BYTE FROM THE * ; * USER BUFFER AND DOES THE NECESSARY PROCESSING * ; * IF THE USER BUFFER IS EMPTY. UPON ENTRY TO THIS * ; * SECTION: * ; * R5 = UCB ADDRESS * ; * * ; ************************************************************ TST U.CNT(R5) ;;;ANY CHARACTERS LEFT BEQ DONE ;;;IF EQ NO CALL $GTBYT ;;;GET ANOTHER BYTE TO OUTPUT MOV U.SCB(R5),R4 ;;;POINT TO SCB MOV S.CSR(R4),R4 ;;;POINT TO CSR MOVB (SP)+,6(R4) ;;;OUTPUT BYTE DEC U.CNT(R5) ;;;ONE LESS TO OUTPUT CALLR $INTXT ;;;FROM INTERRUPT .PAGE .SBTTL I/O DONE,CANCEL,TIMEOUT,POWERFAIL ; ************************************************************ ; * * ; * THIS IS WHERE CODE RELEVANT TO THE COMPLETION * ; * OF I/O REQUESTS SHOULD BE PUT. THIS EXAMPLE * ; * DISABLES THE DEVICE, FORKS, RETURNS A STATUS * ; * CODE AND ATTEMPTS TO REMOVE ANOTHER PACKET * ; * * ; ************************************************************ DONE: CLR (R4) ;;;DISABLE INTERRUPTS MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS CALL $FORK ;;;CREATE A SYSTEM PROCESS MOV S.PKT(R4),R1 ;PICK UP PACKET ADDRESS MOV I.PRM+4(R1),R1 ;RETURN REQUESTED BYTE COUNT MOV #IS.SUC,R0 ;AND SUCCESS CODE ; NOTE THAT $IODON PLACES R0 AND R1 IN IOSB AND IOSB+2 ; COMMON FINISH ROUTINE FOR ALL DONE,CANCEL,TIMEOUT 'DEV'EXT: CALL $IODON ;FINISH I/O BR 'DEV'INI ;LOOK FOR MORE WORK ; ************************************************************ ; * * ; * THIS IS WHERE CODE RELEVANT TO CANCELLING A * ; * PENDING I/O REQUEST. THE EXAMPLE DISABLES * ; * INTERRUPTS AND RETURNS SUCCESS STATUS * ; * * ; ************************************************************ 'DEV'CAN: MOV #IS.SUC,R0 ;;;SET SUCCESS CODE ; ************************************************************ ; * * ; * THIS IS WHERE CODE RELEVANT TO DEVICE TIMEOUTS * ; * SHOULD BE PLACED. THE EXAMPLE MERELY DISABLES THE * ; * DEVICE AND REQUESTS A NEW PACKET ; * * ; ************************************************************ 'DEV'TMO: BIC #100,@S.CSR(R4) ;;;DISABLE INTERRUPTS BR TYEXT ;FINISH IN COMMON CODE ; ************************************************************ ; * * ; * THIS IS WHERE CODE RELEVANT TO POWERFAIL RECOVERY * ; * SHOULD BE PUT. THE EXAMPLE MERELY RE-ENABLES THE * ; * DEVICE AND RETURNS. * ; * * ; ************************************************************ 'DEV'PWR: BIS #100,@S.CSR(R4) ;ENABLE DEVICE RETURN .END .DISABLE DATA .CLOSE