(edited 19-Sep-91;1130) (****Version 1****) (This is old SSM Chapter 5) (Multiterminal Feature\MTT_CHAP)

In describing the multiterminal feature of RT--11 this chapter provides background information on the hardware and describes the data structures of a multiterminal system. It also describes the interrupt service and polling routines, the programmed requests available to application programs, and typical situations in which you can use two terminals without making use of the multiterminal special feature. An example program is provided at the end of the chapter.

(postscript\s560c5mtty_fig.eps\8) (Components of a Multiterminal System)

RT--11 implements support for multiple terminals as a special feature that you select during system generation. Essentially, the multiterminal feature permits an application program to control one or more terminals. It does not change RT--11's basic characteristic of being a single-user operating system. Specifically, multiterminal support does not permit more than one terminal at a time to be the command terminal, the terminal at which you communicate with RT--11 through DCL commands.

Support for multiple terminals is implemented through the following components: (UNNUMBERED) MTTEMT.MAC processes the multiterminal programmed requests. MTTINT.MAC contains the multiterminal interrupt service and polling routines. TRMTBL.MAC defines the multiterminal terminal control blocks.

MTTEMT, MTTINT, and TRMTBL assemble and link together as part of RMON for a multiterminal system.

There are also some important data structures and concepts in multiterminal systems: (UNNUMBERED) (Terminal control blocks), called TCBs (one per terminal), contain information about the terminal and controlling job. The TCBs also contain the input and output ring buffers for the terminal. (Logical unit numbers), called LUNs, through which RT--11 refers to the terminals that are part of your system. (Asynchronous terminal status words), called AST words (one per LUN), in which RT--11 maintains event flags to reflect the current status of each terminal. Support for AST words is a special feature you can select through system generation. The address of AST words are supplied to the system by the .MTATCH request and reside in the user program. (Terminal hooks), called THOOKS, is a data structure that contains addresses of RMON routines that pertain to the terminal support code. This data structure is created in RMON when you request the terminal hooks option. (Hardware Background Information\TTHARDINFO_SEC)

This section provides some background information that is useful if you are unfamiliar with the communication hardware RT--11 supports.

RT--11 supports the serial interfaces: DL series (including DL11 and DLVJ1, or compatible equivalent), the DH series (but not the DH11), and the entire DZ series. An interface is similar to a device controller; it stands between the computer and a serial line. The other end of the line can be connected to a terminal, a modem, or another computer.

The DL interface connects the computer system to a single serial line. Each DL interface has its own Control and Status Register (CSR) address and vector address. RT--11 supports up to eight DL interfaces on your computer system, including the hardware console interface. Since each DL interface is a separate controller, there is no real physical unit number; 0 is assigned for consistency. Note that even though the DLVJ1 module contains four serial lines, they appear to the software as four separate and distinct DL interfaces.

Each RT--11 system must have a hardware console interface so that the hardware can use it at bootstrap time to communicate with the console terminal. The hardware bootstrap on many systems requires that a terminal be connected at the standard console addresses for diagnostic purposes and for operator communication at bootstrap time. Your hardware console interface must be a local DL. Its interrupt vectors are located at 60 and 64 in low memory, and its LUN is always 0.

A DH or DZ interface is called a (multiplexer); it connects several serial lines through a single pair of CSR and vector addresses. (unnumbered) RT--11 supports up to two DH interfaces for a total of up to 16 serial line connections. At least one DL interface is required for the console terminal, for a permitted total of 17 lines. The DZ11 interface connects the computer system to eight lines that have physical unit numbers from 0 through 7. The DZV11 is similar to the DZ11, but it connects the system to only four lines that have physical unit numbers from 0 through 3. You can have two DZ11 or four DZV11 interfaces, for a total of 16 additional lines.

(DLDH_FIG) illustrates the interfaces and their physical and logical unit numbers.

(Interfaces and Physical and Logical Unit Numbers\DLDH_FIG) (POSTSCRIPT\S560C5DLDH_FIG.EPS\11)

During system generation, you specify how many DL, DH, and DZ interfaces your target system has. You also indicate how many of their physical units are actually connected to terminals on the system. Of those terminals, you must indicate which are local and which are remote lines. Unlike physical unit numbers, which are numbered starting at 0 for each interface, the logical unit numbers that RT--11 uses are unique. They begin at 0 and continue until all terminals have been accounted for.

SYSGEN assigns the physical unit numbers of the interfaces to its software logical unit numbers in the following order: (NUMBERED) Local DL lines (the hardware console interface is always LUN 0) Remote DL lines Local DZ lines Remote DZ lines Local DH lines Remote DH lines

The order in which SYSGEN assigns physical lines to logical unit numbers is also the order in which it generates the terminal control blocks. It generates one TCB for each line you specify in the SYSGEN dialogue. The TCBs are arranged in RMON in the order in which you specify the lines to SYSGEN. There are no TCBs for any unused interface physical lines.

Systems with a DLVJ1 interface have three additional DL interfaces at the standard addresses. Some systems have SLU (serial line unit) port numbers; the RT--11 logical unit number corresponding to a port is the SLU number plus 1.

When you bootstrap a multiterminal system, RT--11 checks for the presence of each interface for which a TCB exists by attempting to access its CSR, as specified in the SYSGEN dialogue. If the interface does not exist, the logical unit number associated with that interface is marked as nonexistent, and any attempt to attach such a LUN results in an error. The space occupied by the TCB of a nonexistent LUN is not recoverable. You can use the SHOW TERMINALS monitor command to verify that the information you supplied during system generation was correct.

Note that RT--11 does not attempt to determine whether or not a terminal or modem is actually connected to an interface line; it assumes the connection is present. For an unconnected line, no meaningful input characters can be generated; output directed to the line is sent out and lost. (What is the Console Terminal?\TTCONDEF_SEC)

A potentially confusing aspect of RT--11's multiterminal support is its ability to change the console terminal. This section defines precisely what is meant by the terms (hardware console interface), (boot-time console), (background console), and (private console). You will avoid confusion if you familiarize yourself with these terms and use them consistently.

The (hardware console interface), as (TTHARDINFO_SEC) describes, is the terminal interface located at vectors 60 and 64, whose control and status registers begin at 177560 in the I/O page. This is the serial line interface the hardware bootstrap uses at bootstrap time. (Generally, you must have a terminal connected to the hardware console interface in order to bootstrap the system.) This is almost always the terminal on which RT--11 prints its startup message. Remember that the hardware console interface is always LUN 0.

The (boot-time console )is the terminal on which RT--11 prints its startup message. This is almost always the same as the terminal connected to the hardware console interface. In a system without the multiterminal feature, the CSR for this terminal, 177560, is contained in $TTKS. ($TTKS is located at fixed offset 304 from the start of RMON.) In a multiterminal system, the CSR is located at offset T.CSR in the first TCB in RMON.

The (background console), also called the (command console), is originally the same as the boot-time console. (It remains the same until you use the SET TT: CONSOL command, described below, to move the background console.) It is the terminal on which you type commands to KMON, and through which you communicate with the background job. If you run a foreground job or system jobs, they can share the background console. In this case, you must use CTRL/B to communicate with the background job, CTRL/F for the foreground job, and CTRL/X for the system jobs. For example, to abort a job from a shared console, you must either type the appropriate CTRL sequence, followed by two CTRL/C characters, or use the DCL ABORT command. (See (rmon_chap) for more information on control sequences.)

The programmed requests .TTYIN, .TTYOUT, .CSIGEN, .CSISPC, .GTLIN, and .PRINT interact with the background console for the background job, and also for any foreground or system jobs that happen to be sharing this terminal. () RT--11 ignores any unit number you specify with device TT. Therefore, references to TT:, TT0:, TT1:, and so on, are all equivalent, and refer to the console of the job that issues the request.

In a multiterminal system you can move the background console to another terminal by issuing the SET TT: CONSOL monitor command. By specifying another logical unit number in the SET command, you can move the background console to any other local terminal in the system, except to a private console.

A (private console )is a local terminal used by a single foreground or system job. You give a job its own private console when you start the job by using the FRUN/TERMINAL:n or SRUN/TERMINAL:n commands. No other job can share a private console with the original job. A job's private console is the terminal with which its .TTYIN, .TTYOUT, .CSIGEN, .CSISPC, .GTLIN, and .PRINT programmed requests interact. In addition, any .READ or .WRITE requests to TT that this job makes access the private console. When a job has its own private console, you can no longer communicate with the job through the background console. Thus, you can no longer use CTRL/F at the background console, for example, to interact with a foreground job that has its own private console; instead, you must type on the private console. To abort this foreground job, you must type two CTRL/Cs on its private console or abort the job, using the DCL ABORT command from the background console. You cannot issue DCL commands from a private console.

You cannot change a private console to a different terminal by using the SET TT: CONSOL command; that command is valid only for the background console. This is because KMON runs as a background job, and it can run only on the background console.

A (shared console )refers to the background console unless the following conditions apply: (unNUMBERED) In a system without the system job feature, the foreground job is running with a private console; In a system with the system job feature, all six system jobs and the foreground job are running, and each has a private console.

Remember that a private console can never be shared.

A (console )simply refers to a terminal being used as the background shared console, or as a foreground or system job private console. (Connecting Handlers to Terminal Lines)

