.Title AlvDisable Alvin Device Disable .Psect Alvin,Gbl,Con .Ident /LVL51C/ .Mcall $RTdef, $Alvin, .Purge, .Rctrlo, .Unprotect .Globl GetDDA $RTdef $Alvin ;+ ;;**************************************************************************** ;; AlvDisable - Subroutine to Disable an Alvin device. ;; Expects calls of the form: ;; Jsr PC,AlvDisable ; Disable the unit ;; < unit number is in Reg 3 > ;; ;; < Carry is clear if no error and set if there was an error.> ;; ;; Last modified: 11-Oct-85 DJ Added CL disable, RTctl TTspecial off, and ;; unprotected the vector. ;; 5-Nov-85 DJ cleared the Alvin vector slot for DI disable. ;; 25-Nov-85 DJ Corrected the purge of the channel number. Changed CL ;; support so that both possible logical units which may have ;; taken over a time-sharing line will attempt to detach from it. ;; (Only the last will succeed as a channel will still be ;; be open to it.) ;; DISABLE status is moved in rather than bit-set to remove any ;; possible remnant conflict bits. ;;**************************************************************************** ;- AlvDisable:: Mov R3,-(SP) ;Save Registers Used. Mov R2,-(SP) Jsr R5,GetDDA ; Check the device descriptor table .Word -1 ; for the unit in R3 for Dev Desc Address. Bcc Alvd20 ; Branch if the descriptor was found. Mov #-40,R0 ; No, return error code "UNIT OUT OF RANGE". Br AlvDnx ; (Carry is already set). Alvd20: Mov R0,R2 ; Put the descriptor in Register 2. Bit #Disable,(R2) ; Is it already disabled? Bne AlvDdone ; Yes, then let it go without an error. Mov Lctl(R2),R3 ; Get the logical control word. Mov #Disable,(R2) ; Set logical status to DISABLEd. Bit #RTCtl,R3 ; Is this the console? Beq AlvdCL ; No, branch. Bit #Output,R3 ; Is it the Input device? Bne AlvDdone ; No, then nothing more to do. Bic #TTspecial,@#RTjsw ; Yes, then turn off special input mode. .Rctrlo ; Get RT to acknowledge the JSW change. Br AlvDdone AlvdCL: Bit #CLctl,R3 ; Is this a TSX CL controlled device? Beq DIdisable ; No, it must be a Direct Interrupt device. .Purge Lunit(R2) ; Purge the channel to CL. Movb CLunit(R2),R0 ; Get the CL unit number Mov R0,Attunit ; Set for possible detach of unit from line. Add #^rCL0,R0 ; Generate the device to be deallocated. Mov R0,CLname ; Set the device name in the EMT block. Tstb TSXline(R2) ; Did we take over a time sharring line? Beq AlvDeallocate ; No, then check for deallocation. Clr Attline ; Yes, set line=0 to deatch. (initally zero) Mov #Attach,R0 ; Get the EMT block to R0. EMT 375 ; Detach CLx from the line. ; The detach will fail if another channel is still open to CLx. ; In such a case, it is important to have both devices defined to ; take over the time-sharing line, or they must be disabled in the ; reverse order in which they were enabled (the first one enabled ; must be the one which takes over the line). If both device ; descriptors (CLx input and output) define the TSX line, then the ; last one disabled will release the line for normal time sharing ; activity. AlvDeallocate: Cmpb TSXjob(R2),AllocJob(R2) ; Is this the device that allocated? Bne AlvDdone ; No, branch. ; This technique preserves allocations which may have occured outside ; the scope of this program, ie, done at DCL level prior to the ; invocation of this program. It does allow for the deallocation to ; occur prior to all channels being closed to CLx. (Again, the ; best rule is to disable in the reverse order that they were ; enabled.) The first logical unit to enable a CLx will own the ; allocation for CLx and will be the one which executes the ; deallocation when disabled. Mov #Dealloc,R0 ; EMT to R0. EMT 375 ; Deallocate it. Br AlvDdone ; (? should we detect errors?) DIdisable: Mov DevAdr(R2),R0 ; Get the Device CSR Address. Clr (R0)+ ; Disable interrupts. Tst (R0) ; Remove any pending interrupt. Mov Vector(R2),R0 ; Get the Vector address. Mov R0,-(SP) ; Push it for the unprotect. Mov (R0),R3 ; Get base adr of the Alvin intrpt element. Clr DDAstore(R3) ; Release the element. Mov PEntry(R2),(R0)+ ; Restore previous vector contents Mov PentPS(R2),(R0) ; - revert to state prior to AlvEnable. Mov PDStat(R2),@DevAdr(R2) ; Restore Device CSR contents. Clr -(SP) ; Push one more word on the stack for EMT blk. .Unprotect SP ; Do the Unprotect. Cmp (Sp)+,(Sp)+ ; Pop the EMT block from the stack. AlvDdone: Mov PDBadr(R2),BDefault(R2) ; Restore the Gen'ed default buffer. Clr R0 ;Return Code = 0 = OK, Carry clear. Alvdnx: Mov (SP)+,R2 ;Restore Registers Mov (SP)+,R3 Rts Pc ; Return to User. ;;******************************* DeAlloc: .Byte 1,156 ; TSX device DEALLOCATE EMT arg block. .Word CLname ; Pointer to CLx device name. CLname: .Rad50 'CL0' ; (unit number is filled in above) .Word 0,0,0 ; (the rest of the file spec must be zero) Attach: .Byte 0,155 ; Attach a CL unit to a line - EMT arg block. Attunit: .Word 0 ; CL unit number (filled in above). Attline: .Word 0 ; TSX line number (filled in above). ;;**************************************************************************** .END