.TITLE MB11M MAIL BOX DEVICE .IDENT /16APR0/ ;+ ; - M B : ; ;****NAME: MB: MAIL BOX DEVICE DRIVER ; FILE: MB11M.MAC ; TKB: SY:MBDRV/-HD/-MM,,MBDRV= ; SY:[UIC]MB11M ; SY:[1,54]RSX11M.STB/SS ; SY:[1,1]EXELIB/LB ; / ; PAR=GEN:120000:4000 ; STACK=0 ; // ; ;****PURPOSE: TRANSFER LARGE BLOCKS OF DATA BETWEEN TASKS ; ;****RESTRICTIONS: WORD ALLIGNED BUFFERS ; WORD MODULOUS BYTES TRANSFERED ; MAPPED SYSTEMS ; $BLXIO SYSGEN OPTION ; LOADABLE DRIVER SYSGEN OPTION ; ; SYSTEM: RSX11M ; LANGUAGE: MACRO-11 ; AUTHOR: DAVID DANIELS ; GROUP MP-1 ; MAIL STOP 828 ; LOS ALAMOS SCIENTIFIC LABORATORY ; LOS ALAMOS, NEW MEXICO 87545 ; (505)-667-5241 ; DATE: 18-APR-80 ; REVISIONS: ; ;****DIALOG: ; ;****RESOURCES: ; LIBRARIES: SY:[001,001]RSXMC.MAC ; SY:[001,001]EXEMC.MLB ; SY:[001,001]EXELIB.OLB ; SY:[001,054]RSX11M.STB ; OTHER SUBR: ; DISK FILES: ; DEVICES: ; SGAS: ; EVENT FLAGS: ; SYSTEM DIR: ; LENGTH/PAR: ; ;****NOTES: ; ; MAIL BOX DEVICE. ; ; RSX 11/M EXECUTIVE OPERATING SYSTEM. ; MAPPED SYSTEMS. ; LOADABLE DRIVER. ; ; DESIGNED TO TRANSFER LARGE BLOCKS OF DATA BETWEEN TASKS. ; THE DATA BUFFERS TRANSFERED MUST BE WORD ALLIGNED AND ; THE DATA BUFFER BYTE COUNTS MUST BE WORD MODULUS. ; ; ACCESS QIO FCN,LUN,[EFN],[PRI],[IOST],[AST],[PRL] ; ; FCN I/O FUNCTION CODE. ; IO.RVB READ VIRTUAL BLOCK. ; IO.WVB WRITE VIRTULA BLOCK. ; IO.KIL KILL ALL I/O REQUESTS. ; ; LUN LOGICAL UNIT NUMBER. ; ; EFN EVENT FLAG NUMBER. ; ; PRI PRIORITY. ; ; IOSB I/O STATUS BLOCK. ; IE.IFC INVALID FUNCTION CODE. ; IE.DNR DEVICE NOT READY. ; IE.BAD BAD PARAMETER. ; IE.NST TARGET TASK NOT INSTALLED. ; IE.SPC ILLEGAL BUFFER LIMITS. ; IE.ABO REQUEST TERMINATED. ; IS.PND I/O REQUEST PENDING. ; IS.SUC I/O REQUEST SUCCESSFUL. ; ; AST ADDRESS OF AST ROUTINE. ; ; PRL PARAMETER LIST IN THE FORM . ; ; P1 ADDRESS OF I/O BUFFER. ; P2 BYTE COUNT OF I/O BUFFER. ; P3 FIRST 3 CHARACTERS OF THE TARGET TASK (RAD50). ; P4 LAST 3 CHARACTERS OF THE TARGET TASK (RAD50). ; IF THE RAD50 VALUES ARE ZERO FOR A IO.RVB FUNCTION, ; THE REQUEST IS VIEWED AS A "NON-SPECIFIC READ" FOR ; ANY I/O PACKET THAT IS TARGETED FOR THE INITIATIOR ; TASK. ; P5 ; LOW BYTE: TARGET TASK TERMINAL # + 1. ; IF THE VALUE IS ZERO, THE TEST FOR A ; MATCHING TERMINAL VALUE IS NOT APPLIED. ; HI BYTE: BIT 0, TARGET TASK INSTALLED FLAG. ; BIT 1, TARGET TASK COMPLIMENTRY QIO FLAG. ; FLAG BITS SET IMPLY REJECTION OF CURRENT ; QIO PACKET WHEN CRITERIA NOT MET. ;- .PAGE ;+ ; MACROS AND LOCAL DATA ;- .MCALL ABODF$,DCBDF$,DEVDF$,HWDDF$,PKTDF$ .MCALL QIOSY$,SCBDF$,TCBDF$,UCBDF$ ; ABODF$ ; ABORT TASK CODES. DCBDF$ ; DEVICE CONTROL BLOCK (DCB) OFFSETS. DEVDF$ ; DEVICE OFFSETS. HWDDF$ ; HARDWRARE REGISTER ADDRESSES. PKTDF$ ; AST CONTROL BLOCK AND I/O PACKET OFFSETS. QIOSY$ ; QUEUE I/O SYMBOLS. SCBDF$ ; STATUS CONTROL BLOCK (SCB) OFFSETS. TCBDF$ ; TASK CONTROL BLOCK (TCB) OFFSETS. UCBDF$ ; UNIT CONTROL BLOCK (UCB) OFFSETS. ; I.BUFB = I.PRM+00 ; I/O PACKET BUFFER BIAS I.BUFO = I.PRM+02 ; I/O PACKET BUFFER OFFSET I.CNT = I.PRM+04 ; I/O PACKET BUFFER BYTE COUNT I.NAM = I.PRM+06 ; I/O PACKET TARGET TASK NAME I.TTN = I.PRM+12 ; I/O PACKET TARGET TASK TERNINAL + 1 I.QIO = I.PRM+13 ; I/O PACKET 'QIO REJECT' FLAGS I$INS = 1 ; TARGET TASK INSTALLED BIT I$QIO = 2 ; TARGET TASK COMPLIMENTARY QIO BIT ; U.RLH = U.CNT+02 ; UCB READ LIST HEAD U.WLH = U.CNT+06 ; UCB WRITE LIST HEAD ; BYTE: .WORD 0 ; BYTES TRANSFERED LHD: .WORD 0 ; QUEUE LIST HEAD POINTER MCH: .WORD 0 ; MATCHING PACKET POINTER PKT: .WORD 0 ; QIO PACKET POINTER RWFLAG: .WORD 0 ; READ/ WRITE FLAG SCB: .WORD 0 ; STATUS CONTROL BLOCK POINTER TCB: .WORD 0 ; TASK CONTROL BLOCK POINTER UCB: .WORD 0 ; UNIT CONTROL BLOCK POINTER .PAGE ;+ ; TO INITIATE-ENTRY ; . ; . REPEAT WHILE (QIO PACKETS ARE AVAILIBLE FROM MB0: QUEUE) ; . . SELECT (CURRENT PACKET FUNCTION TYPE) ; . . . (IO.RVB) USE THE INTERNAL WRITE QUEUE TO MATCH PACKETS. ; . . . (IO.WVB) USE THE INTERNAL READ QUEUE TO MATCH PACKETS. ; . . ...FIN ; . . LOCATE-MATCHING-PACKET ; . . WHEN (MATCH FOUND) TRANSFER-DATA ; . . ELSE TEST-FLAG-BITS ; . ...FIN ; . ; ...FIN ;- ; ; R5: UCB ADDRESS ; MBINI: ; INITIATOR ENTRY ; ; R1: QIO REQUEST PACKET (C-BIT CLEAR) ; R2: UCB UNIT # (C-BIT CLEAR) ; R3: CONTROLLER INDEX (C-BIT CLEAR) ; R4: SCB ADDRESS (C-BIT CLEAR) ; R5: UCB ADDRESS ; ; C: CLEAR = PACKET AVAILIBLE ; C: SET = PACKET NOT AVAILIBLE ; JSR PC,$GTPKT ; GET NEXT QIO PACKET BCS 4$ ; NO PACKET? MOV R1,PKT ; SAVE PACKET ADDRESS CMPB I.FCN+1(R1),#IO.RVB/256. ; TEST I/O FUNCTION BNE 1$ ; WRITE FUNCTION? CLR RWFLAG ; READ FUNCTION. BR 2$ ; 1$: MOV #2,RWFLAG ; WRITE FUNCTION. 2$: JSR PC,LOCATE ; LOCATE MATCHING PACKET BCS 3$ ; NO MATCH? JSR PC,XFER ; TRANSFER DATA BR MBINI ; GET ANOTHER PACKET 3$: JSR PC,TEST ; TEST FLAG BITS BR MBINI ; GET ANOTHER PACKET 4$: RTS PC ; DONE. .PAGE ;+ ; TO CANCEL-ENTRY ; . ; . ERROR = IE.ABO, REQUEST TERMINATED. ; . BYTES = 0 ; . REPEAT UNTIL (MB0:, READ AND WRITE QUEUES EXAUSTED) ; . . IF (SUPPLIED TCB = PACKET TCB) FLUSH PACKET ; . ...FIN ; . ; ...FIN ;_ ; ; R0: ACTIVE I/O PACKET ADDRESS ; R1: TCB ADDRESS OF CURRENT TASK ; R3: CONTROLLER INDEX ; R4: SCB ADDRESS ; R5: UCB ADDRESS ; MBCAN: ; CANCEL I/O ENTRY MOV SCB,R4 ; SCB POINTER MOV UCB,R5 ; UCB POINTER MOV R1,TCB ; TASK CONTROL BLOCK POINTER ; MOV SCB,R3 ; LIST HEAD POINTER (SCB) ADD #S.LHD,R3 JSR PC,1$ ; MOV UCB,R3 ; LIST HEAD POINTER (READ QUEUE) ADD #U.RLH,R3 JSR PC,1$ MOV UCB,R3 ; LIST HEAD POINTER (WRITE QUEUE) ADD #U.WLH,R3 JSR PC,1$ RTS PC ; DONE. ; 1$: MOV R3,LHD ; SAVE LIST HEAD 2$: MOV R3,R2 ; SAVE PREVIOUS PACKET POINTER MOV (R3),R3 ; NEXT PACKET POINTER BEQ 4$ ; NO MORE PACKETS? CMP TCB,I.TCB(R3) ; MATCHING TCB POINTERS? BNE 2$ ; NO MATCH MOV @I.LNK(R2),I.LNK(R2); BREAK QUEUE LINK BNE 3$ ; NOT END OF QUEUE? MOV LHD,R4 ; LIST HEAD POINTER MOV R2,2(R4) ; REDEFINE LIST HEAD 3$: MOV R2,-(SP) ; SAVE "PREVIOUS" PACKET POINTER MOV #IE.ABO&377,R0 ; REQUEST TERMINATED CODE CLR R1 ; ZERO BYTES TRANSFERED CLR R2 ; RETRY COUNT FOR ERROR LOGGER MOV SCB,R4 ; SCB POINTER MOVB #1,S.STS(R4) ; SET SCB BUSY MOV R3,S.PKT(R4) ; SET I/O PACKET POINTER JSR PC,$IODON ; ELIMINATE PACKET MOV (SP)+,R3 ; RESTORE "PREVIOUS" PACKET AS "CURRENT" BR 2$ ; LOOP 4$: RTS PC ; DONE. .PAGE ;+ ; TO TIMEOUT-ENTRY ; . ; ...FIN ;- ; ; R0: IE.DNR, DEVICE NOT READY ; R2: DEVICE CSR ; R3: CONTROLLER INDEX ; R4: SCB ADDRESS ; R5: UCB ADDRESS ; MBOUT: ; TIME OUT ENTRY RTS PC ; DONE. .PAGE ;+ ; TO POWER-FAIL-ENTRY ; . ; . INITIALIZE INTERNAL DATA STRUCTURES ; . ; ...FIN ;- ; ; R3: CONTROLLER INDEX ; R4: SCB ADDRESS ; R5: UCB ADDRESS ; MBPWF: ; POWER FAIL ENTRY MOV R4,SCB ; SCB ADDRESS MOV R5,UCB ; UCB ADDRESS ; MOV SCB,R3 ; LIST HEAD POINTER (SCB) ADD #S.LHD,R3 JSR PC,1$ MOV UCB,R3 ; LIST HEAD POINTER (READ QUEUE) ADD #U.RLH,R3 JSR PC,1$ MOV UCB,R3 ; LIST HEAD POINTER (WRITE QUEUE) ADD #U.WLH,R3 JSR PC,1$ ; MOV SCB,R4 ; RECONSTRUCT LIST HEADS CLR S.LHD(R4) MOV SCB,S.LHD+2(R4) ADD #S.LHD,S.LHD+2(R4) CLR U.RLH(R5) MOV UCB,U.RLH+2(R5) ADD #U.RLH,U.RLH+2(R5) CLR U.WLH(R5) MOV UCB,U.WLH+2(R5) ADD #U.WLH,U.WLH+2(R5) RTS PC ; DONE. ; 1$: MOV (R3),R3 ; NEXT PACKET POINTER BEQ 2$ ; END OF QUEUE MOV #IE.ABO&377,R0 ; REQUEST TERMINATED CODE CLR R1 ; BYTES TRANSFERED CLR R2 ; RETRY COUNT FOR ERROR LOGGING MOV SCB,R4 ; SCB POINTER MOVB #1,S.STS(R4) ; SET SCB BUSY MOV R3,S.PKT(R4) ; I/O PACKET POINTER MOV R3,-(SP) ; SAVE "PACKET" POINTER JSR PC,$IODON ; ELIMINATE PACKET MOV (SP)+,R3 ; RESTORE "PACKET" POINTER BR 1$ ; LOOP 2$: RTS PC ; DONE. .PAGE ;+ ; TO INTERRUPT-ENTRY ; . ; ...FIN ;- $MBINI:: ; INTERRUPT ENTRY RTS PC ; DONE. .PAGE ;+ ; TO LOCATE-MATCHING-PACKET ; . ; . COMPARISONS ARE BETWEEN THE CURRENT I/O PACKET ; . AND THE TEST I/O PACKET FOUND IN THE TEST QUEUE. ; . THERE ARE FOUR NAMES TO BE COMPARED BETWEEN THE ; . CURRENT AND TEST PACKETS. TWO IN THE PACKETS ; . AND TWO IN THE TASK CONTROL BLOCKS (TCB). ; . FOR SIMPLICITY: ; . READ TARGET = READ PACKET TARGET TASK NAME ; . READ NAME = READ PACKET TCB NAME ; . WRITE TARGET = WRITE PACKET TARGET TASK NAME ; . WRITE NAME = WRITE PACKET TCB NAME ; . ; . REPEAT UNTIL (END OF TEST QUEUE OR MATCH FOUND) ; . . WHEN (READ TARGET NON-ZERO) ; . . . WHEN (READ TARGET = WRITE NAME) ; . . . . TEST-READ-NAME ; . . . ...FIN ; . . . ELSE ; . . . . IF (READ TARGET = MCR COMMAND) ; . . . . . IF (READ TARGET(2) = WRITE NAME(1)) ; . . . . . . TEST-READ-NAME ; . . . . . ...FIN ; . . . . ...FIN ; . . . ...FIN ; . . ...FIN ; . . ELSE ; . . . TEST-READ-NAME ; . . ...FIN ; . ...FIN ; . ; ...FIN ; ; TO TEST-READ-NAME ; . WHEN (READ NAME = WRITE TARGET) ; . . TEST-TERMINAL-VALUES ; . ...FIN ; . ELSE ; . . IF (WRITE TARGET = MCR COMMAND) ; . . . IF (WRITE TARGET(2) = READ NAME(1)) ; . . . . TEST-TERMINAL-VALUES ; . . . ...FIN ; . . ...FIN ; . ...FIN ; ...FIN ; ; TO TEST-TERMINAL-VALUES ; . WHEN (TI:'S MATCH) PACKETS MATCHED ; . ELSE ; . . IF (A NON-SPECIFIC TI:) PACKETS MATCHED ; . ...FIN ; ...FIN ;- .PAGE MCR: .RAD50 /.../ LOCATE: ; ; PRIME REGISTERS ; TST RWFLAG ; CURRENT PACKET READ/WRITE? BNE 2$ MOV U.WLH(R5),R1 ; PRIME QUEUE LIST HEAD (WRITE) BNE 1$ ; NON-ZERO LIST HEAD? SEC ; SET ERROR FLAG RTS PC ; DONE. 1$: MOV PKT,R3 ; PRIME PACKET ADDRESS (READ) BR 4$ 2$: MOV U.RLH(R5),R3 ; PRIME QUEUE LIST HEAD (READ) BNE 3$ ; NON-ZERO LIST HEAD? SEC ; SET ERROR FLAG RTS PC ; DONE 3$: MOV PKT,R1 ; PRIME PACKET ADDRESS (WRITE) 4$: MOV I.TCB(R1),R2 ; PRIME TCB (WRITE) MOV I.TCB(R3),R4 ; PRIME TCB (READ) ; ; COMPARE READ TARGET TO WRITE NAME ; 5$: TST I.NAM(R3) BEQ 8$ CMP I.NAM(R3),T.NAM(R2) BNE 6$ CMP I.NAM+2(R3),T.NAM+2(R2) BNE 6$ JSR PC,16$ BR 9$ 6$: CMP I.NAM(R3),MCR BNE 7$ CMP I.NAM+2(R3),T.NAM(R2) BNE 7$ JSR PC,16$ BR 9$ 7$: SEC ; SET ERROR FLAG BR 9$ 8$: JSR PC,16$ ; ; UPDATE REGISTERS ; 9$: BCC 13$ ; MATCH FOUND? TST RWFLAG ; CURRENT PACKET READ/WRITE? BNE 11$ MOV (R1),R1 ; UPDATE WRITE PACKET POINTER BNE 10$ ; NOT END OF QUEUE? SEC ; SET ERROR FLAG RTS PC 10$: MOV I.TCB(R1),R2 ; UPDATE WRITE TCB POINTER BR 5$ 11$: MOV (R3),R3 ; UPDATE READ PACKET POINTER BNE 12$ ; NOT END OF QUEUE? SEC ; SET ERROR FLAG RTS PC 12$: MOV I.TCB(R3),R4 ; UPDATE READ TCB POINTER BR 5$ ; CONTINUE. 13$: TST RWFLAG ; CURRENT PACKET READ/WRITE? BNE 14$ MOV R1,MCH ; SAVE MATCHING PACKET POINTER BR 15$ 14$: MOV R3,MCH ; SAVE MATCHING PACKET POINTER 15$: CLC ; CLEAR ERROR FLAG RTS PC ; DONE. ; ; COMPARE WRITE TARGET TO READ NAME ; 16$: CMP I.NAM(R1),T.NAM(R4) BNE 17$ CMP I.NAM+2(R1),T.NAM+2(R4) BNE 17$ JSR PC,19$ RTS PC 17$: CMP I.NAM(R1),MCR BNE 18$ CMP I.NAM+2(R1),T.NAM(R4) BNE 18$ JSR PC,19$ RTS PC 18$: SEC ; SET ERROR FLAG RTS PC ; ; COMPARE TI: VALUES ; 19$: TSTB I.TTN(R1) BEQ 20$ TST I.TTN(R3) BNE 21$ 20$: CLC ; CLEAR ERROR FLAG RTS PC 21$: CMPB I.TTN(R1),I.TTN(R3) BNE 22$ CLC ; CLEAR ERROR FLAG RTS PC 22$: SEC ; SET ERROR FLAG RTS PC .PAGE ;+ ; TO TRANSFER-DATA ; . ; . COMPARE READ/WRITE BYTE COUNTS REQUESTED/AVAILIBLE. ; . USE SMALLEST VALUE. ; . LOAD APPROPROATE BUFFER ADDRESSES. ; . CALL BLXIO ; . ERROR = IS.SUC. ; . BYTES = TRANSFER COUNT. ; . FLUSH CURRENT PACKET. ; . FLUSH MATCHED PACKET. ; . ; ...FIN ;- OFFSET= 4096. ; OFFSET INCREMENT LEFT: .WORD 0 ; BYTES LEFT TO TRANSFER SIZE: .WORD 0 ; BYTE SIZE TO TRANSFER XFER: CMP I.CNT(R1),I.CNT(R3) ; CHOOSE LOWEST BYTE COUNT BGT 1$ MOV I.CNT(R1),BYTE ; SAVE COUNT BR 2$ 1$: MOV I.CNT(R3),BYTE ; SAVE COUNT 2$: CMP BYTE,#OFFSET ; MORE THAN ONE APR? BLE 3$ MOV #OFFSET,SIZE ; DEFINE SIZE (1 APR) BR 4$ 3$: MOV BYTE,SIZE ; DEFINE SIZE (ALL) 4$: MOV BYTE,LEFT ; DEFINE BYTES LEFT MOV SIZE,R0 ; SETUP REGISTERS FOR $BLXIO MOV I.BUFO(R1),R2 MOV I.BUFB(R1),R1 BIC #160000,R2 BIS #120000,R2 MOV I.BUFO(R3),R4 MOV I.BUFB(R3),R3 5$: JSR PC,$BLXIO SUB SIZE,LEFT ; REDUCE # OF BYTES LEFT BLE 7$ CMP LEFT,SIZE ; LAST CHUNK LESS THAN 1 APR? BGE 6$ MOV LEFT,SIZE ; JUST LAST CHUNK. 6$: MOV SIZE,R0 ; RESET REGISTERS ADD #OFFSET/64.,R1 SUB #OFFSET,R2 ADD #OFFSET/64.,R3 SUB #OFFSET,R4 BR 5$ ; LOOP AGAIN 7$: MOV #IS.SUC&377,R0 ; SUCCESS CODE MOV BYTE,R1 ; BYTES TRANSFERED CLR R2 ; RETRY COUNT FOR ERROR LOGGING JSR PC,$IODON ; MOV SCB,R4 ; PRIME REGISTERS TO DEQUE "MATCH" MOV MCH,S.PKT(R4) ; SET "MATCH" TO CURRENT PACKET CLRB S.STS(R4) ; SET SCB IDLE TST RWFLAG ; CURRENT PACKET READ/WRITE? BNE 8$ MOV UCB,R2 ; USER WRITE QUEUE ADD #U.WLH,R2 BR 9$ 8$: MOV UCB,R2 ; USE READ QUEUE ADD #U.RLH,R2 9$: MOV R2,R3 ; SAVE LIST HEAD 10$: CMP MCH,I.LNK(R3) ; CURRENT POINTER MATCHED? BNE 11$ MOV @I.LNK(R3),I.LNK(R3); BREAK QUEUE LINK BNE 12$ ; NOT END OF QUEUE MOV R3,2(R2) ; REDEFINE LIST HEAD BR 12$ 11$: MOV (R3),R3 ; MORE PACKETS? BEQ 12$ BR 10$ 12$: MOV #IS.SUC&377,R0 ; SUCCESS CODE MOV BYTE,R1 ; BYTES TRANSFERED CLR R2 ; RETRY COUNT FOR ERROR LOGGING JSR PC,$IODON RTS PC ; DONE. .PAGE ;+ ; TO TEST-FLAG-BITS ; . ; . IF (TARGET TASK COMPLIMENTRY QIO FLAG SET) ; . . ERROR = IE.DNR, DEVICE NOT READY. ; . . FLUSH CURRENT QIO PACKET. ; . ...FIN ; . IF (NO ERROR) ; . . IF (TARGET TASK INSTALLED FLAG SET) ; . . . SCAN TCB'S FOR TARGET TASK NAME. ; . . . IF (TARGET TASK NOT INSTALLED) ; . . . . ERROR = IE.NST, TARGET TASK NOT INSTALLED. ; . . . . FLUSH CURRENT QIO PACKET. ; . . . ...FIN ; . . ...FIN ; . ...FIN ; . IF (NO ERROR) ; . . REMOVE I/O PACKET FROM MB0: PACKET QUEUE. ; . . APPEND TO APPROPRIATE READ/WRITE INTERNAL QUEUE. ; . ...FIN ; . ; ...FIN ;- TEST: CLC ; CLEAR ERROR FLAG MOV PKT,R3 ; PRIME PACKET POINTER BITB #I$QIO,I.QIO(R3) ; TARGET TASK COMPLIMENTRY QIO? BEQ 1$ MOV #IE.DNR&377,R0 ; DEVICE NOT READY CODE CLR R1 ; BYTES TRANSFERED JSR PC,$IODON SEC ; SET ERROR FLAG BR 2$ 1$: BITB #I$INS,I.QIO(R3) ; TARGET TASK INSTALLED? BEQ 2$ ADD #I.NAM,R3 ; TARGET TASK NAME JSR PC,$SRSTD ; SCAN TASK CONTROL BLOCKS BCC 2$ ; TASK INSTALLED? MOV #IE.NST&377,R0 ; TASK NOT INSTALLED CODE CLR R1 ; BYTES TRANSFERED JSR PC,$IODON SEC ; SET ERROR FLAG 2$: BCS 5$ ; ERROR FLAG SET? MOV PKT,R0 ; PACKET POINTER TST RWFLAG ; CURRENT PACKET READ/WRITE? BNE 3$ MOV UCB,R1 ; LIST HEAD (READ QUEUE) ADD #U.RLH,R1 BR 4$ 3$: MOV UCB,R1 ; LIST HEAD (WRITE QUEUE) ADD #U.WLH,R1 4$: CLR I.LNK(R0) ; ZERO FORWARD POINTER MOV R0,@2(R1) ; APPEND PACKET TO QUEUE MOV R0,2(R1) ; IDENTIFY AS LAST PACKET MOV SCB,R4 ; SCB POINTER CLRB S.STS(R4) ; SET SCB IDLE 5$: RTS PC ; DONE .PAGE ;+ ; DEVICE DISPATCH TABLE ;- LD$MB==0 ; LOADABLE DRIVER $MBTBL:: .WORD MBINI ; DEVICE INITIATIOR ENTRY POINT .WORD MBCAN ; DEVICE CANCEL I/O ENTRY POINT .WORD MBOUT ; DEVICE TIMEOUT ENTRY POINT .WORD MBPWF ; DEVICE POWERFAIL ENTRY POINT .PAGE ;+ ; DEVICE CONTROL BLOCK (DCB) ;- $MBDAT:: ; START OF TABLES ; FOR LOADABLE DRIVERS MBDCB: .WORD 0 ;D.LNK ; LINK TO NEXT DCB ; ZERO FOR LOADABLE DRIVERS .WORD MBUCB0 ;D.UCB ; LINK TO 1'ST UCB .ASCII /MB/ ;D.NAM ; GENERIC DEVICE NAME .BYTE 0 ;D.UNIT ; LOWEST UNIT # .BYTE 0 ; HIGHEST UNIT # .WORD UCBHI-UCBLO ;D.UCBL ; LENGTN OF UCB .WORD 0 ;D.DSP ; ADDRESS OF DISPATCH TABLE ; ZERO FOR LOADABLE DRIVERS .WORD 000001 ;D.MSK ; LEGAL FUNCTION'S (0-15.) ; IO.KIL: KILL I/O .WORD 000000 ; CONTROL FUNCTION'S (0-15.) .WORD 000000 ; N0-OP'ED FUNCTION'S (0-15.) .WORD 000000 ; ACP FUNCTION'S (0-15.) .WORD 000006 ; LEGAL FUNCTION'S (16.-31.) ; IO.RVB: READ VIRTUAL ; IO.WVB: WRITE VIRTUAL .WORD 000000 ; CONTROL FUNCTION'S (16.-31.) .WORD 000000 ; NO-OP'ED FUNCTION'S (16.-31.) .WORD 000000 ; ACP FUNCTION'S (16.-31.) .WORD 0 ;D.PCB ; ADDRESS OF PARTITION CONTROL BLK .PAGE ;+ ; UNIT CONTROL BLOCK (UCB) ZERO ;- UCBLO=. ; START OF UCB .WORD 0 ;U.OWN ; OWNING TERMINAL UCB ADDRESS MBUCB0: .WORD MBDCB ;U.DCB ; BACK POINTER TO DCB .WORD .-2 ;U.RED ; REDIRECT UCB POINTER ;U.CTL ; CONTROL FLAGS .BYTE UC.LGH&1+UC.ALG!UC.KIL!UC.PWF ; WORD ALIGNED TRANSFERS ; WORD ALIGNED BUFFERS ; UNCONDITIONAL CALL TO MBCAN ; UNCONDITIONAL CALL TO MBPWF .BYTE 0 ; U.STS ; UNIT STATUS .BYTE 0 ; U.UNIT; PHYSICAL UNIT # .BYTE US.RED!US.PUB ; U.ST2 ; UNIT STATUS ; NO REDIRECTION ; PUBLIC DEVICE .WORD 0 ; U.CW1 ; CHARACTERISTICS WORD #1 .WORD 0 ; U.CW2 ; CHARACTERISTICS WORD #2 .WORD 0 ; U.CW3 ; CHARACTERISTICS WORD #3 .WORD 32767.-64. ; U.CW4 ; CHARACTERISTICS WORD #4 ; DEFAULT BUFFER SIZE .WORD SCB0 ; U.SCB ; POINTER TO SCB .WORD 0 ; U.ATT ; ICB ADDRESS OF ATTACHED TASK .WORD 0 ; U.BUF ; BUFFER RELOCATION BIAS .WORD 0 ; +2 ; BUFFER ADDRESS .WORD 0 ; U.CNT ; BYTE COUNT ; DEVICE SPECIFIC DATA .WORD 0 ; U.RLH ; READ PACKET LIST HEAD .WORD 0 ; +2 ; .WORD 0 ; U.WLH ; WRITE PACKET LIST HEAD .WORD 0 ; +2 ; UCBHI=. .PAGE ;+ ; STATUS CONTROL BLOCK (SCB) ZERO ;- SCB0: .WORD 0 ; S.LHD ; I/O QUEUE LIST HEAD .WORD .-2 ; .BYTE PR0 ; S.PRI ; DEVICE PRIORITY .BYTE 0 ; S.VCT ; INTERRUPT VECTOR/4 ; PSEUDO DEVICE .BYTE 0 ; S.CTM ; CURRENT TIMEOUT COUNT .BYTE 0 ; S.ITM ; INITIAL TIMEOUT COUNT .BYTE 0 ; S.CON ; (CONTROLER INDEX)*2 .BYTE 0 ; S.STS ; CONTROLER STATUS .WORD 0 ; S.CSR ; ADDRESS OF CSR .WORD 0 ; S.PKT ; ADDRESS OF CURRENT I/O PACKET .WORD 0 ; S.FRK ; FORK LINK WORD .WORD 0 ; FORK PC .WORD 0 ; FORK R5 .WORD 0 ; FORK R4 .WORD 0 ; RELOCATION BIAS OF DRV PARTITION ; FOR LOADABLE DRIVERS $MBEND:: ; END OF TABLES .END