Through the SYSGEN procedure, you can build support for a monitor and handlers that lets each such handler connect to the port controller on a terminal line without regard for the interface to which it is ultimately connected. The multiterminal interrupt service manages the port controller. Such support is called (multiterminal handler hooks) and the (hooks) are the connection between the handler and the interrupt service.

Multiterminal handler hooks support is valid for DH, DL, and DZ controllers and all multiterminal monitors. For example, the distributed LS and XL handler source files can be built to make use of such support. Standard interface support and multiterminal handler hooks support can be included in the same handler. (s560c5hhook_fig) illustrates the multiterminal handler hooks connection.

(Multiterminal Handler Hooks Connection\s560c5hhook_fig) (postscript\s560c5hhook_fig.eps\36)

See the following sections for information on monitor support and a short discussion of such support in LS and XL. See the (dev_book) for more information on LS and XL and for information on including multiterminal handler support within your own handler. See the (syg_book) for SYSGEN dialogue questions that build this support in the monitor and handlers. (Monitor Support)

Support for the multiterminal handler hooks is built into a monitor when the system conditional, MTY$HK, is set to 1 (MTY$HK=1). That support places a pointer in RMON fixed offset 472, $THKPT, to the monitor handler hooks data structure, THOOKS. (If MTY$HK=0, $THKPT has a zero value.)

Further, when a handler built for such support is fetched or loaded, it writes values into the TCB for the terminal line it will use. The handler places the address of the handler hook routine entry point in T.OWNR (TCB offset 12) and sets HANMT$ (bit 3) in the T.STAT word (TCB offset 14). The handler must also ensure that the word before the handler hook routine entry point contains the RAD50 physical name of the handler.

The basic protocol between the monitor interrupt service and the device handler is as follows: (numbered) An interrupt occurs and the interrupt service routine in the multiterminal monitor is entered. If the line on which the interrupt occurred is not attached by a handler, the interrupt is processed normally. If the line on which the interrupt occurred is attached by a handler (HANMT$ is set in T.STAT), the interrupt service code passes control to the handler hook routine (using the address in T.OWNR).

R0 indicates the type of interrrupt and R5 is used to pass characters between the handler and the interrupt service code.

If the monitor is passing a character to the handler (an input interrupt), the monitor clears R0 (function code TH.PIC) and passes the character to the handler in R5. The handler processes the character, preserving all other registers, and returns.

If the monitor is requesting an output character from the handler because of an output interrupt, the monitor places the value 1 in R0 (function code TH.GOC) and calls the handler hook code, which returns a character in R5 with carry clear. If the handler cannot pass a character, it sets the carry bit and returns. All other registers are preserved across the call. When the monitor receives a character from a controller and the TCB for that LUN is attached to a handler: (numbered) The monitor interrupt service calls routine OUTCHR. OUTCHR calls the handler hook entry point (found in T.OWNR in that TCB). OUTCHR clears the low bit in R0 (function code TH.PIC) and passes the character to the handler in R5. The handler processes the character, preserves all registers, and returns. When the monitor receives an interrupt request and that LUN is attached to a handler (the handler called the MTOENB routine): (numbered) The monitor interrupt service calls routine INCHAR. INCHAR calls the handler hook entry point at T.OWNR with the low bit in R0 set (function code TH.GOC). INCHAR receives the character from the handler in R5 with the PSW carry bit clear.

If the handler has no character to output, it should return only PSW carry bit set. All registers are preserved across the call.

The monitor part of the protocol is described in the following sections. The handler part of the protocol is described in the (dev_book). In particular, see the XL handler section for information on an example handler hook routine, and the XL handler description in the Appendix. (Terminal Hooks Data Structure, THOOKS\mtty_han_hook_sec)

The terminal hooks data structure, THOOKS, is defined by the .THKDF macro in the system definition library, SYSTEM.MLB. THOOKS contains the number of TCBs in the system and pointers to monitor routines that process character input and output and manage serial lines for modem control: (Terminal Hooks Data Structure, THOOKS\thkdf_tab) (3\6\8) (Offset\Name\Contents) (00\THK.LE\Length (in bytes) of the data structure; for Version 5.6, THK.LE contains THK.SZ (14(8)). (A byte offset.)) (01\THK.NU\Number of TCBs in system (and therefore the number of possible LUNs). (A byte offset.)) (02\THK.TC\Pointer to list of pointers to TCBs. The first word points to the TCB for LUN 0, the second word points to the TCB for LUN 1, and so forth.) (04\THK.OE\Pointer MTOENB, the terminal output enable routine. See (MTOENB_sec).) (06\THK.BK\Pointer to MTYBRK, the terminal line BREAK routine. See (MTYBRK_sec).) (10\THK.CT\Pointer to MTYCTL, the terminal modem control routine. See (MTYCTL_sec).) (12\THK.ST\Pointer to MTYSTA, the terminal modem status routine. See (MTYSTA_sec).) (\THK.SZ\Length of the structure, stored in THK.LE (offset 00).) (Terminal Output Enable Routine, MTOENB\MTOENB_sec)

The handler calls MTOENB to inform the monitor that the handler has waiting output. The handler cannot initiate output but rather only responds to the monitor. The handler uses MTOENB to tell the monitor that it should enable output interrupts for the terminal line. The MTOENB offset calls the monitor's output interrupt routine, TTOENB.

MTOENB is called through offset 4 of the THOOKS data structure.

On entry to MTOENB:

(2\8) (Register\Contents) (R3\TCB address)

All registers are preserved across the call.

The following is sample code for the call: MOV TCBADX,R3 ; R3 -> TCB CALL @MTOENX ; Enable output interrupts TCBADX: .BLKW ; Points to TCB MTOENX: .BLKW ; Points to MTOENB in monitor (from ; THK.OE in THOOKS data structure)

The handler is entered asynchronously as the interface can accept output characters. (Terminal Line Break Routine, MTYBRK\MTYBRK_sec)

The handler calls MTYBRK to set or reset the BREAK signal on the specified serial line.

MTYBRK is called through offset 6(8) of the THOOKS data structure.

On entry to MTYBRK:

(2\8) (Register\Contents) (R0\Low bit indicates the desired BREAK signal status.

If low bit is clear, CLEAR the BREAK.

If low bit is set, SET the BREAK.) (R3\TCB address)

All registers are preserved across the call. BREAK$ = 000001 MOV #BREAK$,R0 ; Prepare to assert BREAK ; CLR R0 ; Prepare to deassert BREAK MOV TCBADX,R3 ; R3 -> TCB CALL @MTYBRX ; Set BREAK as desired TCBADX: .BLKW ; Points to TCB MTYBRX: .BLKW ; Points to MTYBRK in monitor ; (from THK.BK in THOOKS data ; structure) (Terminal Modem Control Routine, MTYCTL\mtyctl_sec)

The handler calls MTYCTL to set or reset certain EIA control signals on a particular serial port. Calling MTYCTL is appropriate only for ports for which REMOTE (modem) support has been specified during SYSGEN.

Set HANMC$ (bit 8) in the TCB T.STAT word before calling MTYCTL.

MTYCTL is called through offset 10(8) of the THOOKS data structure.

The following control signals can be set or reset on the specified controllers:

(3\10\10) (Controller\Signal\Bit Mask) (DL, DH, DZ\DTR\000002) (DL, DH\RTS\000004)

On entry to MTYCTL:

(2\8) (Register\Contents) (R0\Bit pattern (mask) to be set for line) (R3\TCB address)

On return from MTYCTL:

(2\8) (Register\Contents) (R0\Current status of EIA control signals) (R3\TCB address) (R1,R2,R5\Preserved across the call)

The following is example code for the call: MOV #bits,R0 ; R0 = EIA signals to assert MOV TCBADX,R3 ; R3 -> TCB CALL @MTYCTX ; Set EIA signals as desired TCBADX: .BLKW ; Points to TCB MTYCTX: .BLKW ; Points to MTYCTL in monitor ; (from THK.CT in THOOKS data ; structure) (Terminal Modem Status Routine, MTYSTA\mtysta_sec)

The handler calls MTYSTA to obtain the status of certain EIA control signals of a particular serial port. Calling MTYSTA is appropriate only for ports for which REMOTE (modem) support has been specified during SYSGEN.

MTYSTA is called through offset 12(8) of the THOOKS data structure.

The status of the following control signals can be returned if the signal is supported by the interface:

(3\10\10) (Signal\Bit Mask\Meaning) (DLRI$\040000\Ring indicator) (DLCTS$\020000\Clear to send) (DLDCD$\010000\Data carrier detect) (DLRIE$\000100\Receiver interrupt enable) (DLTIE$\000100\Transmitter interupt enable) (DLRTS$\000004\Request to send) (DLDTR$\000002\Data terminal ready)

On entry to MTYSTA:

(2\8) (Register\Contents) (R3\TCB address)

On return from MTYSTA:

(2\8) (Register\Contents) (R0\Current status of EIA control signals as described above) (R3\TCB address) (R1,R2,R4,R5\Preserved across the call)

The following is example code for the call: MOV TCBADR,R3 ; R3 -> TCB CALL @MTYSTX ; Obtain current EIA signals TCBADR: .BLKW ; Points to TCB MTYSTX: .BLKW ; Points to MTYSTA in monitor ; (from THK.ST in THOOKS ; data structure) (Connecting a Serial Interface Printer Handler (LS)\mtty_ls_sec)

