.NLIST TTM .LIST MEB .ENABL LC .TITLE MBDRV .IDENT /RICE01/ .MCALL ABODF$,HWDDF$,PKTDF$,UCBDF$,SCBDF$ ABODF$ ; DEFINE ABOFT CODES HWDDF$ ; DEFINE HARDWARE REGISTERS PKTDF$ ; DEFINE I/O PACKET ADDRESSES UCBDF$ ; DEFINE UCB OFFSETS SCBDF$ ; DEFINE SCB OFFSETS LD$MB=0 MBCSR=164000 ; MIOP CONTROL STAT REGISTER MBPDR=164002 ; MIOP PROGRAM DATA REGISTER ; ;START EXECUTION OF COMMAND LIST ; QIO$ IO.RBC,LUN,[EFN],[PRI],[ISB],[AST], ; IO.RBC = FUNCTION, MODIFIERS ARE: ; 200 = RESTART CLIST (WHERE IT LAST STARTED) ; BUFF = I/O BUFFER (MUST BE IN LOWER 64 KBYTES) ; SIZE = BUFFER SIZE(#BYTES) EVEN NUMBER ONLY ; CLIST = COMMAND LIST ADDRESS (LOWER 64 KB ONLY) ; CLSIZ = CLIST SIZE(#BYTES) EVEN NUMBER ONLY ; ITMO = TIMEOUT COUNT (1-255) ; = 0 (TIMEOUT COUNT IS 4 SEC) ; < 0 (INFINITE COUNT, NO TIMEOUT) ; CRMSK = BYTE CRATE MASK. BIT# IS SET FOR EA. CRATE USED. ; ;STOP EXECUTION OF CURRENT COMMAND LIST (REQUESTOR MUST BE ATTACHED) ; QIO$ IO.STP,LUN,,,, ; ;ATTACH LUN AND UP TO 8 CRATES AND ENABLE FAST QUEING ; QIO$ IO.ATT,,,, ; ;DETACH LUN AND CRATES ; QIO$ IO.DET,,, ; ;STATUS RETURNS ; ;BYTE 0 ; IS.SUC = Success ; IE.DNR = MIOP crash (device not ready) ; IE.PRI = Privelege error (from IO.ATT, IO.STP, IO.RBC) ; IO.STP Device is not attached ; IO.ATT,IO.RBC Device is attached by another user. ; IE.ABO = CLIST aborted (by timeout, IO.KIL, IO.STP) ; IE.SPC = Buffer or CLIST outside of users space ; IE.DAO = Data overrun attempted by CLIST ; IE.BAD = Bad final CLIST address outside CLIST boundaries ; IE.DAA = Device already attached (IO.ATT) ; IE.DNA = Device not attached (IO.DET) ; ;BYTE 1 = 200 If this buffer is continuation ;BYTES 2+3 = #BYTES TRANSFERRED ; ;MIOP CSR BITS ; ; 0 = GO ; 1-3 = FUNCTION ; 1 = RESET,2 = LOAD IR, 3 = EXECUTE IR ; 4 = SINGLE INSTR. EXECUTE(FROM CM),5 = CONTINUE ; 6 = INITIALIZE CHAN. (SEL FIELD),7 = NOP ; 4 = 0 (UNUSED) ; 5 = BUSY (READ ONLY) ; 6 = INTERRUPT ENABLE (READY,ERROR) ; 7 = READY ; 8-11 = CHAN # SELECT ; 12 = 0 (Unused) ; 13 = BRANCH XFR ERROR ; 14 = BUS TIMING ERR. ; 15 = ERROR OCCURRED ; ; ;I/O PACKET DEFINITIONS ; I.BUF = I.PRM ; I/O BUFFER DOUBLE WORD ADDRESS I.CNT = I.PRM+4 ; I/O COUNT (BYTE OR WORD) I.CLS = I.PRM+6 ; COMMAND LIST ADDRESS (VIRTUAL OR MIOP) I.SIZ = I.PRM+10 ; COMMAND LIST SIZE (# BYTES) I.TIM = I.PRM+12 ; TIMEOUT COUNT (0-255.) I.ATT = I.PRM+14 ; CRATE ATTACHMENT MASK ; S.MBQ = S.FRK ; FAST QUEING Conditional (list head) U.CRAT = U.CW2 ; CRATE ATTACHMENT STATUS IOCONT = 1 ; CLIST Continue conditional ; ;IMPURE DATA TABLES ; MBCRSH: .BLKW 12. ; Crash status ; ; BUFFER address, initial, final ; Termination mode, BUFFER address requested ; MB.BUF: .BLKW 1 ; Buffer address (0 = ABORT) MB.CNT: .BLKW 1 ; Buffer count (-=overflow) MB.CLS: .BLKW 1 ; Clist address (final address) MB.STT: .BLKW 1 ; (Final buffer address) .BLKW 60. CNTBL: .BLKW 16. ; POINTS TO UCB TEMP: .BLKW 1 ; SAVES CONTROLLER # DURING SETUP PDRSAV: .BLKW 1 ; SAVES PDR VALUE ATTSTS: .BLKW 1 ; SAVES ATTACHMENT STATUS ; ; ;ENTRY POINT TABLE ; $MBTBL::.WORD MBCHK,MBCAN,MBOUT,MBPWF ; START,CANCEL,TIMEOUR,POWER FAIL ; ; INITIATOR TO START I/O ON THE MIOP ; ; ; R5 = UCB ; R4 = SCB ; R1 = I/O PACKET ; MBCHK: ; CHECK I/O PACKET BEFORE QUEING MOV R1,R3 ; SAVE PACKET ADDRESS 1$: MOVB I.FCN+1(R1),R0 ; GET FUNCTION CMP R0,#IO.STP/256. ; IS FUNCTION I/O STOP? BNE 6$ ; NO CMP U.ATT(R5),I.TCB(R1) ; IS REQUESTOR ATTACHED BNE 4$ ; NO, DO NOT STOP MTPS #PR5 ;;; RAISE PRIORITY JSR PC,MBOUT ;;; CANCEL CURRENT CLIST MTPS #PR0 ;;; RESTORE ZERO PRIORITY MOV #IS.SUC,R0 ; SUCESSFUL OPERATION BR 5$ ; NO ERROR CODE 4$: MOV #IE.PRI&377,R0 ; (PRIVELEGE ERROR) 5$: CLR R1 ; CLEAR EXTRA STATUS JMP MBFIN ; FINISH I/O 6$: CMP R0,#IO.RBC/256. ; IS FUNCTION IO.RBC?? BNE 21$ ; NO, ONLY QUE IT MOV I.CLS(R3),R0 ; VIRTUAL ADDRESS OF CLIST MOV I.SIZ(R3),R1 ; LENGTH CALL $ACHCK ; DO ADDRESS CHECK BCC 10$ ; ADDRESS SPACE IS OK 7$: MOV #IE.SPC&377,R0 ; ERROR CODE BR 5$ ; TERMINATE I/O 10$: CALL $RELOC ; GET DOUBLE WORD ADDRESS MOV I.SIZ(R3),R0 ; CLIST SIZE (# BYTES) CALL CVDTMB ; GET MIOP ADDRESS BCS 7$ ; ADDRESS IS NFG MOV R1,I.CLS(R3) ; STORE IN PACKET MIOP ADDRESS MOV R0,I.SIZ(R3) ; STORE CLIST SIZE (WORDS) MOV I.CNT(R3),R0 ; BUFFER BYTE COUNT MOV I.BUF(R3),R1 ; BUFFER DOUBLE WORD ADDRESS MOV I.BUF+2(R3),R2 ; BUFFER DOUBLE WORD ADDRESS CALL CVDTMB ; GET MIOP ADDRESS BCS 7$ ; BAD ADDRESS MOV R1,I.BUF(R3) ; SAVE ADDRESS IN PACKET MOV R0,I.CNT(R3) ; SAVE COUNT (WORDS) TSTB I.TIM(R3) ; CHECK TIME OUT COUNT BNE 13$ ; IT IS NON ZERO MOV #4,I.TIM(R3) ; SET IT TO 4 SEC. STANDARD 13$: BGT 14$ ; POSITIVE VALUE IS OK CLR I.TIM(R3) ; MAKE IT NONE 14$: MOV R3,R1 ; RESTORE IOPKT ADDRESS ; ; THIS SECTION IS USED IF FAST QUEING IS DESIRED ; .IFDF S.MBQ CMP U.ATT(R5),I.TCB(R1) ; IS REQUESTOR ATTACHED? BNE 21$ ; SKIP IMMEDIATE QUE .IFDF U.CRAT ; IF CRATE ATTACHMENT ALLOWED MOVB I.ATT(R1),R0 ; GET CRATES USED BICB U.CRAT(R5),R0 ; CLEAR BITS FOR OWNED CRATES BITB R0,ATTSTS ; TEST IF WRONG CRATES USED BNE 4$ ; YES, ISSUE ERROR .ENDC MOVB U.UNIT(R5),R2 ; R2 = UNIT# MOV R2,R3 ; UNIT INTO R3 ASL R3 ; NOW IS WORD POINTER ASL R3 ; NOW IS DOUBLE WORD POINTER ASL R3 ; R3 = MBTABL MTPS #PR5 ;;; RAISE PRIORITY TSTB S.STS(R4) ;;; IS UNIT BUSY BNE 15$ ;;; ONLY QUE JSR PC,MBBEG ;;; START THE I/O BR 20$ 15$: CLR (R1) TST S.MBQ(R4) ;;; IS QUE ENPTY? BNE 16$ ;;; NO MOV R1,S.MBQ(R4) BR 17$ 16$: MOV R1,@S.MBQ+2(R4) ;;; INSERT AT END OF QUE 17$: MOV R1,S.MBQ+2(R4) ;;; SET END QUE POINTER 20$: MTPS #PR0 ;;; RESTORE STATUS BR MBINI ; CHECK FOR I/O PACKET .ENDC ; ; NORMAL SLOW QUEING SEQUENCE ; 21$: MOV R4,R0 ; MUST BE SCB TO QUE CALL $QINSP ; INSERT INT PRIORITY ORDERED QUE ; ; INITITATE I/O ; MBINI: CALL $GTPKT ; GET IO PACKET IF AVAILABLE BCS MBXIT ; NONE AVAILABLE ; ; R1 = IO PKT R2 = UNIT# R3 = CONTROL INDEX ; R4 = SCB R5 = UCB ; CMPB I.FCN+1(R1),#IO.RBC/256. ; TEST IF RBC BEQ 5$ ; YES MOV #30.,R3 ; UNITS-1 * 2 CMPB I.FCN+1(R1),#IO.ATT/256. ; IS FUNCTION ATTACH? BNE 2$ ; NO ,IT MUST BE DETACH 1$: MOV CNTBL(R3),R2 ; UCB TO CHECK CMP I.TCB(R1),U.ATT(R2) ; ARE WE ATTACHED TO THIS UNIT BEQ 11$ ; YES, DO NOT CHECK CRATE MASK BITB I.PRM(R1),U.CRAT(R2) ; ARE CRATES(S) ALREADY ATTACHED? BNE 6$ ; YES, GIVE ERROR 11$: SUB #2,R3 ; NEXT UCB BGE 1$ ; CONTINUE TILL COUNT EXHAUSTED MOVB I.PRM(R1),U.CRAT(R5) ; ATTACH THE CRATE BISB I.PRM(R1),ATTSTS ; SET MASK BR 4$ ; EXIT WITH OK STATUS 2$: CLRB U.CRAT(R5) ; (IO.DET) CLEAR ATTACHMENT CLRB ATTSTS ; CLEAR OUT ATTACHMENT STATUS 3$: MOV CNTBL(R3),R2 ; UCB BISB U.CRAT(R2),ATTSTS ; RESET CRATE STATUS SUB #2,R3 ; NEXT UCB BGE 3$ ; CONTINUE TILL DONE 4$: MOV R1,R3 ; R3 = IOPKT (FOR $IOFIN) MOV #IS.SUC,R0 ; SET SUCCESS BR 7$ ; AND REST RESET 5$: MOVB I.ATT(R1),R0 ; (IO.RBC) GET INTENDED CRATES BICB U.CRAT(R5),R0 ; CLEAR ONES YOU OWN BITB R0,ATTSTS ; CHECK IF ILLEGAL CRATE TO BE USED BEQ 10$ ; IT IS OK 6$: MOV R1,R3 ; R3 = IOPKT (FOR $IOFIN) MOV #IE.PRI&377,R0 ; (PRIVILEGE VIOLATION) ERROR CODE 7$: CLR R1 ; NO COUNT CLRB S.STS(R4) ; CLEAR BUSY BICB #US.BSY,U.STS(R5) ; CLEAR UNIT BUSY JMP MBFIN ; FINISH I/O 10$: ASL R3 ; (IO.RBC) R3 IS DOUBLE WORD POINTER ASL R3 ; R3 = MBTABL INDEX MTPS #PR5 ;;; SET UP PRIORITY 5 CALL MBBEG ;;; START MIOP CHANNEL MTPS #PR0 ;;; RESTORE PRIORITY MBXIT: RETURN ; ; INTERRUPT ENTRY ; $MBINT:: INTSV$ MB,PR5,16. ;;; SAVE REGS + LOWER PRIORITY ; ; R5 = UCB R4 = CONTROLLER INDEX ; MOV U.SCB(R5),R4 ;;; R4 = SCB **** TSTB S.STS(R4) ;;; IS CONTROLLER BUSY BNE 1$ ;;; YES, ALLOW FURTHER PROCESSING INC U.CW4(R5) ;;; Increment error counter JMP $INTXT ;;; NO, EXIT FROM SPURIOUS INTERRUPT 1$: MOV R3,-(SP) ;;; SAVE EXTRA REGISTERS MOV R2,-(SP) ;;; MOV R1,-(SP) ;;; MOV R0,-(SP) ;;; MOVB S.CON(R4),R3 ;;; GET CONTROLLER INDEX ASL R3 ;;; NOW IS 2 WORD POINTER ASL R3 ;;; R3 = MBTABL INDEX MOV MB.CLS(R3),-(SP) ;;; SAVE TABLE MOV MB.CNT(R3),-(SP) ;;; SAVE TABLE MOV MB.BUF(R3),-(SP) ;;; SAVE TABLE CLR MB.BUF(R3) ;;; Prevent double starts MOV MB.STT(R3),-(SP) ;;; SAVE TABLE MOV S.PKT(R4),-(SP) ;;; SAVE IO PKT ; ; FAST QUEING CONDITIONAL SECTION ; .IFDF S.MBQ MOV S.MBQ(R4),R1 ;;; GET NEW PACKET BEQ 2$ ;;; NONE TO GET JSR PC,MBBEG2 ;;; START IT MOV (R1),S.MBQ(R4) ;;; NEXT PACKET BR 3$ ;;; DO NOT CLEAR STAT .ENDC ; ; SET UP ERROR STATUS ; 2$: CLRB S.CTM(R4) ;;; CLEAR TIMEOUT COUNT CLRB S.STS(R4) ;;; CLEAR STATUS BICB #US.BSY,U.STS(R5) ;;; CLEAR UNIT BUSY 3$: MOV (SP)+,R1 ;;; GET OLD PACKET MOV (SP)+,R0 ;;; BUFFER LAST WORD ADDRESS (MB.STT) SUB I.BUF(R1),R0 ;;; SUBTRACT STARTING ADDRESS TST I.BUF(R1) ;;; WAS IT PRE-ABORTED? BNE 4$ ;;; NO CLR R0 ;;; YES 4$: CMP R0,I.CNT(R1) ;;; IS FINAL ADDRESS OK? BLOS 12$ ;;; YES INCB MBCRSH ;;; Count the number of crashes MOVB U.UNIT(R5),MBCRSH+1 ;;; Save unit # MOV (SP)+,MBCRSH+20 ;;; Buffer address sent MOV (SP)+,MBCRSH+16 ;;; Termination mode MOV (SP)+,MBCRSH+2 ;;; Final CLIST address (word) MOV I.CLS(R1),MBCRSH+4 ;;; Save initial CLIST address (word) MOV I.SIZ(R1),MBCRSH+6 ;;; CLIST size (word) MOV R0,MBCRSH+10 ;;; Buffer word count ADD I.BUF(R1),MBCRSH+10 ;;; Now is final address (word) MOV I.BUF(R1),MBCRSH+12 ;;; Buffer start address (word) MOV I.CNT(R1),MBCRSH+14 ;;; Buffer size (word) CLR I.PRM+2(R1) ;;; Clear status word count MOV #IE.DNR&377,R0 ;;; ERROR CODE (Device not ready) BR 13$ 12$: ASL R0 ;;; NUMBER OF BYTES READ/WRITE MOV R0,I.PRM+2(R1) ;;; SAVE BYTE COUNT IN I/O PACKET MOV #IS.SUC,R0 ;;; SUCESSFUL TERMINATION CODE TST (SP)+ ;;; CHECK IF BUFFER ABORTED (MB.BUF) BNE 5$ ;;; NOT ABORTED MOV #IE.ABO&377,R0 ;;; (CLIST ABORTED) 5$: TST (SP)+ ;;; CHECK TERMINATION MODE (MB.CNT) BGE 6$ ;;; No buffer overrun MOV #IE.DAO&377,R0 ;;; DATA OVERRUN ERROR 6$: MOV (SP)+,R2 ;;; FINAL CLIST ADDRESS (MB.CLS) SUB I.CLS(R1),R2 ;;; SUBTRACT INITIAL CLIST ADDRESS CMP R2,I.SIZ(R1) ;;; GREATER THAN CLIST SIZE? BLOS 13$ ;;; Clist final address is OK MOV #IE.BAD&377,R0 ;;; Not OK set error ; ADD I.CLS(R1),R2 ;;; Now make it absolute address*** DEBUG MOV R2,U.CW3(R5) ;;; Save the relative address 13$: MOV R0,I.PRM(R1) ;;; SAVE ERR CODE IN I/O PKT MOVB I.FCN(R1),I.PRM+1(R1) ;;; Continuation status MOV R4,R2 ;;; NOW R2 = SCB MOV R1,R4 ;;; R4 = I/O PKT ADD #I.PRM+14,R4 ;;; POINTS TO END OF FORK BLOCK MOV U.SCB(R5),R2 ;;; GET STATUS CONTROL BLOCK MOV S.FRK+10(R2),(R4) ;;; GET RELOCATION ADDRESS MOV R1,-(R4) ;;; SAVE ADDRESS OF I/O PACKET MOV (SP)+,R0 ;;; RESTORE REGS 0-3 MOV (SP)+,R1 ;;; MOV (SP)+,R2 ;;; MOV (SP)+,R3 ;;; CALL $FORK1 ;;; NOW GO TO ZERO PRIORITY CMPB I.PRM(R4),#IE.DNR ; Crash ? BNE 15$ ; NO MOV #T.NDNR,R0 ; YES, Device not ready message CALL $DVMSG ; Type the message 15$: MOV R4,R3 ; R3 = IOPKT (FOR $IOFIN) MOV I.PRM(R3),R0 ; R0 = STATUS MOV I.PRM+2(R3),R1 ; R1 = BYTE COUNT MBFIN: CALL $IOFIN ; FINISH I/O (R0,R1,R3,R5) REQUIRED JMP MBINI ; START NEW I/O ; ; POWERFAIL ROUTINE ; ; R5 = UCB R4 = SCB ; R3 = CNTRL INDEX ; MBPWF: .IFDF U.CRAT ; IF CRATE ATTACHEMENT ALLOWED CLRB U.CRAT(R5) ; CLEAR ATTACHEMENT CLRB ATTSTS ; AND MASK .ENDC .IFDF S.MBQ ; IF FAST QUEING ALLOWED CLR S.MBQ(R4) ; CLEAR FAST QUEING .ENDC MOV #MB.BUF,R2 ; MB TABLE ADDRESS MOV @#KISAR5,R1 ; NOW IS DOUBLE WORD ADDRESS CALL CVDTMB ; TURN INTO MIOP ADDRESS INC R1 ; NOW IS CORRECT ADDRESS MOV R1,PDRSAV ; SAVE THE PDR MOV R1,@#MBPDR ; AND LOAD IT MOV R5,CNTBL(R3) ; UCB SAVED FOR LATER USE BR MBOUT ; CANCEL THIS CHAN. ; ; CANCEL I/O & TIMEOUT ROUTINE ; ; R5 = UCB ; R4 = SCB ADDRESS ; R3 = CONTROLLER INDEX ; MBCAN: ; R1 = REQUESTING TCB R0 = I/O PACKET CMP R1,I.TCB(R0) ;;; DOES REQUESTING TCB MATCH ONE IN I/O BNE NOCAN ;;; NO,DO NOT CANCEL .IFDF S.MBQ ; IF MB QUE IS DEFINED ACTIVATE IT MOV S.MBQ(R4),R1 ;;; GET START OF FAST MB QUE BEQ MBOUT ;;; NONE TO KILL 1$: CLR I.BUF(R1) ;;; SET UP FOR IMMEDIATE ABORT MOV (R1),R1 ;;; NEXT IN QUE? BNE 1$ ;;; YES, KILL IT TOO .ENDC MBOUT: ; R2 = CSR R0 = #IE.DNR (IOSTAT) ASL R3 ;;; ASL R3 ;;; NOW IS MBTABL POINTER CLR MB.BUF(R3) ;;; BUFFER ADDRESS IS ZERO BR LDSTAT ;;; RUN THE CHANNEL TO FLUSH OUT I/O ; ; CONVERT FROM DATA ADDRESS TO MB ADDRESS ; ; INPUT: R1,R2 = DOUBLE WORD ADDRESS R0 = BYTE COUNT ; OUTPUT: R1 = MIOP ADDRESS R0 = WORD COUNT ; CARRY = CLEAR IF ADDRESS IS OK! ; CVDTMB: BIT #174000,R1 ; CHECK FOR ADDRESS TOO LARGE BNE 2$ ; IT IS TOO BIG ASH #5,R1 ; SHIFT IT TO BE WORD ADDRESS ASR R2 ; SHIFT TO WORD ADDRESS BCS 2$ ; ODD BYTE ADDRESS ILLEGAL BIC #177700,R2 ; CLEAR EXTRANEOUS BITS ADD R2,R1 ; WORD ADDRESS DEC R1 ; MIOP ADDRESS = WORD ADDRESS - 1 CLC ROR R0 ; TURN BYTE COUNT INTO WORD COUNT MOV R0,-(SP) ; SAVE WORD COUNT ADD R1,(SP)+ ; IF NO OVERFLOW IT IS OK BCS 2$ ; OVERFLOW ERROR CLC ; ADDRESS IS OK INDICATOR RETURN 2$: SEC RETURN ; ; START MIOP BY LOADING STAT REGISTER (MBCSR) ; ; R5 = UCB ; R4 = SCB ; R3 = MBTABL ; R2 = DESTROYED BY THIS ROUTINE (MIOP FUNCTION RETURNED) ; R1 = I/O PKT ; ; MBBEG - BEGINS I/O ; MBBEG2 - BEGINS I/O (ASSUMES BUSY STATUS ALREADY SET) ; LDSTAT - ONLY R5 REQUIRED (START CHANNEL FOR KILL OR STP) ; MBBEG: MOVB #1,S.STS(R4) ;;; SET CONTROLLER BUSY BISB #US.BSY,U.STS(R5) ;;; SET UNIT BUSY MBBEG2: MOV R1,S.PKT(R4) ;;; SET PACKET INTO QUE ; ; CONDITIONAL SECTION TO HANDLE CONTINUATION BUFFERS ; .IFDF IOCONT TST MB.CNT(R3) ;;; WAS LAST DATA OVERRUN? BGE 10$ ;;; NO TSTB I.FCN(R1) ;;; IS CONTINUANCE REQUESTED? BGE 10$ ;;; NO SUB #3,MB.CLS(R3) ;;; RESET OLD CLIST ADDRESS MOV I.CLS(R1),R2 ;;; GET NEW CLIST ADDRESS CMP MB.CLS(R3),R2 ;;; WAS OLD CLIST ADDRESS>=NEW ADDRESS? BLO 10$ ;;; NO, ILLEGAL CONTINUATION ADD I.SIZ(R1),R2 ;;; LAST LEGAL CLIST ADDRESS CMP MB.CLS(R3),R2 ;;; IS IT LESS THAN LAST ADDRESS? BLOS 11$ ;;; YES CONTINUE WITH LAST CLIST .ENDC ; ; 10$: MOV I.CLS(R1),MB.CLS(R3) ;;; SET UP CLIST ADDRESS CLRB I.FCN(R1) ;;; No continuation 11$: MOV I.CNT(R1),MB.CNT(R3) ;;; BUFFER SIZE (WORDS) MOV I.BUF(R1),MB.BUF(R3) ;;; BUFFER ADDRESS (0 = KILL) MOV I.BUF(R1),MB.STT(R3) ;;; Final buff address=initial MOVB I.TIM(R1),S.CTM(R4) ;;; Timeout count (secs) LDSTAT: MOVB U.UNIT(R5),R2 ;;; R2 = UNIT # (Kill entry) SWAB R2 ;;; UNIT NUMBER INTO HI BYTE ADD #115,R2 ;;; BEGIN CLIST WITH INT ENABLED CMP PDRSAV,@#MBPDR ;;; TEST PDR FOR SECURITY BNE PDRERR ;;; BAD ERROR 1$: TSTB @#MBCSR ;;; READY? BGE 1$ ;;; NO, WAIT SOME MORE MOV R2,@#MBCSR ;;; LOAD CSR NOCAN: RETURN PDRERR: BIC #1,@#MBCSR ;;; KILL MIOP INC MBCRSH ;;; INDICATE CRASH RETURN ; ; SYSTEM DATA TABLES ; $MBDAT:: ; ; DCB ; DCBMB: .WORD 0 ; (D.LNK) POINTS TO NEXT DCB .WORD UCB0+2 ; (D.UCB) POINTS TO FIRST UCB .WORD "MB ; (D.NAM) DEVICE NAME .BYTE 0,17 ; (D.UNIT) LOWEST HIGHEST UNIT # .WORD UCB1-UCB0 ; (D.UCBL) LENGTH IN BYTES OF UCB .WORD 0 ; (D.DSP) DISPATCH TABLE (0= NON RESIDENT) .WORD 131 ; (D.MSK) LEGAL FUNC 0-17 (0,3,4,6)(KIL,ATT,DET,RBC) .WORD 031 ; CONTROL FUNC (ATT,DET) .WORD 0 ; NOOP FUNC .WORD 0 ; ACP FUNC .WORD 020000 ; LEGAL FUNC (20-37) 35 (IO.STP) .WORD 020000 ; CONTROL FUNC .WORD 0 ; NOOP FUNC .WORD 0 ; ACP FUNC .WORD 0 ; D.PCB (PARTITION CONTROL BLOCK) ; ; UCB ; .MACRO MBUCB,UNIT,SCB ; UCB,SCB DEFINITION .WORD 0 ; (L.OWN) OWNER OF ALLOC DEVICE .WORD DCBMB ; POINTER TO DCB (U.DCB) .WORD .-2 ; REDIRECT POINTER (U.RED) .BYTE UC.ALG!UC.QUE!UC.PWF!01!UC.ATT ; CONTROL FLAGS (U.CTL) ; UC.ALG = WORD ALIGNMENT OF BUFFERS ; UC.QUE = ENTER DRIVER BEFORE QUEING PACKET ; UC.PWF = ENTER DRIVER WHEN "LOA" OR BOOT ; 01 = EVEN BYTE COUNT FOR BUFFER ; UC.ATT = ATTACH/DETACH NOTIFICATION ; .BYTE 0 ; STATUS (U.STS) .BYTE UNIT ; UNIT # (U.UNIT) .BYTE US.RED ; STATUS (NO REDIRECTION POSSIBLE) .WORD 0 ; CHARACTERISTIC WORD #1 (U.CW1) .WORD 0 ; U.CW2 = U.CRAT(CRATE ATTACHMENT BYTE) .WORD 0 ; U.CW3 .WORD 0 ; U.CW4 (SET BY SET /BUF= NNN.) .WORD SCB ; SCB ADDRESS (U.SCB) .WORD 0 ; TCB OF ATTACHING TASK (U.ATT) .WORD 0,0 ; BUFFER DOUBLE WORD ADDRESS(U.BUF) .WORD 0 ; BUFFER LENGTH (U.CNT) .ENDM MBUCB ; ; SCB ; .MACRO MBSCB,UNIT .WORD 0,.-2 ; I/O QUE LISTHEADERS (S.LHD) .BYTE PR5 ; DEVICE PRIORITY (S.PRI) .BYTE 60+UNIT ; INTERRUPT VECTOR/4 (S.VCT) .BYTE 0,4 ; TIMEOUT COUNT,INITIAL COUNT (S.CTM,S.ITM) .BYTE UNIT*2 ; CONTROLLER INDEX (S.CON) .BYTE 0 ; STATUS (NON ZERO IF BUSY) (S.STS) .WORD MBCSR ; STATUS REGISTER (S.CSR) .WORD 0 ; I/O PACKET (S.PKT) .WORD 0,0,0,0,0 ; FORK(LINK,PC,R5,R4),BASE (S.FRK) ; S.MBQ = S.FRK (LINK,PC USED FOR QUE) .ENDM MBSCB .NLIST MEB ; ; PURE R/W LOADABLE DATA TABLES ; UCB0: MBUCB 0,SCB0 UCB1: MBUCB 1,SCB1 UCB2: MBUCB 2,SCB2 UCB3: MBUCB 3,SCB3 UCB4: MBUCB 4,SCB4 UCB5: MBUCB 5,SCB5 UCB6: MBUCB 6,SCB6 UCB7: MBUCB 7,SCB7 UCB8: MBUCB 8.,SCB8 UCB9: MBUCB 9.,SCB9 UCB10: MBUCB 10.,SCB10 UCB11: MBUCB 11.,SCB11 UCB12: MBUCB 12.,SCB12 UCB13: MBUCB 13.,SCB13 UCB14: MBUCB 14.,SCB14 UCB15: MBUCB 15.,SCB15 SCB0: MBSCB 0 SCB1: MBSCB 1 SCB2: MBSCB 2 SCB3: MBSCB 3 SCB4: MBSCB 4 SCB5: MBSCB 5 SCB6: MBSCB 6 SCB7: MBSCB 7 SCB8: MBSCB 8. SCB9: MBSCB 9. SCB10: MBSCB 10. SCB11: MBSCB 11. SCB12: MBSCB 12. SCB13: MBSCB 13. SCB14: MBSCB 14. SCB15: MBSCB 15. $MBEND:: .END