.TITLE UCB .IDENT /101183/ ;************************************************************************ ; ; Program to print out terminal UCB's ; ; Dept: DPG ; Date: 04-OCT-83 ; Author: Peter V. DeVita ; ; Modified ; -------- ; ; 11-OCT-83 PVD Add terminal UCB extension mapping. ; ;************************************************************************ .ENABL LC .NLIST BEX .NLIST ME .MCALL EXIT$S,QIOW$S,DIR$,EXST$S,GMCR$,SWSTK$ .MCALL DCBDF$,SCBDF$,UCBDF$ DCBDF$ ; Get Device Control Block offsets SCBDF$ ; Get Status Control Block offsets UCBDF$ ; Get Unit Control Block offsets .PAGE .SBTTL Local Macros .MACRO MSG NUM,MESSAGE MSG'NUM: .ASCII <15><12>"MESSAGE"<15><12> MSGL'NUM=.-MSG'NUM .EVEN .ENDM .MACRO PRINT MSGNUM QIOW$S #IO.WVB,#5,#1,,,,<#MSG'MSGNUM,#MSGL'MSGNUM> .ENDM .MACRO ASCMSG LINMSG .ASCII \LINMSG\<15><12> .ENDM .PAGE .SBTTL MAIN - Code Section ;+ ; This is the main program control loop. ; ;- START: CLRB MCRBUF ; Assume nothing typed on MCR command line CALL GETCMD ; Get MCR command line CALL PARCMD ; Parse the command line for UCB CALL FNDUCB ; Find UCB CALL CPYUCB ; Copy the UCB to local storage CALL PRTUCB ; Print out the UCB CALLR EXIT ; Otherwise print only once and exit .PAGE .SBTTL GETCMD -- Get MCR Command. ;+ ; ; Get the MCR command line typed. ; ; INPUT ; None. ; ; OUTPUT ; MCRBUF = Start of Typed MCR command or command prompted for. ;- GETCMD: TST MCRFLG ; First time through ? BNE 4$ ; BR if no DIR$ #MCRDPB ; Get MCR command line MOV $DSW,R1 ; Char counter BLT 2$ ; Failed TSTB MCRBUF ; Character in buffer ? BNE 3$ ; BR if yes 4$: QIOW$S #IO.RPR,#5,#1,,#IOSB,,<#MCRBUF,#6,,#UCBPMT,#PMTSIZ,#44> CMPB $DSW,#IS.SUC ; Success ? BEQ 1$ ; BR if yes 2$: PRINT 1 ; Read failed CALLR EXIT ; 1$: INC MCRFLG ; Say we had to prompt for command line 3$: RETURN .SBTTL PARCMD -- Parse Command. ;+ ; ; Parse the MCR command line for device name and unit number. ; Examples: ; ddnn: or dd: ; ; INPUT ; MCRBUF = MCR command line. ; ; OUTPUT ; UNAM = Device name in ASCII. ; UNUM = Device number in octal. ;- PARCMD: MOV #MCRBUF,R0 ; Input buffer MOV (R0),UNAM ; Save unit name MOVB #-1,UNUM ; Say we want all units ADD #2,R0 ; Point past unit name 1$: CMPB #':,(R0) ; Find terminator BEQ 2$ ; If = then end of line CALL $COTB ; Convert ASCII octal to binary CMPB #':,R2 ; Conversion complete ? BEQ 3$ ; BR if yes PRINT 1 ; Syntax error TST MCRFLG ; Prompt mode ? BEQ 4$ ; BR if no CALLR START ; Try again 4$: CALL EXIT ; Exit 3$: MOVB R1,UNUM ; Save the octal unit number 2$: RETURN .PAGE .SBTTL FNDUCB -- Find UCB. ;+ ; ; Find the desired UCB. ; ; INPUT ; UNAM = Device name in ASCII. ; UNUM = Device number in octal. ; ; OUTPUT ; CURUCB = UCB address of desired device. ; ;- FNDUCB: CMPB #-1,UNUM ; Print all UCB's BEQ 20$ ; Can't do that yet! (next release) MOV $DEVHD,R0 ; Head of system device list MOV UNAM,R1 ; Unit we want 1$: TST R0 ; End of DCB list BEQ 20$ ; Yes CMP D.NAM(R0),R1 ; Is this the device we want BEQ 10$ ; Yes MOV (R0),R0 ; Link through DCB listhead BR 1$ ; Continue ; ; At this point we have the device type in the system. ; 10$: CMPB UNUM,D.UNIT(R0) ; Test low unit range for this DCB BLT 30$ ; CMPB UNUM,D.UNIT+1(R0); Test high unit range for this DCB BGT 30$ ; MOV D.UCB(R0),R2 ; Save first UCB MOV D.UCBL(R0),UCBL ; Save UCB length 12$: TST R2 ; End of UCB list BEQ 20$ ; Yes CMPB UNUM,U.UNIT(R2) ; Is this the unit ? BEQ 15$ ; Yes ADD D.UCBL(R0),R2 ; Find next UCB BR 12$ ; Continue 15$: MOV R2,CURUCB ; Save the UCB address RETURN ; And return 20$: PRINT 2 ; Device not in system CALLR EXIT ; Exit 30$: MOV D.LNK(R0),R0 ; Link to next DCB BEQ 20$ ; BR if end of DCB chain BR 10$ ; Continue .SBTTL CPYUCB -- Copy UCB to local storage. ;+ ; ; Copy the current UCB to loacl storage. ; ; INPUT ; CURUCB = UCB address of desired device. ; ; OUTPUT ; UCBSAV = Starting address of local copy of desired UCB. ;- CPYUCB: MOV CURUCB,R0 ; Address of actual UCB MOV #UCBSAV,R1 ; Address of UCB save area MOV UCBL,R2 ; Current UCB length 1$: MOVB (R0)+,(R1)+ ; Move it SOB R2,1$ ; " CMP #"TT,UNAM ; Is this a terminal UCB BNE 3$ ; BR is no SWSTK$ 3$ ; Switch to system stack MTPS #PR7 ;;; Lock out interrupts MOV KDSAR6,-(SP) ;;; Save old kernel APR 6 MOV CURUCB,R0 ;;; Get UCB pointer MOV U.TUX(R0),KDSAR6 ;;; Map to UCB extension in data space MOV #140000,R1 ;;; Start of APR 6 MOV #UCBSAV,R2 ;;; Address of UCB save area ADD UCBL,R2 ;;; Current UCB length INC R2 ;;; OM... plus 2 MOV #T$$UXL,R3 ;;; Current UCB extension length 2$: MOVB (R1)+,(R2)+ ;;; Copy terminal UCB SOB R3,2$ ;;; ... MOV (SP)+,KDSAR6 ;;; Restore old APR 6 mapping MTPS #0 ;;; Lower priority RETURN ;;; From system stack 3$: RETURN ; Done .SBTTL PRTUCB -- Format and print the UCB. ;+ ; Format and print the desired UCB. ; ; INPUT ; UCBSAV = Starting address of local copy of desired UCB. ; ; OUTPUT ; Print the formatted UCB on the TI:. ;- PRTUCB: MOV #OUT,R0 ; Output buffer MOV #IN,R1 ; Input buffer MOV #CURUCB,R2 ; Binary arguments to convert CALL $EDMSG ; Convert it ! QIOW$S #IO.WVB,#5,#1,,,,<#OUT,#OUTLEN> ; Print it RETURN EXIT: EXST$S R3 ; Exit status is 40 on error .PAGE .SBTTL Local Variables. UNAM: .WORD 0 ; Will get two ASCII characters UNUM: .BYTE 0 ; Will get the octal unit number .EVEN MCRDPB: GMCR$ MCRBUF= MCRDPB+G.MCRB+4 ; Ptr to number after UCB IOSB: .BLKW 2 .SBTTL Task error messages. MSG 1, MSG 2, MSG 3, .EVEN MCRFLG: .WORD 0 ; MCR command received flag. UCBPMT: .ASCII <15>/UCB> / ; UCB prompt string. PMTSIZ=.-UCBPMT ; UCB prompt size. .EVEN UCBL: .WORD 0 ; Current UCB length CURUCB: .WORD 0 ; Current UCB UCBSAV: .BLKB 256. ; Storage for UCB .EVEN IN: ASCMSG < > ASCMSG < > ASCMSG ASCMSG < > ASCMSG <%P U.DCB ; Back pointer to DCB> ASCMSG <%P U.RED ; Pointer to redirect unit UCB> ASCMSG <%P U.CTL ; Control pocessing flags> ASCMSG < U.STS ; Unit status> ASCMSG <%P U.UNIT ; Physical unit number> ASCMSG < U.ST2 ; Unit status extension> ASCMSG <%P U.CW1 ; First device characteristics word> ASCMSG <%P U.CW2 ; Second device characteristics word> ASCMSG <%P U.CW3 ; Third device characteristics word> ASCMSG <%P U.CW4 ; Fourth device characteristics word> ASCMSG <%P U.SCB ; Pointer to SCB> ASCMSG <%P U.ATT ; TCB address of attached task> ASCMSG <%P U.TUX ; Pointer to UCB extension (UCBX)> ASCMSG <%P U.TSTA ; Status Triple word> ASCMSG <%P> ASCMSG <%P> ASCMSG <%P> ASCMSG <%P U.TTAB ; If 0: U.TTAB+1 is single-character type ahead> ASCMSG < ; buffer, currently empty> ASCMSG < ; If ODD: U.TTAB+1 is single-character> ASCMSG < ; type-ahead buffer and holds a character> ASCMSG < ; If NON-0 and EVEN: pointer to multi-character> ASCMSG < ; type-ahead buffer> ASCMSG <%P U.TLPP ; Lines per page> ASCMSG < U.FRQ ; Fork request byte> ASCMSG <%P U.FLK ; Fork list link word> ASCMSG <%P U.TCHP ; Current horizontal position> ASCMSG < U.TCVP ; Current vertical position> ASCMSG <%P U.UIC ; Terminal UIC> ASCMSG <%P U.TTYP ; Terminal type> ASCMSG < U.TMTI ; Modem timer> ASCMSG <%P U.CTYP ; Controller type> ASCMSG <%P U.ACB ; Ancillary control driver block addr> ASCMSG <%P U.AFLG ; Ancillary control driver flags word> ASCMSG <%P U.ADMA ; Ancillary control driver DMA buffer> UCBX: ASCMSG <%P U.TCI ; If solicited input in progress:> ASCMSG < ; pointer to current input request packet> ASCMSG < ; If unsolicited input in progress:> ASCMSG < ; pointer to second word in first buffer> ASCMSG < ; If input idle:> ASCMSG < ; 0> ASCMSG <%P U.TIP ; If buffered input in progress:> ASCMSG <%P ; first word = pointer to current buffer> ASCMSG < ; second word = pointer to next byte> ASCMSG < ; in current buffer> ASCMSG < ; If non-buffered input in progress:> ASCMSG < ; first word = KISAR6 bias for task buffer> ASCMSG < ; second word = virtual address in KISAR6> ASCMSG < ; of next byte in task buffer> ASCMSG <%P U.TIC ; Remaining bytes in current input buffer> ASCMSG <%P U.TTIC ; Total remaining bytes to input> ASCMSG < ; (excluding current buffer)> ASCMSG <%P U.TFIB ; Pointer to first input buffer (only with> ASCMSG < ; buffered input)> ASCMSG <%P U.TCO ; If task output in progress:> ASCMSG < ; pointer to current output request packet> ASCMSG < ; If echo in progress, or output idle:> ASCMSG < ; 0> ASCMSG <%P U.TOP ; First word = pointer to current output buffer> ASCMSG <%P ; Second word = pointer to next byte in> ASCMSG < ; current output buffer> ASCMSG <%P U.TOC ; Remaining bytes in current output buffer> ASCMSG <%P U.TTOC ; Total remaining bytes to output> ASCMSG < ; (excluding current buffer)> ASCMSG <%P U.TFOB ; Pointer to first output buffer> ASCMSG <%P U.TFPB ; First prompt buffer for IO.RPR> ASCMSG <%P U.TAST ; Pointer to AST block> ASCMSG < ; 0 If no AST set up> ASCMSG <%P U.TISV ; Input state variable> ASCMSG < U.TIHP ; Initial horizontal position for input> ASCMSG <%P U.TECB ; Echo buffer> ASCMSG < U.TVFC ; Vertical format control> ASCMSG <%P U.TITI ; Timer> ASCMSG < U.TOTI ; Output timer> ASCMSG <%P U.TSHP ; Saved horizontal position> ASCMSG < U.TSVP ; Saved vertical position> ASCMSG <%P U.TRTT ; Special terminators table> ASCMSG <%P U.TDYP ; Offset in UCB extension for data type (byte)> .BYTE 0 ; This will end the $EDMSG function INLEN=.-IN OUT: .BLKB OUTLEN=.-OUT .END START