Through the SYSGEN procedure, you can build an LS handler for connection to any LUN in a multiterminal system. Any serial line can be used as the printer port.

The monitor must be built with the terminal hooks option and the handler must also be built with multiterminal hooks support. During system generation a LUN can be specified as the default multiterminal line number for the handler. The default can be overridden with the command, SET LS LINE=n, before the handler is loaded. See the LS section of the (dev_book) for information.

The handler hooks option for LS can be useful in many applications. For example, you can use a hardcopy boot-time console as the system printer by setting LS to the console DL (SET LS LINE=0). You could assign a video terminal at LUN1 as the console by issuing (SET TT CONSOL=1). When you finish the printing job, you can unload LS and (only these circumstances) reassign the hardcopy terminal to LUN0 by issuing (SET TT CONSOL=0). (Connecting a Serial Communications Handler (XL)\mtty_xl_sec)

Through the SYSGEN procedure, you can build an XL handler for connection to any LUN in a multiterminal system. Any serial line can be used as the communications port.

The monitor must be built with the terminal hooks option and the handler must be built with multiterminal serial line support. During system generation a LUN can be specified as the default multiterminal line number for the handler. The default can be overridden with the command, SET XL LINE=n, before the handler is loaded. See the (dev_book) for information. (Using Two or More Terminals\mttyterm_sec)

The following sections discuss the methods you can use to support two or more terminals on your multiterminal system. (nomttyterm_sec) describes methods you can use to support two terminals on a system that has not been generated for multiterminal support. The methods in (nomttyterm_sec) pertain only to systems that contain more than one DL controller and make a system on which you can use only one terminal at any time. If you want to use more than one terminal at the same time, you must build a multiterminal monitor. (A Separate Terminal for Each Job)

Once you perform a system generation for the multiterminal feature, you can easily establish private consoles for up to eight jobs. However, you must be running a multi-job monitor with the system job feature in order to support more than two jobs.

As (TTCONDEF_SEC) describes, simply use the FRUN/TERMINAL:n or SRUN/TERMINAL:n commands to start foreground and system jobs, and assign them to private consoles. You need not use any multiterminal programmed requests to do this. Remember that each console is truly private -- no two jobs can share terminals through the FRUN or SRUN /TERMINAL:n mechanism.

Each job can attach its own console terminal and issue subsequent multiterminal programmed requests. (Multiterminal Applications)

Some applications need to take advantage of RT--11's multiterminal feature by using the programmed requests to manage more than one terminal for each job. In these applications, one program controls several terminals. Jobs that must control more than one terminal use the multiterminal data structures and programmed requests. (Introduction to Multiterminal Programmed Requests)

It is not difficult for a program to use more than one terminal in a multiterminal system. (MTTYSUM_TAB) summarizes the actions a program may need to take in order to use a terminal in addition to its own console terminal. It also lists the appropriate procedures for the program to follow. Familiarize yourself with the procedures and the corresponding programmed requests. The (RT--11 Programmer's Reference Manual) provides detailed information on the format of each programmed request. Study this information before you attempt to write a multiterminal application program.

(Summary of Activities for a Program in a Multiterminal System\MTTYSUM_TAB) (2\27) (Activity\Procedure to Follow) (Obtain the status of a multiterminal system.\Use the .MTSTAT programmed request.) (Acquire a terminal.\Use the .MTATCH programmed request to attach the terminal and dedicate it to this program. As part of its startup procedure, a program usually attaches all the terminals it needs. Note that only one job can attach a shared console, and only the terminal's owner can issue multiterminal programmed requests for it. However, all the jobs sharing the background console can issue .TTYIN, .TTYOUT, .CSIGEN, .CSISPC, .GTLIN, and .PRINT requests for it, as well as .READ and .WRITE requests for TT. To detect status changes without issuing a programmed request, examine the AST word for each terminal.) (FIRST) (Examine the characteristics of each attached terminal.\Use the .MTGET programmed request.) (Change terminal characteristics if necessary.\Use the .MTSET programmed request.) (Get a character from a terminal and wait for it.\Use the .MTIN programmed request.) (Get a character from a terminal; do not wait for it.\Use .MTSET to set the status word, then use the .MTIN programmed request. (You need issue the .MTSET only once.)) (Send a character to a terminal and wait for it.\Use the .MTOUT programmed request.) (LAST) (Send a character to a terminal; do not wait for it.\Use .MTSET to set the status word, then use the .MTOUT programmed request. (You need issue the .MTSET request only once.)) (Send a line to a terminal; wait until it prints.\Use the .MTPRNT programmed request.) (Reset CTRL/O for a terminal, enabling output.\Use the .MTRCTO programmed request.) (Relinquish ownership of a terminal so that another job can use it.\Use the .MTDTCH programmed request.) (Multiterminal Data Structures)

The following sections describe the two important data structures for multiterminal systems: terminal control blocks, and asynchronous terminal status words. (Terminal Control Block (TCB))

RT--11 creates one terminal control block, called a TCB, for each terminal you describe at system generation time. Each TCB located in RMON contains terminal characteristics, terminal status, and the input and output ring buffers and pointers for the terminal. The length of a TCB varies, depending on the special features you select through system generation. Note, though, that the first 20 decimal words in each TCB are fixed. (Format)

(TCBFORMAT_FIG) illustrates the format of the TCB; (TCBCONTENTS_TAB) describes its contents. The size, offset, or existence of the data structure elements following I.ITOP depend on the special features you select through system generation.

(Format of the Terminal Control Block (TCB)\TCBFORMAT_FIG) (POSTSCRIPT\S560C5TCNFG1_FIG.EPS\25) (POSTSCRIPT\S560C5TCNFG2_FIG.EPS\34)
(Contents of the Terminal Control Block (TCB), .TCBDF\TCBCONTENTS_TAB) (\MULTIPAGE) (3\6\8) (Offset\Name\Description) (0\T.CNFG\The terminal configuration word. A program and the monitor communicate with each other about terminal characteristics through the .MTGET and .MTSET programmed requests. These requests use a four-word status block within the program to store terminal information. The first word, M.TSTS, has the same structure as T.CNFG. (TCNFG_TAB) describes the meaning of each bit in T.CNFG.) (FIRST) (2\T.CNF2\The second terminal configuration word. The structure of this word is the same as that of M.TST2, the second word of the four-word status block for .MTGET and .MTSET programmed requests. (TCNF2_TAB) describes the meaning of each bit in T.CNF2.) (4\T.TFIL\Contains the character after which this terminal requires one or more fill characters. The counterpart of this byte in the four-word status block for .MTGET and .MTSET programmed requests is called M.TFIL.) (5\T.FCNT\Contains the number of fill characters that this terminal requires. The counterpart of this byte in the four-word status block for .MTGET and .MTSET programmed requests is called M.FCNT.) (6\T.WID\Contains the carriage width of this terminal. The counterpart of this word in the four-word status block for .MTGET and .MTSET programmed requests is called M.TWID. The maximum value is 255 decimal.) (10\T.OCHR\Contains the character to output.) (11\T.LPOS\Contains the current carriage position for this terminal.) (12\T.OWNR\A pointer to the impure area of the job that currently owns this terminal. This word has a value when this terminal is a private console for a job, or, when it is a shared console and one job has attached it. This word is 0 when this terminal is a shared console and no job has attached it, or when it is not a console and no job has attached it.

Alternately, if the HANMT$ bit is set in the T.STAT word (offset 14), T.OWNR is a pointer to the multiterminal hook routine in a handler. ) (14\T.STAT\Contains the terminal status. (TSTAT_TAB) describes the meaning of each bit in T.STAT.) (16\T.CSR\Contains the CSR for the keyboard of this terminal. It is 0 if the bootstrap could not find the CSR; this makes the LUN unusable.) (20\T.VEC\Contains the first interrupt vector for this terminal.) (22\T.PRI\Contains the device interrupt priority.) (24\T.JOB\Contains the job number of the job that currently owns this terminal.) (25\T.PUN\Contains the physical unit number of this terminal. This value is always 0 for terminals on DL interfaces. For terminals on DZ interfaces, the value ranges from 0 through 7 (0 through 3 for DZV11s). For DH interfaces, the value ranges from 0 through 15(10). ) (26\T.NFIL\Active fill character counter. This byte contains the number of nulls left to print.) (27\T.PTTI\Contains the last character typed on the terminal keyboard.) (30\T.TCTF\Contains the special fill character. (For example, a space is the special fill character for a tab, and a line feed is the special fill character for a form feed.)) (31\T.TNFL\Contains the count for the special fill character. The value is stored as a negative number.) (32\T.TID\A pointer to the terminal identification prompt string, which contains the job name, and is used only when the monitor is actually printing an identification. It is 0 at all other times.) (34\---\PAR address in mapped systems; else reserved.) (36\T.TTLC\Contains the terminal line count (the number of lines in the input buffer).) (40\T.IRNG\A pointer to the first byte of the input ring buffer. (For more information on ring buffers, see (rmon_chap).)) (42\T.IPUT\Input PUT pointer.) (44\T.ICTR\Input character count.) (46\T.IGET\Input GET pointer.) (50\T.ITOP\Indicates the top of the input ring buffer. This word points to the byte just beyond the high limit of the buffer.) (52\---\Input ring buffer. Its length is determined at system generation time. It is TTYIN bytes long. (Default is 134(10))) (\T.OPUT\Output PUT pointer.) (\T.OCTR\Output character count.) (\---\CTRL/O flag. A value of 0 means CTRL/O is not in effect; a value of 377(8) means that CTRL/O is in effect.) (\T.OGET\Output GET pointer.) (\T.OTOP\Indicates the top of the output ring buffer. This word actually points to the byte just beyond the high limit of the buffer.) (\---\Output ring buffer. Its length is determined at system generation time. It is TTYOUT bytes long. (Default is 40(10))) (\T.RTRY\Present if device time-out support or support for modems was selected at system generation time. This word contains the retry count for output.) (\T.TBLK\Present if device time-out support or support for modems was selected at system generation time. This seven-word area is the time-out block for this terminal.) (\T.AST\Present if the asynchronous terminal status word was selected at system generation time. This word is a pointer to the AST word. In mapped systems, the AST pointer is followed by a second word that contains a PAR1 value for mapping to the AST word.) (\T.XFLG\Present if the system job feature was selected at system generation time. If this flag byte is nonzero, it indicates that a CTRL/X sequence is in progress.) (\T.XCNT\Present if the system job feature was selected at system generation time. This byte contains the number of characters typed in a CTRL/X sequence.) (LAST) (\T.XPRE\Present if the system job feature was selected at system generation time. This word contains the previous character typed on the terminal keyboard.) (\T.XBUF\Present if the system job feature was selected at system generation time. This three-word area contains the characters typed as part of a CTRL/X sequence.) (\T.CNT\Present if the system job feature was selected at system generation time. This word contains the number of jobs that are sharing the background console.)

(Terminal Configuration Word, T.CNFG (.TCFDF)\TCNFG_TAB) (\MULTIPAGE) (3\6\8) (Bit\Name\Meaning) (0\HWTAB$\Hardware tab bit. When set, it indicates that this terminal has hardware tab support. The monitor does not convert a tab character to spaces before sending it to the output ring buffer. Your program can set this bit for a particular terminal through the .MTSET programmed request (described in (MTSET_SEC)). The SET TT: TAB command sets this bit for the background console.) (1\CRLF$\When this bit is set, the monitor sends a carriage return/line feed combination to the terminal when its carriage width is exceeded. Your program can set this bit for a particular terminal through the .MTSET request. The SET TT: CRLF command sets this bit for the background console.) (2\FORM$\Hardware form feed bit. When set, it indicates that this terminal has hardware form feed support. The monitor does not convert a form feed character to line feeds before sending it to the output ring buffer. Your program can set this bit for a particular terminal through the .MTSET programmed request. The SET TT: FORM command sets this bit for the background console. ) (3\FBTTY$\When this bit is clear, the monitor treats CTRL/F, CTRL/B, and CTRL/X as ordinary characters and ignores their special meanings. The SET TT: NOFB command clears this bit for the background console. Your program cannot set this bit for other terminals; only the shared console can use it.) (4-5\------\Reserved.) (6\TCBIT$\The inhibit TT wait bit. It is similar to bit 6 in the Job Status Word, which a program can set. When this bit is set, the program does not wait for I/O to complete on the terminal before execution continues. Note that bit 6 in the JSW affects only the job's current console; it does not affect any other terminals attached to this job. If the program uses other terminals for I/O, it can set this bit in each TCB by using the .MTSET programmed request.

If this terminal is a private console for this job, the job can set bit 6 in the JSW. In a multiterminal application, the job can set bit 6 in either the JSW or in the TCB for the console terminal. In any case, setting bit 6 in one place (the TCB or the JSW) results in both bits being set. Be sure and issue a .CRTLO request after modifying the JSW. ) (7\PAGE$\The XON/XOFF bit. When set, it enables recognition of the XON (CTRL/Q) and XOFF (CTRL/S) characters. The SET TT: PAGE command sets this bit for the background console. (See (rmon_chap) for more information on XON/XOFF processing.)) (8-11\LINSP$\The baud rate mask for terminals on DH or DZ lines. (The baud rate for terminals on DL lines is not programmable through the .MTSET request.) Notice that the values for masks 5400 and 7400 are different between DZ and DH interfaces. The values are as follows:

(3\8\8) (Mask\DZRate\DHRate) (0000\50\50) (0400\75\75) (1000\110\110) (1400\134.5\134.5) (2000\150\150) (2400\300\300) (3000\600\600) (3400\1200\1200) (4000\1800\1800) (4400\2000\2000) (5000\2400\2400) (5400\3600\38400) (6000\4800\4800) (6400\7200\7200) (7000\9600\9600) (7400\not used\19200)

There are baud rate restrictions for DH; see the appropriate DH interface technical manual for information. ) (12\TTSPC$\The special mode bit. It is similar to bit 12 in the Job Status Word, which affects the job's console. If this terminal is a private console for this job, the job can set bit 12 in the JSW to enable special mode. In a multiterminal application, the job can set bit 12 in either the JSW or in the TCB for the console terminal. In any case, setting bit 12 in one place (the TCB or the JSW) results in both bits being set. (See the description of .TTYIN in the (SML_BOOK) for more information on special mode.) Be sure to issue a .MTRCTO request after modifying the JSW. If the program uses other terminals for I/O, it can set this bit in each TCB by using the .MTSET programmed request. ) (13\REMOT$\The remote terminal bit. It is read-only, and your program cannot alter it. When set, this bit indicates that this terminal is remote. ) (14\TTLC$\When this bit is set, lower- and upper-case typing is enabled. When this bit is clear, the monitor converts all typed characters to upper-case. If this terminal is a private console for this job, the job can set bit 14 in the JSW. In a multiterminal application, the job can set bit 14 in either the JSW or in the TCB for the console terminal. In any case, setting bit 14 in one place (the TCB or the JSW) results in both bits being set. Be sure to issue a .MTRCTO request after changing any bits in the JSW. ) (15\BKSP$\When this bit is set, the monitor takes the appropriate action for a video terminal when the DELETE key is pressed. Your program can set this bit for a particular terminal through the .MTSET programmed request. The SET TT: SCOPE command sets this bit for the background console. )

(Second Terminal Configuration Word, T.CNF2 (.TC2DF)\TCNF2_TAB) (3\6\8) (Bit\Name\Meaning) (0-1\CHRLN$\ These two bits indicate the length of a character. The DZ and DH interfaces can transmit characters that are five, six, seven, or eight bits long. The values are as follows:
(2\6) (Value\Character Length) (00\5 bits) (01\6 bits) (10\7 bits) (11\8 bits) These bits are unused for DL interfaces.) (2\USTOP$\Unit stop bit. Depending on the speed, it indicates the number of stop bits to send. The values are as follows:
(2\6) (Value\Stop Bits) (0\Send one stop bit) (1\Send two stop bits (one and one-half stop bits if five-bit characters are used)) This bit is unused for DL interfaces.) (3\PAREN$\The parity enable bit. When set, it enables parity checking.) (4\ODDPR$\Indicates whether parity checking will be odd or even. The values are as follows:
(2\6) (Value\Parity) (0\Even parity) (1\Odd parity) This bit is unused for DL interfaces.) (5-6\\Reserved.) (7\RPALL$\When set, this bit indicates (read pass-all) mode. In this mode, RT--11 passes (on input) all eight bits of each character without interpreting or echoing the characters. This feature is often referred to as (transparency.) For example, it passes CTRL/C as 203 in read pass-all mode if the terminal sets the high bit upon transmission. When RPALL$ is set, the terminal is implicitly in single-character mode.) (8-14\\Reserved.) (15\WPALL$\When set, this bit indicates write pass-all mode. In this mode, RT--11 passes (on output) all eight bits of each character without interpreting the characters.)

(Terminal Status Word, T.STAT (.TSTDF)\TSTAT_TAB) (\MULTIPAGE) (3\6\8) (Bit\Name\Meaning When Set) (0\FILL$\Indicates that a fill sequence is in progress.) (1\CTRLU$\CTRL/U in progress.) (2\DHOIP$\Output in progress on DH controller.) (3\HANMT$\LUN owned by a device handler.) (4\DTACH$\Indicates that a detach operation is in progress. Input from the terminal is ignored.) (5\WRWT$\This is the TT handler synchronization bit.) (6\INEXP$\Indicates that an output interrupt is expected.) (7\PAGE$\Indicates that the terminal has sent XOFF to request suspension of output.) (8\HANMC$\Indicates that the handler intends to control the modem signals (defined only for MTTY systems with HANMT$ set.)

If HANMC$ is clear, MTTY monitor controls modem signals.) (9\\Reserved.) (10\SHARE$\Indicates that this terminal is the shared console.) (11\HNGUP$\Indicates that the remote terminal has hung up.) (12\DZ11$\Indicates that the terminal interface is a DZ.) (13\DH11$\Indicates that the terminal interface is a DH.

If bits 12 and 13 both clear, indicates terminal interface is a DL.

Bits 12 and 13 both set is reserved.) (14\CTRLC$\Indicates that two CTRL/C characters were typed at this terminal. This bit is reset by .MTGET.) (15\CONSL$\Indicates that this terminal is a console for some job. It can be shared or private.) (Patching a TCB)

You can use SIPP to make binary patches to the terminal control blocks in your monitor file, (monitr).SYS. The TCBs are located in p-sect MTTY$, which you can find on your monitor link map. They appear in the same order in which SYSGEN assigned physical units to logical unit numbers at system generation time (see (TTHARDINFO_SEC)). The first TCB is for LUN 0; it starts at the label DLTCB::. The TCBs are all the same size; the value of T.CBSZ is their length. (Asynchronous Terminal Status (AST) Word)

Support for the asynchronous terminal status (AST) word is a special feature that you can select at system generation time. If you select this feature, you can set aside space for one AST word per LUN in your own program. (You can check for AST support from within your program by checking if the CF3.AS bit (bit 13 in RMON fixed offset CONFG3) is set.) Then, when you issue the .MTATCH programmed request to attach a terminal to your job, you specify as an argument the address of the AST word for that terminal.

The purpose of the AST word is to monitor each terminal's line so that the program can obtain certain information without issuing a programmed request. RT--11 sets or clears bits in the AST word asynchronously, as significant events occur. The AST word contains information on whether: (UNNUMBERED) Input is available from the terminal The terminal's output ring buffer is empty Double CTRL/C was typed on the terminal A remote line just dialed in or just hung up

(AST_TAB) shows the event flags in the AST word and their meaning. Unused bits are reserved for future use by Digital.

(Asynchronous Terminal Status (AST) Word (.TASDF)\AST_TAB) (\MULTIPAGE) (4\8\9\10) (Bit\Name\Bit Pattern\Meaning When Set) (15\AS.CTC\100000\Double or multiple CTRL/C was typed on this terminal. You must reset this bit; the monitor never turns it off.) (14\AS.INP\40000\Input is available from this terminal.) (13\AS.OUT\20000\The output ring buffer is empty.) (7\AS.CAR\200\Carrier is present (for remote lines only).) (6\AS.HNG\100\This remote line just hung up and RT--11 dropped it.)

The monitor sets bit 15, AS.CTC, whenever two or more consecutive CTRL/Cs are typed on any terminal. Typing two CTRL/Cs on a job's console terminal always aborts the job, unless the job already issued the .SCCA programmed request to intercept the characters. The job must reset this bit before it continues processing.

The monitor sets bit 14, AS.INP, when input is available from the terminal. It can be a line of characters in normal mode, or a single character in special mode. The monitor clears this bit when the program reads the characters.

The monitor sets bit 13, AS.OUT, when the terminal's output ring buffer is empty. This occurs after the last character in the ring buffer is printed on the terminal. The monitor clears this bit when there are characters in the ring buffer.

The monitor sets bit 7, AS.CAR, when it answers a remote line. It clears this bit when the remote line hangs up or drops carrier. (Carrier )is a tone transmitted over the remote line. It carries information through its modulation.

The monitor sets bit 6, AS.HNG, when it drops a remote line that just hung up. (Using the Multiterminal Programmed Requests)

The routines in MTTEMT, which are part of RMON, dispatch the multiterminal programmed requests and process them. The multiterminal programmed requests are more fully described in the (SML_book).

The dispatch routine accepts programmed requests that translate into EMT 375 instructions with a subcode of 37 and a function code in the range 0 through 10 octal. The dispatch routine first checks to see if the programmed request is a valid one. Then it verifies the logical unit number and makes sure that the terminal is installed. If the programmed request is for an attach operation, the dispatch routine verifies that the terminal is not already attached. For all other requests, the dispatch routine verifies that the terminal is attached to the calling program.

If the request passes all the checks in the dispatch routine, control passes to the EMT processing code for the individual request. (Attaching a Terminal: .MTATCH)

Issue the .MTATCH programmed request to attach a terminal to your job. This permits your program to print characters on the terminal, get characters from it, and alter its characteristics.

The attach routine first checks to see if the terminal is the shared console, but not this job's console. If so, the routine issues error code 4. If the terminal is already attached to another job, the routine also issues error code 4. Finally, the routine checks if the terminal is attached to a handler. If the terminal (serial line) is attached to a device handler, the routine returns error code 6 and R0 contains the RAD50 handler name. The status information is always placed in the status block in your program even when an error is returned from this operation.

The routine attaches the terminal by setting up certain TCB offsets for this terminal. The routine always stores a pointer in the T.OWNR word to the owning job's impure area. In multi-job systems, it also stores the job number in the T.JOB byte.

If AST support is part of the system, the routine puts a pointer to the AST word in T.AST. In mapped systems, it also stores a value in T.AST + 2 to be used as a PAR1 value in mapping to the AST word.

The routine next moves some bits from the JSW into T.CNFG if this terminal is the job's console. It copies TTLC$ (bit 14 for lower case), TTSPC$ (bit 12 for special mode), and TCBIT$ (bit 6 for wait inhibit). If the terminal is the background console, T.TFIL is loaded from location 56.

When a job attaches a terminal, the terminal remains attached until the job issues a .MTDTCH request, or until the job exits or aborts. (unnumbered) If the terminal is detached through the .MTDTCH request, the job is blocked until output in process for the terminal finishes and the monitor detaches the terminal. If the terminal is detached through a job exit, the actions taken are determined by the type of monitor and the type of terminal. A single-job monitor detaches a console terminal immediately (no wait for output to finish); with other terminal types, the monitor waits for output to finish.

A multijob monitor detaches a shared terminal immediately (no wait for output to finish); with other terminal types, the monitor waits for output to finish. If the terminal is detached when the job aborts, the output terminates and the monitor detaches the terminal immediately. (Getting Terminal Status: .MTGET)

Issue the .MTGET programmed request to obtain the status of a terminal. (The terminal need not be attached to your program in order to obtain the status.)

The .MTGET routine moves information from the TCB to the status block in your program. The following transfers occur: (SIMPLE) T.CNFG to M.TSTS T.CNF2 to M.TST2 T.TFIL to M.TFIL T.FCNT to M.FCNT T.WID to M.TWID High byte of T.STAT to M.TSTW

Then, if the terminal is not attached to any job, the routine returns error code 1. If the terminal is attached, but not to this job, the routine returns error code 4 and R0 contains the job number of the terminal's owner. If the terminal is the shared console, but the job has its own private console, R0 contains the job's own job number. If the terminal (serial line) is attached to a device handler, the routine returns error code 6 and R0 contains the RAD50 handler name. The status information is always placed in the status block in your program even when an error is returned from this operation.

Finally, if no error was returned, the routine clears bit 14 (CTRL/C) in T.STAT. (Setting Terminal Characteristics: .MTSET\MTSET_SEC)

Issue the .MTSET programmed request to set the characteristics of a terminal. If the terminal is not attached to your program, the request returns error code 1.

The request moves the contents of M.TSTS to T.CNFG, except for REMOT$ (bit 13, the remote terminal bit), which is read only in T.CNFG. If the terminal is the job's console, the routine moves some bits from T.CNFG into the JSW. It copies TTLC$ (bit 14 for lower case), TTSPC$ (bit 12 for special mode), and TCBIT$ (bit 6 for wait inhibit).

Whether or not the terminal is the job's console, the routine moves the following information: (SIMPLE) M.TST2 to T.CNF2 M.TFIL to T.TFIL M.FCNT to T.FCNT M.TWID to T.WID

If DH or DZ support is part of the system and if this terminal is on a DH or DZ interface, the routine waits for any characters to finish printing on this terminal, then sets up the appropriate DH or DZ line parameters. ()Always issue an .MTGET request before an .MTSET request. Change only the fields you are interested in. For a one-bit field, use a BIS or BIC instruction to set or clear it. For a multiple-bit field, clear it first with a BIC and then use BIS to load the field. Use MOVB or MOV instructions only for byte or word fields. Changing other bits can cause unusual terminal service errors. Finally, issue the .MTSET specifying the same status block that you used for the .MTGET request. (Getting Characters: .MTIN)

Issue the .MTIN programmed request to get one or more characters from the terminal.

The routine moves some bits from the JSW into T.CNFG if this terminal is the job's console. It copies TTLC$ (bit 14 for lower case), TTSPC$ (bit 12 for special mode), and TCBIT$ (bit 6 for wait inhibit). If the terminal is the background console, T.TFIL is loaded from location 56.

The routine gets a character from the input ring buffer and adjusts the ring buffer pointers. If the terminal is the console, the routine uses the ring buffer in the job's impure area. If the terminal is not the console, the routine uses the ring buffer in the terminal's TCB.

If the input character is CTRL/C on a console terminal, and .SCCA is not in effect, the job aborts. (Printing Characters: .MTOUT)

Issue the .MTOUT programmed request to print one or more characters on the terminal.

The routine moves some bits from the JSW into T.CNFG if this terminal is the job's console. It copies TTLC$ (bit 14 for lower case), TTSPC$ (bit 12 for special mode), and TCBIT$ (bit 6 for wait inhibit). If the terminal is the background console, T.TFIL is loaded from location 56.

The routine moves a character from the user buffer into the output ring buffer and adjusts the ring buffer pointers. If the terminal is the console, the routine uses the ring buffer in the job's impure area. If the terminal is not the console, the routine uses the ring buffer in the terminal's TCB. (Printing a Line: .MTPRNT)

Issue the .MTPRNT programmed request to print a string of characters on the terminal. The string can end with a null byte (to print a carriage return and a line feed at its end) or a 200 octal byte, just as in the .PRINT programmed request.

The routine moves a line from the user buffer into the output ring buffer and adjusts the ring buffer pointers. If the terminal is the console, the routine uses the ring buffer in the job's impure area. If the terminal is not the console, the routine uses the ring buffer in the terminal's TCB. If there is no room in the output ring, the job is blocked until room is available, regardless of the value of TCBIT$ (bit 6) in T.CNFG. (Resetting CTRL/O: .MTRCTO)

Issue the .MTRCTO programmed request to enable output on a terminal even though CTRL/O may have been typed.

This routine clears the CTRL/O flag in the TCB for the terminal and moves some bits from the JSW into T.CNFG if this terminal is the job's console. It copies TTLC$ (bit 14 for lower case), TTSPC$ (bit 12 for special mode), and TCBIT$ (bit 6 for wait inhibit). If the terminal is the background console, T.TFIL is loaded from location 56.

If you ever alter the contents of the JSW, Digital recommends that your program issue the .MTRCTO request immediately afterward so that the TCB and the JSW always have the same information. In particular, if you require lower-case input for a .GTLIN request, set TTLC$ (bit 14) in the JSW and issue .MTRCTO or .RCTRLO before using .GTLIN. (Getting System Status: .MTSTAT)

Issue the .MTSTAT programmed request to obtain status information about the multiterminal system. This request returns the following four words of information to your program: (UNNUMBERED) The offset from the start of RMON to the first TCB The offset from the start of RMON to the TCB of the current console terminal for this job The value of the LUN associated with the last TCB. The size of each TCB in bytes. (Note that all TCBs on a particular monitor are the same size.)

Remember that the TCBs are located in RMON in the order in which you specified interface lines to the SYSGEN dialogue. That is, the TCBs for local DLs appear first, followed by remote DLs, local DZs, remote DZs, and local and remote DHs.

With the information returned to you by .MTSTAT you can find the TCB for any terminal in the system and examine its contents with the .GVAL request. (TCBFORMAT_FIG) and (TCBCONTENTS_TAB) describe the contents of each TCB. (Detaching a Terminal: .MTDTCH)

Issue the .MTDTCH programmed request to detach a terminal from your job and make it available for use by another job.

The routine first sets the DTACH$ bit (bit 4) in T.STAT to indicate that a detach operation is in progress. This avoids any race conditions in the module MTTINT. (A race condition is a situation in which two or more processes attempt to modify the same data structure at the same time; as a result, the data structure is corrupted and the integrity of the processes is compromised.) It then forces XON if XOFF had been previously set. If the terminal is not a shared console, the output buffer is then flushed. The job is blocked until T.OCTR is clear.

The words T.OWNR and T.AST are set to zero to detach the terminal. DTACH$ is finally cleared to finish the operation.

Whenever a job aborts, terminals attached to it are detached without having their buffers flushed. (The Console as a Special Case)

The console terminal is always a special case for I/O in multiterminal systems. Recall that each job has input and output ring buffers and pointers, both in its console's TCB and in its impure area. Whenever a job gets characters from its console terminal, or writes characters to it, the monitor uses the set of ring buffers located in the job's impure area. In this case, the console can be the background console, if this job is sharing it, or it can be a private console, if this job has one.

For all I/O requests involving the job's console, the monitor performs the request based on the characteristics indicated in the Job Status Word rather than in the terminal configuration word. However, the monitor aligns corresponding bits in the job's console terminal configuration word with the JSW the next time the job does any I/O or a reset CTRL/O request is issued for that terminal. (See (TCNFG_TAB)). To force the alignment before any I/O or reset CTRL/O request is issued, Digital recommends that you issue the .MTRCTO request immediately after altering the JSW to make sure that the contents of the JSW are duplicated in the TCB for the terminal. Similarly, if you modify the terminal configuration word with .MTSET for a job's console, the monitor also modifies the JSW.

Note that a program must issue the .SCCA programmed request to inhibit CTRL/C on its console terminal. (Interrupt Service)

Terminal service in multiterminal systems is centralized in the routines contained in MTTINT. This source file is assembled and linked together with other files to become part of RMON.

In general, RT--11 services terminals in one of two ways, depending on whether the terminal is connected through a local or a remote line. (Local Terminals)

RT--11's interrupt service routine for multiterminal systems contains the following data structures: (UNNUMBERED) Receive CSR I/O page address Receive data buffer I/O page address Transmit CSR I/O page address Transmit data buffer I/O page address

RT--11's interrupt service is essentially simple. The bootstrap sets the input (or receiver) interrupt enable bit; the monitor leaves it set at all times. If a character is typed on a local terminal, an interrupt occurs and the monitor picks up the character. If the terminal is not attached to any job, the character is ignored. In multiterminal systems with time-out support, the monitor ensures that the interrupt enable bit for each DL is enabled once every 30 clock ticks (every half-second).

The monitor only sets the output interrupt enable bit when it is ready to print a character. It clears the bit after the output ring buffer is empty. (Remote Terminals)

Remote terminals are connected to RT--11 through modems (also known as data sets) and telephone lines so that someone can call up the computer and ring its data phone. When this occurs, it causes an interrupt, which the monitor recognizes. If the unit is attached, the multiterminal service routine answers the phone call and sends out carrier in response. (Carrier is a tone transmitted over the remote line that carries information through its modulation.)

The remote terminal can communicate with RT--11 through an approved protocol. When a remote terminal connects to an RT--11 system, using a modem, the following protocol should be used: (numbered) The remote terminal asserts Data_Terminal_Ready (DTR) to the attached modem. The user places the call to the RT--11 system. The modem attached to the RT--11 system answers the phone and responds with a carrier. RT--11 sets a 30 second timer.

If the modem attached to the remote terminal responds with carrier within 30 seconds, the timer is cancelled and I/O can begin.

If the 30 second timer expires and the modem attached to the remote terminal has not responded with carrier, RT--11 disconnects the line.

Once communication has begun, RT--11 never takes the initiative to terminate the connection. It always continues to send carrier. However, there are two situations in which RT--11 does hang up on the remote line. If the terminal stops sending carrier for any reason, RT--11 waits two seconds for it to resume. When the interval expires, RT--11 hangs up on the remote line. In the other situation, the remote terminal hangs up. RT--11 detects loss of carrier and waits two seconds before disconnecting the remote line. Special requirements for customers in the United Kingdom are met through assemblies based on the U.K. conditional being set to 1.

Remote terminals require a DL11-E, DLV11-E (or equivalent), DH, or DZ interface. In addition to the data lines required for remote terminals, the following control lines must be connected (for dial-up operations): (UNNUMBERED) Data terminal ready Ring indicator Carrier detect

A local terminal can be connected to a remote terminal interface if it is identified during system generation as a local terminal. The control lines listed above are then ignored and you can leave them unconnected. (Polling Routines)

RT--11's multiterminal support includes two polling routines, which the following sections describe. (The DH interface does not require polling.) (Time-Out Routine for DL Terminals)

You can select the time-out polling routine as a special feature at system generation time. It is an example of the device time-out feature that is available to application programs through the .TIMIO programmed request. RT--11 executes this routine once every half second. Its purpose is to periodically reenable the I/O interrupt enable bits on DL interfaces so that noise on a line or local static electricity cannot seriously affect transmissions.

The polling routine examines each DL line on the system every half second. It turns on the line's input interrupt enable bit and, if the line is remote, its modem interrupt enable bit. Then, if output is pending with no output interrupt, it turns the output interrupt enable bit off and then on, to force an output interrupt on the line. (Depending on the hardware failure that caused the loss of the output interrupt, this may occasionally cause a character to be repeated.)

The last thing the time-out routine does is schedule itself to run again. (DZ Remote Line Polling Routine\REMOTEDZ_SEC)

The DZ polling routine polls the terminals connected to the system through DZ interfaces. It is necessary because these terminals do not interrupt when their status changes.

The remote line polling routine schedules a mark time request. It waits 30 seconds after the data set rings to detect carrier. If there is no carrier after the required amount of time, the routine disconnects the remote line. The routine takes similar action on line errors and lost carrier. This routine is automatically included in the multiterminal service for remote DZ lines. (Restrictions)

The restrictions that apply to systems with the multiterminal special feature are listed in the (srn_book). (Debugging a Multiterminal Application)

Use VDT, the Virtual Debugging Technique, to debug a multiterminal application. See the (sum_book) for more information on VDT. (Multiterminal Example Program)

(MTYSET_FIG) shows a program that uses the multiterminal programmed requests.

(Multiterminal Example Program\MTYSET_FIG) ((wide\MULTIPAGE)) (The following gives you a 7 point code-example font) defcodexamplefontsevenpointmono .TITLE MTYSET.MAC - Auto-baud and Initialize DEC Terminals .IDENT /X05.01/ ; COPYRIGHT 1989, 1990, 1991 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ALL RIGHTS RESERVED ; ;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ;TRANSFERRED. ; ;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ;CORPORATION. ; ;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ;SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. .SBTTL Abstract and Edit History ;+ ; ; Auto-baud and Initialize DEC Terminals ; ; AUTHOR: LCP - 10/79 ; ; This program will attach all "known" terminals and ; if they are VT5x, VT1xx or LA1xx series it will determine ; at what baud rate they are set and put that information in ; their TCBs. ("Foreign" terminals will be assumed to ; be set at their correct baud rate). As each terminal is ; "initialized", its screen will be cleared, a "sign-on" ; message will be displayed, and the terminal type and ; baud rate will be logged on the background console. ; ; Edit History: ; ; (001) 01-Jun-91 MBG Source clean-up using macros from SYSTEM, add ; support for DH, fix numerous bugs. ; ;- .SBTTL Macros & Definitions .LIBRARY "SRC:SYSTEM.MLB" ; RT-11 Programmed requests .MCALL .MTATC .MTDTC .MTGET .MCALL .MTOUT .MTIN .MTPRN .MCALL .MTSET .MTSTA .EXIT .MCALL .MTRCT .PRINT .TTYOU .MCALL .MRKT .CMKT .MCALL .ASSUM ; TCB offset and bit definitions .MCALL .MGTDF .MSTDF .TCBDF .MCALL .TCFDF .TSTDF .MGTDF ;Define MTGET block offsets .MSTDF ;Define MTSTAT block offsets .TCBDF ;Define TCB offsets .TCFDF ;Define configuration word bits .TSTDF ;Define status word bits ; Characters C.LF = 12 ;Line feed C.CR = 15 ;Carriage return C.ESC = 33 ;Escape .SBTTL Start of Program .ENABL LSB MTYSET: MOV #STAT,R3 ;R3 -> 8-word status block for .MTSTAT .MTSTA #AREA,R3 ;Get MTTY status MOV MST.LU(R3),R2 ;R2 = # of highest LUN BEQ MTEXIT ;If highest is zero (console), exit MOV MST.CT(R3),R4 ;R4 = Offset to console TCB .Assume MST.1T EQ 0 SUB @R3,R4 ;R4 = Diff from 1st TCB BEQ 1$ ;No difference, so LUN 0 is console MOV MST.ST(R3),R5 ;R5 = Size of TCB CLR R1 ;R1 = Quotient DIV$: INC R1 ;Divide diff by size of TCB SUB R5,R4 ; to get LUN of console BHI DIV$ ;Repeat until done... MOV R1,(PC)+ ;Save console LUN... CLUN: .WORD 0 ;for later reference 1$: CMP R2,CLUN ;Is this the Console? BEQ 4$ ;Yes...already set up .MTATC #AREA,#0,R2 ;Try to attach terminal BCS MTERR1 ;If carry set, can't! .MTGET #AREA,R3,R2 ;Get terminal's status BCS MTERR2 ;Can't! (Very Bad!!!) BITB #(<)DH11$!DZ11$>/400,M.TSTW(R3) ;Is line a DZ or DH? BEQ 6$ ;Nope, assume it's a DL... .Assume M.TSTS EQ 0 BIT #(<)REMOT$>,@R3 ;Remote line? BEQ 2$ ;Nope... BITB #(<)HNGUP$>/400,M.TSTW(R3) ;Is it on-line? BNE 5$ ;Branch if not 2$: CALL TSETUP ;Figure out baud rate ; and terminal type 3$: .MTRCT #AREA,R2 ;Reset CTRL/O .MTPRN #AREA,#HELLO,R2 ;Clear screen (if CRT) ; and say hello... .MTDTC #AREA,R2 ;Release it since we're done CALL LOGLUN ;Log terminal ID on console 4$: DEC R2 ;Are we finished? BPL 1$ ;No...go do another LUN MTEXIT: .EXIT ;We're done...exit .SBTTL Terminal ID Log Routines, Error Routines 5$: .PRINT #OFFLIN ;Log terminal offline BR 8$ ; and list LUN 6$: .Assume M.TSTS EQ 0 BIS #(<)TTSPC$!TCBIT$>,@R3 ;DL11 - Set terminal special mode ; and inhibit terminal wait MOV #ENDTBL,R4 ;Don't know speed... MOV #32,LOTIM ;Magic # for baud rate determination, ; reflects worse case situation, ; 50 baud rate on DL lines CALL TERMID ;Attempt to determine terminal type CALL RSET ;Set new status... BR 3$ ;Merge... LOGLUN: .PRINT #ATMSG ;Print 1st part of log CALL PRNLUN ;Print LUN .PRINT R1 ; the terminal ID, .PRINT #TINIT ; and .PRINT R4 ; baud rate RETURN PRNLUN: MOV R2,R0 ;Copy LUN into R0 SWAB R0 ;Put it in high byte 7$: ADD #(<)-10.*400>+1,R0 ;Divide by 10 with ;repeated subtracts BPL 7$ ;Q= Q-10, R= R+1 until ;overflow (V set) ADD #'0*400+'0+(<)10.*400-1>,R0 ;Correct ;Q & R then ASCIIfy... .TTYOUT ;Print Q... SWAB R0 ;R to low byte... .TTYOUT ;Print it... RETURN MTERR1: .PRINT #MSG1 ;Log attach error BR 8$ ;Merge MTERR2: .PRINT #MSG2 ;Log get status error 8$: CALL PRNLUN ;Include LUN .PRINT #CRLF BR 4$ ;Try next LUN .SBTTL Main Terminal Setup Subroutine TSETUP: MOV #SPTABL-2,R4 ;R4 => Baud rate table .Assume M.TSTS EQ 0 MOV @R3,MSTAT ;Save old status... .Assume M.TSTS EQ 0 BIS #(<)TTSPC$!TCBIT$>,@R3 ;Set special bits 10$: TST (R4)+ ;R4 => Next table entry .Assume M.TSTS EQ 0 BIC #LINSP$,@R3 ;Clear baud rate mask MOV (R4)+,R5 ;R5 = Baud from table .Assume M.TSTS EQ 0 BIS R5,@R3 ;Set it in CONFG1 CMP #ENDTBL,R4 ;Are we thru table? BEQ 14$ ;Yes...use as is MOV #32,LOTIM ;Magic # for .MRKT SWAB R5 ;Put mask in low byte SUB R5,LOTIM ;Subtract from magic # ; to get # ticks to wait CALL TERMID ;Try to get terminal ID BCS 10$ ;No dice... RSET: .Assume M.TSTS EQ 0 BIC #(<)TTSPC$!TCBIT$>,@R3 ;Clear special bits .Assume M.TSTS EQ 0 BIC (R1)+,@R3 ;Turn off unwanted options .Assume M.TSTS EQ 0 BIS (R1)+,@R3 ;Turn on desired options ;R1 => Terminal ID string 12$: MOV @R4,R4 ;R4 => ASCII baud rate 13$: .MTSET #AREA,R3,R2 ;Store status RETURN ;Return to caller 14$: CALL GETSP ;Get ASCII of baud rate BR 13$ ;Merge... TERMID: .MTSET #AREA,R3,R2 ;Set new status MOV #TTLIST,R5 ;R5 => List of Terminals 15$: MOV (R5)+,R1 ;R1 => Terminal specific ; character sequence BEQ 18$ ;End of table - leave! CALL TOUT ;Try to communicate... BCS 15$ ;Carry set = no dice ADD OUTCT,R1 ;R1 => Expected response BIT #1,R1 ;Odd address? BEQ 16$ ;No INC R1 ;YES! Make it even 16$: CMP MSGIN,(R1)+ ;Match? BNE 15$ ;Nope... CMP MSGIN+2,(R1)+ ;Still match? BNE 15$ ;Nope... RETURN ;Return with R1 => options 18$: MOV #UNKTT,R1 ;R1 => "Unknown terminal" SEC ;Set carry... RETURN .SBTTL Terminal I/O & Get Baud Rate Routines TOUT: MOVB (R1)+,INCNT ;Get 'what-are-you?' response length MOVB (R1)+,OUTCT ;Get 'what-are-you?' query length .MTOUT #AREA,R1,R2,OUTCT ;Send 'what-are-you?' query BCS 20$ ;Output error CLRB TFLG ;Clear flag CLR MSGIN+2 ;Init input buffer .MRKT #AREA,#WAITM,#CRTNE,#1 ;Set time-out 19$: TSTB TFLG ;Did time-out occur? BEQ 19$ ;Nope... .MTIN #AREA,#MSGIN,R2,INCNT ;Get response, 20$: RETURN ; (with carry status) GETSP: MOV #SPTABL,R4 ;R4 => baud rate table .Assume M.TSTS EQ 0 MOV @R3,R5 ;R5 = TCB config word 1 BIC #^C(<)LINSP$>,R5 ;Clear all but baud rate 21$: CMP (R4)+,R5 ;Compare it with table BEQ 22$ ;Branch if equal CMP #UNKSP,(R4)+ ;End of table? BNE 21$ ;Try another if not 22$: MOV @R4,R4 ;R4 => ASCII baud rate RETURN ;Return to caller .SBTTL Timeout Completion Routine CRTNE: INCB TFLG ;Set time-out flag RETURN ; to mainline ; Argument blocks & working storage INCNT: .WORD 0 ;Input byte count OUTCT: .WORD 0 ;Output byte count AREA: .BLKW 5 ;EMT argument block WAITM: .WORD 0 ;Time-out argument (MINUTES) LOTIM: .WORD 0 ;Lo order ticks STAT: .BLKW 8. ;Status block (8 words) .SBTTL Baud Rate Mask & ASCII Baud Rate Tables ; Baud rate table - in "best guess" order SPTABL: .WORD 7000,B9600 ;9600 baud ;Scopes .WORD 3400,B1200 ;1200 baud ;LA120 .WORD 2400,B300 ;300 baud ;LA36 .WORD 6000,B4800 ;4800 baud ;Scopes .WORD 5000,B2400 ;2400 baud ;Scopes .WORD 2000,B150 ;150 baud ;LA36 .WORD 1400,B134 ;134.5 baud ;IBM MSTAT: .WORD 0 ;Orig status ENDTBL: .WORD UNKSP ;End-of-Table ; => "Unknown baud" MSGIN: .BLKB 8. ;Response buffer TFLG: .BYTE 0 ;Time-out flag .EVEN .NLIST BEX B134: .ASCIZ /134.5 Baud/ B150: .ASCIZ /150 Baud/ B300: .ASCIZ /300 Baud/ B1200: .ASCIZ /1200 Baud/ B2400: .ASCIZ /2400 Baud/ B4800: .ASCIZ /4800 Baud/ B9600: .ASCIZ /9600 Baud/ .EVEN .SBTTL Terminal ID Tables TTLIST: ;Terminal List... .WORD VT100 .WORD VT52 .WORD LA120 .WORD LA34 .WORD VT55 .WORD 0 ;Table stopper ; DEC terminal command sequences VT100: .BYTE 4,3,C.ESC,'[,'c ;INCNT,OUTCNT,"W-A-Y" seq .EVEN .BYTE C.ESC,'[,'?,'1 ;Response .WORD CRLF$,(<)HWTAB$!BKSP$> ;Undesired, Desired options .ASCII / VT100/(<)200> ;ASCII terminal ID .EVEN VT52: .BYTE 2,2,C.ESC,'Z .EVEN .BYTE C.ESC,'/,0,0 ;VT52 response varies w/ model! .WORD CRLF$,(<)HWTAB$!BKSP$> .ASCII / VT52 /(<)200> .EVEN LA120: .BYTE 4,3,C.ESC,'[,'c .EVEN .BYTE C.ESC,'[,'?,'2 .WORD 0,0 .ASCII / LA120/(<)200> .EVEN LA34: .BYTE 4,3,C.ESC,'[,'c .EVEN .BYTE C.ESC,'[,'?,'3 .WORD 0,0 .ASCII / LA34 /(<)200> .EVEN VT55: .BYTE 2,2,C.ESC,'Z .EVEN .BYTE C.ESC,'E,0,0 .WORD CRLF$,(<)HWTAB$!BKSP$> .ASCII / VT55 /(<)200> .EVEN .SBTTL Message & Text Initialization String ; Message Text... MSG1: .ASCII /?Cannot attach terminal LUN:/(<)200> MSG2: .ASCII /?Status error - LUN:/(<)200> ATMSG: .ASCII /Attaching LUN:/(<)200> TINIT: .ASCII / initialized at /(<)200> UNKSP: .ASCIZ /unknown baud rate/ UNKTT: .ASCII / unidentifiable/(<)200> OFFLIN: .ASCII /Terminal offline - LUN:/(<)200> CRLF: .ASCIZ // ; Clear screen & say hello character string... HELLO: .ASCII (<)C.ESC>"[2J" ;VT100 Erase screen .ASCII (<)C.ESC>"" ;VT52 "Exit hold screen mode" .ASCII (<)C.ESC>"H"(<)C.ESC>"J" ;VT52 HOME & "Erase-to-End-of Screen .ASCII (<)C.CR>(<)C.LF> ;CRLF (for hardcopy) .ASCIZ (/TERMINAL INITIALIZED/) .EVEN .END MTYSET ;End of program (The following gives you a 10 point code-example font) defcodexamplefonttenpointmono (Using Two or More Terminals Without the Multiterminal Feature\ nomttyterm_sec)

The following sections describe methods you can use to support two terminals on a system that has not been generated for multiterminal support. The methods pertain only to systems on which there is more than one DL controller and no more than one terminal is to be available at any one time. If your system includes one DL controller and either DH or DZ controllers, you must use a built multiterminal monitor, as described in (mttyterm_sec).

There are several situations in which you may need to use more than one terminal, but you do not need any of the special features available through the multiterminal programmed requests. The following sections describe some of those situations and show how to arrange the terminals. (A Video Console Terminal and a Hardcopy Printing Terminal)

A typical situation that arises in RT--11 applications is the case in which it is desirable to use a video terminal as the background console terminal and a hardcopy terminal as a line printer. The next two sections describe the procedures to use, depending on whether the video terminal or the hardcopy terminal is the boot-time console. (The Video Terminal Is the Boot-Time Console\VIDEOCON_SEC)

If your video terminal is the boot-time console, it is simple to use a hardcopy printing terminal as a line printer. (Note that the hardcopy terminal must be on a DL interface to use this procedure.) You set up the vectors and CSR addresses for the hardcopy terminal in the LS device handler file (by using the SET LS: commands described in the (sug_book)) and install LS. You can then simply assign LP to LS and proceed to use the hardcopy terminal as a line printer.

Under many circumstances, it may be desirable to have the hardcopy terminal become the console terminal. Use the procedure described in (SWITCON_SEC) to do this. (The Hardcopy Terminal Is the Boot-Time Console)

You can use any of the following procedures to make the hardcopy terminal the line printer when the hardcopy terminal is also the boot-time console. Both the hardcopy terminal and the video terminal must be on a DL interface.

In (Procedure 1 )you can perform a system generation (without including the multiterminal feature) to make the video terminal appear to be the boot-time console. Note that the hardcopy terminal remains the hardware console interface. That is, you must still type the name of the system device on the hardcopy terminal in response to the boot prompt. However, RT--11 does print its boot message on the video terminal. Once the system is bootstrapped, you can use the LS handler to access the hardcopy terminal as a line printer.

In (Procedure 2 )you can change your system configuration so that the video terminal is the boot-time console, and the hardcopy terminal is on a local DL interface. Then, you can use the procedure outlined in (VIDEOCON_SEC).

In (Procedure 3 )you can use a special program to switch the background console to the video terminal. Except that the default boot-time console defaults to the hardcopy terminal after each reboot, this is similar to procedure 1, above. You can use the LS handler to access the hardcopy terminal as a line printer. (SWITCON_SEC) shows the program you run to use Procedure 3.

(Procedure 4 )is similar to Procedure 3, except that you alter the monitor image on a mass storage device instead of in memory. This procedure is useful only in systems without the multiterminal feature and only for another DL-like interface. (VECMOD_FIG) shows the patch for Procedure 4. You must supply the correct value for the vector, CSR, protection offset, and protection code (see (lowmembitmap_sec)) for your application.

(Patch for Procedure 4\VECMOD_FIG) (wide\MULTIPAGE) ! Permanent modification of monitor using CSR and Vector addresses ! CSR = 175620-175626 / Vec = 310-316 (.)(R SIPP (RET\TEXT)) (*)(monitr.SYS (RET\TEXT)) (! monitr represents the file name) (Base? )(;S (RET\TEXT)) (! of the monitor file you are) (Search for? )(60 (RET\TEXT)) (! changing) (Start? )(5100 (RET\TEXT)) (End? )(5200 (RET\TEXT)) (Found at nnnnnn) (Base? )(nnnnnn (RET\TEXT)) (Offset? )((RET\TEXT)) ( Base Offset Old New?) (nnnnnn 000000 000060 )(310 (RET\TEXT) )(! New vector) (nnnnnn 000002 xxxxxx )((CTRL/Z\BOX) (RET\TEXT)) (Offset? )(6 (RET\TEXT)) ( Base Offset Old New?) (nnnnnn 000006 000064 )(314 (RET\TEXT) )(! New vector plus 4) (nnnnnn 000010 xxxxxx )((CTRL/Z\BOX) (RET\TEXT)) (Offset? )((CTRL/Z\BOX) (RET\TEXT)) (Base? )($RMON(RET\TEXT) )(! Find the value of $RMON on your) (Offset? )(304 (RET\TEXT) )(! link map.) ( Base Offset Old New?) ($RMON 000304 177560 )(175620 (RET\TEXT) )(! New CSR) ($RMON 000306 177562 )(175622 (RET\TEXT) )(! New CSR) ($RMON 000310 177564 )(175624 (RET\TEXT) )(! New CSR) ($RMON 000312 177566 )(175626 (RET\TEXT) )(! New CSR) ($RMON 000314 177777 )((CTRL/Z\BOX) (RET\TEXT)) (Offset? )(342 (RET\TEXT) )(! Offest for protection byte) ( Base Offset Old New?) ($RMON 000342 000000 )(17 (RET\TEXT) )(! Enable protection) ($RMON 000344 000000 )((CTRL/Y\BOX)) (*)((CTRL/C\BOX)) (.) (Switching the Console Terminal\SWITCON_SEC)

RT--11 distributes a program called CONSOL that you can use to switch the console terminal to another terminal in a system without the multiterminal special feature. Edit the source file to supply values for the CSR and vector for the new console; use the symbols CSRAD and VEC. To switch the console back and forth between two terminals, maintain two copies of the program, one for each terminal. The terminal interfaces must be DL11s; the program will not work on DH11 or DZ11 interfaces.

To switch the console terminal with DH11 or DZ11 interfaces, you must perform a system generation for multiterminal support and request handler hooks support for LS. See (mtty_ls_sec) for information. (End of Chapter)