(edited 19-sep-91 for editor's comments) (System Components and Memory Layouts\SCM_CHAP)

This chapter presents a somewhat idealized view of the operating system and introduces the various components without providing great detail. You should look further in this manual and in the (dev_book) and (vff_book) for more information on particular components or concepts that are introduced here. Consult the (mas_book) for page references.

RT--11 distributes a library of system data structures, SYSTEM.MLB, described in (system_app). Throughout this chapter (and the rest of the manual), the symbols that define data structures and the elements of those structures are as defined in SYSTEM.MLB.

This chapter introduces the components of the RT--11 system that can be memory resident. It provides maps of physical and virtual memory that show where the components are located, and it indicates how their positions can change dynamically. This chapter covers components divided into two groups: static components, which have a relatively fixed position in memory, and dynamic components, whose locations are changeable.

The location of system components in physical memory is determined by hardware and the monitor. In mapped systems, components reside at virtual addresses. A virtual address does not necessarily (or probably) correspond to the same physical address. In mapped systems, a component that is described as residing at location 40, for example, probably does not reside at physical location 40, but rather at a virtual location to which it is mapped. The location of components in mapped systems is described more fully in (xm_chap).

The components are arranged to leave the most space available for user programs and to be flexible. Flexibility is obtained by positioning the components after determining the total amount of memory at bootstrap time. Normally, you do not have to take any special steps to move a program that runs under a particular monitor from one PDP--11 computer to another. (Static Components)

The static components have fixed locations in memory. Their actual addresses vary from one PDP--11 computer to the next. Unmapped addresses correspond directly to physical memory addresses. Mapped (virtual) addresses do not necessarily correspond directly to physical memory addresses.

The static components or areas are as follows: (UNNUMBERED) Trap vectors System communication area Interrupt vectors Background job Resident Monitor (RMON) System device handler I/O page (Trap Vectors)

(TRAPVEC_TAB) shows the memory locations from 0 to 36, an area that contains the trap vectors. A plus sign (+) marks the locations that are reserved for use by RT--11. You should not attempt to modify these locations; a bitmap protects them each time you load a program. An asterisk (*) marks the locations that your programs can use. (TRAPVEC_FIG) is a summary of the trap vector area information. (Trap Vectors\TRAPVEC_TAB) (2\9) (Location\Contents) (0,2+\Monitor restart, executes the .EXIT request and returns control to the monitor (has additional uses in mapped systems).) (4,6+\Odd address and bus time-out trap; RT--11 sets this to point to its internal trap handler.) (10,12+\Reserved instruction trap; RT--11 sets this to point to its internal trap handler.) (14,16*\BPT (breakpoint trap), T-bit trap (used by debugging utility programs).) (20,22*\IOT, input/output trap.) (24,26*\Powerfail and restart trap. Your programs can use this location unless you included support for powerfail restart through system generation. If your system includes the powerfail restart feature, locations 24 and 26 are reserved for use by RT--11.) (30,32+\EMT, emulator trap; RT--11 uses this for programmed requests.) (34,36*\TRAP instruction. Note that you cannot use the TRAP instruction in assembly language subroutines linked with FORTRAN, DIBOL, or BASIC programs; these languages use the TRAP instruction for internal error reporting.)
(Trap Vector Area\TRAPVEC_FIG) (POSTSCRIPT\S560C2TRAPVEC_FIG.EPS\27) (System Communication Area)

The memory locations from 40 through 57 are called the (system communication area\bold). This area holds information about the job currently executing, as well as certain information normally used only by the monitor.

The diagram in (SYSCOM_FIG) is a summary of the system communication area information. (SYSCOM_TAB) describes the contents of each location. The symbols in the table are from SYSTEM.MLB.

(2-2)

(System Communication Area\SYSCOM_FIG) (postscript\mlo-007360b\24)

(2-2)

(System Communication Area (.SYCDF)\SYSCOM_TAB) (3\8\8) (Location\Symbol\Contents) (40,41\$USRPC\Start address of job. When you link a file to create an RT--11 executable image, the linker sets the word at address 40 in the program's file to the starting address of the program. This word is loaded into memory location 40 at run time. When a foreground job executes, the FRUN processor relocates this word to contain the actual starting address of the program.) (42,43\$USRSP\Initial value of stack pointer. If the user program does not set this value with an .ASECT directive, the value defaults to 1000 or to the top of the program's absolute section, whichever is larger. You can use the linker /B:n option to set the initial value of the background job's stack pointer. If a foreground program does not specify a stack pointer in this word (by using an .ASECT directive), the FRUN processor allocates a default stack of 128(10) bytes immediately below the program, and the initial stack pointer value is 1000, relative to the base of the foreground job.) (44,45\$JSW\Job Status Word (JSW). This is a flag word for the monitor. The monitor maintains some of the bits itself, and your program can set or clear others. See (JSW_SEC) for more information on the JSW.) (46,47\$UFLOA\USR load address. This word is normally 0, but you can set it in the file or at run time to any valid word address in your program. If this word is 0, the USR loads in its default location through an address contained in offset 266 ($USRLC of .FIXDF) of RMON. If this word is not 0, the USR loads at the address it specifies, unless the USR is set NOSWAP. This location is cleared by an exit to KMON (via .EXIT, CTRL/C, or fatal error).) (50,51\$USRTO\High-memory address. In this word the monitor maintains the highest address your program can use. The linker sets this word initially to the high-limit value. You can modify it by using the .SETTOP programmed request. Your program must never modify this word directly. In mapped systems, locations 50 and 51 in the file contain the address that is the top of the root section plus the low memory (/O) overlays. In memory, locations 50 and 51 contain the same value unless the program issues a .SETTOP. In this case, these locations contain the highest available virtual address (see (XMXSVJ_SEC)).) (52\$ERRBY\EMT error code. If a monitor request results in an error, the code number of the error is always returned in byte 52 in memory, and the carry bit is set. Each monitor call has its own set of possible errors. Byte 52 in the job's file has a different meaning (see (VFF_BOOK)). $ERRBY is defined in the .ERRDF macro in SYSTEM.MLB. Always address location 52 as a byte, never as a word, since byte 53 has a separate function. ) (53\$USRRB\User program error code (USRRB). If a user program encounters errors during execution, it indicates the error by using this byte in memory. See (USERERRBYTE_SEC) for more information about this byte. See (VFF_BOOK) for its meaning in the job's file.)) (54,55\$SYPTR\Address of the beginning of RMON. RT--11 always loads the monitor into the highest available memory locations of low (rather than extended) memory; this word in memory points to its first location. Never alter this word -- doing so causes RT--11 to malfunction. ) (56\$TTFIL\Fill character (7-bit ASCII). Some very old terminals require fill (null) characters after printing certain characters. Byte 56 in memory should contain the ASCII 7-bit representation of the character after which fills are required. See (VFF_BOOK) for the meaning of this bit in the job's file.) (57\$TTNFI\Fill count. This byte in memory specifies the number of fill characters that are required. The number of characters is determined by hardware. If bytes 57 and 56 are 0, no fill is required. See (VFF_BOOK) for the meaning of this byte in the job's file.) (User Error Byte\USERERRBYTE_SEC)

KMON examines the (user error byte )when a program terminates. If your program has reported a significant error in this byte, KMON can abort any indirect command files in use. This prevents spurious results from occurring if subsequent commands in the indirect file depend on the successful completion of all prior commands.

A program can exit in one of the following states: (UNNUMBERED) Success Warning Error Fatal Unconditionally fatal error

The program status is (success \bold)when the execution of the program is free of errors.

The (warning \bold)status indicates that warning messages occurred, but the program ran to completion.

The (error \bold)status indicates that a user error occurred and the program did not run to completion. This level is also used by RT--11 system utility programs when they produce an output file even though it may contain errors. For example, a compiler can use the error level to indicate that an object file was produced, but the source program contains errors. Under these conditions, execution of the object file will not be successful if the module containing the error is encountered.

The (fatal \bold)status indicates that the program did not produce any usable output, and any command or operation depending on this program output may not execute properly. This type of error can result when a resource needed by the program to complete execution is not available -- for example, insufficient memory space to assemble or compile an application program.

The (unconditionally fatal \bold)status indicates that not only has an operation completely failed, but that the integrity of the monitor itself is questionable.

Utility programs and KMON always set the user error byte to reflect the result of each monitor command you issue. By default, indirect command files abort when there has been any monitor command error. However, by issuing the SET ERROR NONE command, you guarantee that indirect command files will continue to execute unless they encounter an unconditionally fatal error. Only unconditionally fatal errors that indicate problems within KMON itself abort indirect files at the SET ERROR NONE level. (USERERRBYTE_TAB) shows the bits of byte 53, their status, and the status code printed by the RT--11 system utility program messages.

(User Error Byte ($USRRB), .UEBDF\USERERRBYTE_TAB) (5\8\8\8\12) (Bit\Mask\Symbol\Status\RT--11 Message) (0\1\SUCCS$\Success\?PROG-I-text, or none) (1\2\WARN$\Warning\?PROG-W-text) (2\4\ERROR$\Error\?PROG-E-text) (3\10\FATAL$\Fatal\?PROG-F-text) (4\20\UNCON$\Unconditional\?PROG-U-text)

Bits 5 through 7 of the user error byte are reserved for Digital's future use; do not use them in your programs. Programs should never clear byte 53 and should set it only through a BISB instruction, as the following example shows. If more than one bit is set at any given time, the highest bit is the one that RT--11 recognizes.

.LIBRARY "SRC:SYSTEM" .MCALL .UEBDF .SYCDF .UDBDF .SYCDF ERROR: BISB #ERROR$,@#$USRRB ;SET ERROR STATUS CLR R0 ;HARD EXIT .EXIT

Note that this byte is meaningful only for KMON and for background jobs. It was designed to be used by system utility programs and language processors, which run as background jobs. A foreground job can set it, but that action has no effect on the system. (Job Status Word (JSW)\JSW_SEC)

Bytes 44 and 45 make up the (Job Status Word) (JSW). (JSW_TAB) shows the meanings of the bits in this word. The bits marked with a dollar sign ($) can be set by the monitor. The bits marked with an asterisk (*) can be set by a user program during execution. Bits marked with a plus sign (+) are set at load time from the program image. Note that some bits can be set at both load and run time. Unused bits are reserved for future use by Digital.

(Job Status Word ($JSW) (.JSWDF)\JSW_TAB) (3\6\8) (Bit\Symbol\Meaning When Set) (15\\Reserved.) (14+*\TTLC$\Lowercase bit. Disables automatic conversion of typed lowercase to uppercase characters. EDIT sets it when you type the EL command.) (13+*\RSTRT$\Reenter bit. Indicates that a program can be restarted from the terminal when you type the REENTER command.) (12+*\TTSPC$\Special mode terminal bit. Indicates that the job is in a special keyboard mode of input. Refer to the explanation of the .TTYIN and .TTINR programmed requests in the (sml_BOOK) for details.) (11+*\CHNIF$\Pass line to KMON bit. Indicates, when a program exits, that the program is passing a command line to KMON. This action causes any open indirect file to abort. The command line should be stored in the CHAIN information area, locations 500 through 776. R0 must be cleared before exiting. Refer to the example program for .EXIT in the (sml_BOOK). This bit is ignored with foreground or system jobs.) (10$+\VIRT$\Virtual image bit (mapped systems only). Indicates that the job to be loaded is a virtual job. You must set this bit yourself in the executable file before you attempt to run the program. Do this at assembly time by using an .ASECT directive and modifying the $JSW, or before run time by patching this location in the file. See (XM_CHAP) for more information on virtual jobs.) (9+*\OVLY$\Overlay bit. This bit is set by the linker if the user program uses the linker overlay feature. You can set OVLY$ in the file if you want to have channel 17 left open on the program's file (even if the program is not overlaid.)) (8$+\CHAIN$\CHAIN bit. This bit can be used in two ways. If it is set in a job's save image, the monitor always loads words 500 through 776 from the save file when the job is started. (These words are normally used to pass parameters from one job to another across a .CHAIN or to pass a copy of the command string if the program was invoked by RUN or CCL.)

The monitor sets this bit when loading the job only if the job was actually entered with a .CHAIN.) (7$\VBGEX$\VBGEXE is executing in the background (mapped systems only). Bit is set by VBGEXE and should not be changed by a job. Futher, the VBGEX$ bit in the $JSX word (the $JSW extension) has a different meaning.) (6+*\TCBIT$\Inhibit terminal wait bit. Inhibits the job from entering a console terminal wait state. For more information, refer to the sections concerning .TTYIN, .TTINR, .TTYOUT, and .TTOUTR in the (sml_BOOK).) (5+*\SPXIT$\Special chain exit bit. If set when a program exits, text in the chain area, locations 510 to 777, is passed to KMON and appended to the command buffer. R0 must be cleared before exiting. This does not abort an open indirect file. Refer to bit 11, above. If you pass multiple command lines, any line containing the @ indirect file command must be the last line of the series.) (4+*\EDIT$\Disable single-line editor bit. Setting this bit disables all single-line editor functions.) (3+*\GTLIN$\Nonterminating .GTLIN bit. When GTLIN$ of the $JSW is set and your program encounters a CTRL/C in an indirect command file, the .GTLIN request collects subsequent lines from the terminal. If you then clear GTLIN$, the next line collected by the .GTLIN request is the CTRL/C in the indirect command file; this causes the program to terminate. Further input will come from the indirect command file if there are any more lines in it. The LINK, DUP, SIPP, SLP, QUEMAN, SRCCOM, and LIBR utilities make use of this feature. To activate it in an indirect file, put an up arrow (^) followed by a C on a line by itself in the file. This causes the utilities to accept the response from the terminal instead of taking it directly from the file.

The following indirect file shows how to obtain a response from the terminal: RUN LINK TEST,TEST=MOD1,LIB/I ^C

All further input to the linker will come from the terminal, as a result of the CTRL/C in the indirect command file.) (2$*\VRUNV$\Job was run by the V or VRUN command (mapped systems only). If set, a .CHAIN request will run the chained-to program in the completely virtual environment and leave VRUNV$ set.) (0-1\\Reserved.) (Interrupt Vectors)

(INTVEC_TAB) shows the locations in the low-memory area that are reserved for interrupt vectors. (RT--11 does not support all the devices in the table.) (INTVEC_FIG) shows how the interrupt vector area relates to the rest of memory.

(Interrupt Vectors\INTVEC_TAB) (2\8) (Location\Contents) (60,62\DL11: Console terminal input ) (64,66\DL11: Console terminal output ) (70,72\PC11: Paper tape reader) (74,76\PC11: Paper tape punch) (100,102\KW11--L: Line clock) (104,106\KW11--P: Programmable clock) (110,112\Reserved) (114,116\Memory system errors: parity, cache, and uncorrectable ECC errors) (FIRST) (120,122\XY11: X/Y Plotter) (124,126\DR11-B: DMA interface) (130,132\AD01: Analog to digital subsystem) (134,136\AFC11: Analog input subsystem) (140,142\AA11: Digital to analog subsystem) (144,146\AA11: (requires two vectors)) (150,152\MSCP device number 1) (154,156\MSCP device number 0) (160,162\RL11/RLV11: RL01/RL02 Disk cartridge) (164,166\Reserved) (170,172\LP/LS/LV11 Line printer number 1) (174,176\LP/LS/LV11 Line printer number 2) (200,202\LP/LS/LV11 Line printer number 0 (includes LA180 parallel interface)) (204,206\RH11,RH70: RS03/RS04 fixed-head disk RF11: fixed-head disk) (210,212\RK611/RK711: RK06/RK07 disk cartridge) (214,216\TC11: DECtape) (220,222\RK11/RKV11: RK05 disk cartridge) (224,226\RH11/RH70: TU16, TE16, TU45 magtape TM11: TU10/TE10 magtape TS03: magtape TS11: magtape first controller (others float) TS05/TSV05: magtape) (230,232\CD11/CM11/CR11: card reader) (234,236\UDC11: Digital control subsystem) (240,242\PIRQ (programmed interrupt request)) (244,246\FPP or FIS floating-point exception) (250,252\KT11: memory management fault) (254,256\RP11: RP02/03 disk RH11/RH70: RP04/05/06/RM02/03 Disk) (LAST) (260,262\TMSCP Unit 0 (bootable unit); TA11: cassette tape) (264,266\RX11/RXV11/RX211/RX2V1: RX01, RX02 diskette) (270,272\LP/LS/LV11 line printer number 3) (274,276\LP/LS/LV11 line printer number 4) (300,302\Start of the floating vector area) (320,322\VT11/VS60 Graphics terminal (requires three vectors)) (324,326\VT11/VS60 ) (330,332\VT11/VS60 )
(Interrupt Vector Area\INTVEC_FIG) (postscript\ml0-7361b\31.5) (Background Job)

The (background job\bold) in the single-job and multi-job systems is essentially identical for the purpose of this discussion. (BGJOB_FIG) shows the general structure of an unmapped background job, as well as its relative location in memory. (xm_chap) describes and illustrates background job loading in a mapped system.

(Background Job\bgjob_fig) (postscript\mlo-007362b\31.5)

There are five ways in which RT--11 can load a background job: RUN, R, VRUN, V, and .CHAIN. They are described in the following sections. (RUN Command)

One way to load a job is to use the (RUN) command. The RUN command is the same as the GET and START commands combined. First, if the SAV file is not on the system device, RUN (or GET) loads the handler for the proper device. When this occurs, KMON and the USR, which normally occupy the space above the background job and below RMON, relocate themselves, if necessary. For more information on the USR and KMON, see later sections of this chapter. For information on virtual and completely virtual background job loading, see (xm_chap).

The space available for background job loading consists of the background job area, the space occupied by KMON, and (in unmapped systems) the space occupied by the USR (unless the USR is set to NOSWAP). In mapped systems, the USR is always resident. If the job needs more space, an error message prints and then control returns to KMON.

With mapped systems, you can often run a background job in the completely virtual environment when there is insufficient memory to run it otherwise. See (xm_chap) for information about the (SET RUN VBGEXE) command, and other information about the completely virtual environment.

Once the job passes the size tests, RUN loads from the file those memory locations (0 through 476) that are not protected. KMON reads block 0 of the .SAV file into an internal USR buffer. It extracts information from locations 40--64 and 360--377 (the CCB bitmap, described further in this section). Using the protection bitmap (called $LOWMA), which resides in RMON, KMON checks each word in block 0 of the file. It does not load locations that are protected, such as location 54 and the device interrupt vectors. It loads unprotected locations into memory from the USR buffer. Next, KMON sets $USRTO (location 50) to the top of the user program.

By default, the RUN command causes RT--11 to load main memory locations 500 through 776 with a copy of the command string following RUN ddn:filname. This enables a program to make use of the command string that was used to invoke it.

If required, RT--11 can load locations 500 through 776 from the save image of the program rather than with a copy of the command string. To do this with the RUN command, you must set CHAIN$ (bit 8) in $JSW (offset 40) in block 0 of the save image. CHAIN$ must be set in the file, not in memory, after the program is loaded.

For example, the command: (RUN SY:FOO INPUT OUTPUT)

returns the string INPUT OUTPUT in locations 500 through 776 if CHAIN$ in $JSW in block 0 of SY:FOO.SAV is clear. If CHAIN$ is set, RT--11 loads locations 500 through 776 from the save image.

To load locations 1000 and up, RUN examines the (core control block), called the CCB, which starts at location 360 in the job file and goes through location 377. The CCB is restricted for use by the system. The Linker stores the program memory usage bits in these eight words, which are called a bitmap. Each bit represents one 256-word block of memory and is set if the program occupies any part of that block of memory. Bit 7 of byte 360 corresponds to locations 0 through 777; bit 6 of byte 360 corresponds to locations 1000 through 1777, and so on. The monitor uses this information when it loads the program. If KMON is in memory space that the program needs to use, KMON puts the block of the .SAV file into a USR buffer and then moves it to the file SWAP.SYS.

Finally, when it is time to begin execution of the program, KMON transfers control to RMON. RMON reads the parts of the program, if any, that are stored in SWAP.SYS into memory, where they overlay KMON and possibly the USR. The monitor keeps track of the fact that KMON (and perhaps the USR) are swapped out, and execution of the program begins. (RUNCOMM_FIG) summarizes how the RUN command loads a job image into memory.

When the program terminates, RMON reads KMON and the USR back into memory from the monitor .SYS file. The memory area up to the bottom of KMON contains the background job image. If the job overlaid KMON and SET EXIT SWAP is in effect, the remainder of the job image is first written out to SWAP.SYS. This procedure allows the EXAMINE and DEPOSIT commands to operate on the job image on disk, even though KMON has written over the job's locations in memory, and the RESTART command can restart the program. If SET EXIT NOSWAP is in effect, program termination is faster, but you cannot use the EXAMINE, DEPOSIT, or RESTART commands.

(RUN Command\RUNCOMM_FIG) (postscript\mlo-007363b\44.5) (R Command)

The (R command \bold)is identical to the RUN command except the default location for the utility being run with the R command is SY. (VRUN Command)

The (VRUN command\bold) runs a job in the completely virtual environment under mapped monitors. The default location for the utility being run is DK. The completely virtual environment is described in (xm_chap). (V Command)

The (V command\bold) is identical to the VRUN command except the default location for the utility being run with the V command is SY. (.CHAIN Request\chain_sec)

The fifth way to load a job is to chain to it from another job. The first job issues the (.CHAIN )programmed request to do this. The second job can use information in memory locations 500 through 776 that was placed there by the first job. Consequently, the only difference between loading a job with the RUN command and starting a job by chaining to it is that chaining does not load memory locations 500 through 776 from the second file unless you set the chain bit in the $JSW of the second file at assembly time.

Note that chaining to a FORTRAN job does not preserve channel information from the previous job. This is because FORTRAN itself closes the channels and discards the impure area. (Resident Monitor (RMON))

The (Resident Monitor \bold)(RMON) is the RT--11 monitor component that is always resident in memory. When you bootstrap an RT--11 system, the bootstrap routine determines how much main memory is available. RMON loads at the highest possible low memory address, just below the system device handler. It does not move during system operation.

RMON contains routines to handle the programmed requests in RT--11. It also contains the background job's impure area, the error processor, timer routines, console terminal service routines, USR swap routines, and other monitor functions. (RMON_FIG) shows a summary of the contents of RMON. See (RMON_CHAP) for more information.

Link maps of the distributed RT--11 monitors are part of the distribution kit. They exist as files named RTxx.MAP, where (xx) is the monitor name, such as RTXM.MAP. (MONPSECT_TAB) lists the p-sects that make up RMON and KMON.

(Resident Monitor (RMON)\RMON_FIG) (postscript\mlo-007364b\25.5)
(Monitor P-sects\MONPSECT_TAB) (2\8) (P-sectName\Contents) (RT11\KMON) (RMNUSR\USR buffer and code) (RTDATA\RMON fixed offsets and database) (OWNER$\$OWNER table) (UNAM1$\$UNAM1 table ) (UNAM2$\$UNAM2 table) (PNAME$\$PNAME table) (ENTRY$\$ENTRY table) (STAT$\$STAT table) (DVREC$\$DVREC table) (HSIZE$\$HSIZE table) (PNAM2\$PNAM2 table) (DVSIZ$\$DVSIZ table) (DVINT$\$DVINT table) (MTTY$\Multi-terminal terminal control blocks) (RMON\Resident Monitor) (USRRMN\RMON code in the USR source) (XMSUBS\Extended Memory routines) (MTEMT$\Multi-terminal programmed requests ) (MTINT$\Multi-terminal interrupt service) (STACK$\RMON stacks) (PATCH$\Patch space) (OVLYnn\KMON overlays containing command processors) ($LAST$\Last monitor .PSECT) (System Device Handler)

The (system device handler \bold)is the handler for the device from which the system was bootstrapped. (dev_book) describes the structure of a system device handler in detail.

At bootstrap time, the monitor loads any system support handlers and then binds together with the system device handler file found on the system volume. The system device handler is loaded into memory immediately below any system support handler or the I/O page. RMON is loaded below the system device handler. Once it is read into memory, the system device handler remains resident and does not change its location. (SYSDEVHAN_FIG) shows where the system device handler resides in memory.

(System Device Handler\SYSDEVHAN_FIG) (postscript\mlo-007365b\31.5) (I/O Page)

The highest 4K words(1\An LSI-11 with MSV-11DD and memory jumper and the SBC--11/21 have a 2K-word I/O page and 30K words of regular memory. Throughout this manual, however, a 4K-word I/O page is assumed.) of addressing space in PDP--11 computers are reserved for device control, status, and data buffer registers. This area is called the (I/O page\bold). In addition to the device registers, it may also contain the Processor Status word and, for some processors, the system's general registers (R0 through R5), the stack pointer (R6), and the program counter (R7). Locations in the I/O page are directly addressable by application programs and system software, but since they are bus addresses and not memory locations, they cannot be used to store code and data. (IOPAGE_FIG) shows where the I/O page is addressed in relation to the rest of the system components. You can find more information on the I/O page and the device registers for your own processor and peripherals in the (PDP11_BOOK), the (PPER_BOOK), the (MPH_BOOK), the (MPER_BOOK), and in most hardware manuals.

(I/O Page\IOPAGE_FIG) (postscript\mlo-007366b\31.5) (Dynamic Components)

Dynamic components do not always load into fixed places in memory. Once loaded, the USR and KMON can continue to shift location based on the state of the rest of the system. The dynamic components and areas are as follows: (UNNUMBERED) Device handlers (device drivers) and free space Foreground and system jobs User Service Routine (USR) Keyboard Monitor (KMON)

As you read about the rest of the dynamic components, you will also learn how the system manages free space in memory. You have already seen how the system device handler and RMON load at the highest possible addresses, and how the background job begins loading at location 1000 and up. The strategy behind the way the system manages free memory is that it attempts to make the most space available for foreground and background application jobs. (Device Handlers and Free Space\DEVHANFRESPC_SEC)

(Device handlers \bold)(drivers) are routines that provide the interface to the computer's hardware devices. The handlers (drive\bold), or (service\bold), peripheral devices and take care of moving data between memory and devices. (dev_book) describes device handlers in greater detail.

RT--11 uses a dynamic scheme to provide memory space for loaded handlers, foreground jobs, system jobs, indirect file and command line expansion. Memory is allocated in the region above KMON/USR and below RMON. If there is not enough memory in this region (initially, after the system is bootstrapped, there is none), memory is taken from the background region by (sliding down) the KMON and USR the required number of words.

When memory allocated in this manner is released, the memory area is returned to a singly-linked free memory list, the head of which is located in RMON. Any contiguous blocks are concatenated into a single larger block. A block found to be contiguous with the KMON/USR is reclaimed by (sliding up) the KMON/USR, thus removing the block from the list.

(SBS2LH_FIG) shows an SB system with a small application job and two loaded device handlers. When you issue the LOAD monitor command, the handler loads into the memory area just above the USR and KMON. The USR and KMON slide down in memory to provide the handlers with enough space, leaving less space for the user program.

(SB System with Two Loaded Handlers\SBS2LH_FIG) (postscript\mlo-007367b\30.5)

Once handlers are brought into memory, they do not move up or down, as the USR and KMON do. (SBS1UH_FIG) shows the system after the monitor UNLOAD command has removed one handler from memory. In the figure, the free space above handler #2 has not been reclaimed and is available for later use. A handler that is the same size as the empty space, or smaller, can be loaded there without causing any other components to move.

(SB System with One Handler Unloaded\SBS1UH_FIG) (postscript\mlo-007368b\30.5)

(SBS2UH_FIG) shows the system after the second handler was unloaded. This time there is free space directly above the USR (the space formerly occupied by the two handlers), so the USR and KMON slide up into it, making more space available for the user program.

(SB System with Both Handlers Unloaded\SBS2UH_FIG) (postscript\mlo-007369b\30.5) (Foreground and System Jobs)

Foreground and system jobs are described in detail in the the (int_book). In a multi-job system, (foreground jobs \bold)and (system jobs \bold)are essentially identical. The RT--11 system jobs in the multi-job environment are the error logger (ERRLOG), the on-line index utility (INDEXX), the keypad editor (KEX), the file queuing program (QUEUE), the transparent spooler program (SPOOL), and the virtual terminal communication program (VTCOM). For more information on the foreground and system job loading environment, see (xm_chap).

(FGJOB_FIG) shows the general structure of an unmapped foreground job, as well as its relative location in memory. Handlers loaded after the foreground job are placed below it in memory, and above the USR. (See (RMON_CHAP).)

(Foreground Job\FGJOB_FIG) (postscript\mlo-007370b\30.5) (Differences Between Foreground and Background Jobs)

There are some significant differences between foreground and background jobs. (NUMBERED) The impure area (described in (RMON_CHAP)) for the foreground job is located immediately below the job area itself. For a background job, the impure area is always in RMON. Another major difference is that a foreground job cannot dynamically change its memory allocation: the job is a fixed size. You can only change the low memory allocation at FRUN time by using the /BUFFER:n option. See (xm_chap) for further information on memory allocation. You must load all the handlers a foreground job needs before the job attempts to use them. A background job, on the other hand, can use the .FETCH programmed request to load a handler when it is needed. For FB systems only, if the USR is swapped out and the foreground job needs it, the foreground job must allocate 2K words of program space for the USR to swap over. (See (USR_SEC) for more information on the USR.) (FRUN Command)

The (FRUN command \bold)loads the foreground program into memory and starts execution. The (SRUN command\bold), which performs the same functions for system jobs, is essentially identical. You can also use FRUN or SRUN to start a virtual .SAV job, since these jobs do not require relocation. (See (XM_CHAP) for more information on virtual jobs.) Before you start a job with FRUN, you must load all the handlers the job requires. You can use the FRUN/PAUSE option, load the handlers and then resume the foreground job. In any case, the handlers need to be loaded only before the job actually uses them.

FRUN first opens the .REL file or virtual .SAV file, reads its first block (locations 0 through 776), and determines how much memory the job requires. The job's total memory requirement is equal to the sum of the program itself (as indicated by $USRTO (location 50) in block 0 of the file), the size of the impure area, the extra space allocated with the FRUN/BUFFER:n command, and the extra space (if any) allocated with the LINK/FOREGROUND:stacksize command. If you do not allocate extra stack space, the default stack size is used. If there is not enough memory available to run the job, an error message prints and the monitor dot prints on the terminal.

Once FRUN gets the memory space the job needs, it sets up the job's impure area. FRUN also sets up the job context on the foreground job's stack for FB systems, or in the job's impure area for mapped systems. So, when you first load a foreground job, it appears to be context-switched out. (See (RMON_CHAP) for more information on context switching and other monitor functions.)

Next, FRUN loads the foreground main program into memory and relocates addresses in the root to reflect the current load address. Virtual .SAV files do not require relocation. If the job is overlaid, there is one more step before execution can begin. FRUN reads and relocates just the root of an overlaid program. Then it reads the overlay relocation information into a buffer. One by one, each overlay segment is then read into memory, relocated, and written back to disk. Finally, FRUN starts job execution. Therefore, you cannot run more than one copy of a disk-overlaid .REL system job from the same file. (FRUNCOMM_FIG) shows a summary of how the FRUN command loads a foreground job image into memory.

(FRUN Command\FRUNCOMM_FIG) (postscript\mlo-007371b\39) (Starting Foreground and System Jobs)

The (int_book) provides a lot of information on starting foreground and system jobs; you should read that part before using either. In brief, (FBSYS_FIG) illustrates the procedure Digital recommends for starting up a system that has both system jobs and a foreground job. In the example in (FBSYS_FIG), the two handlers that the QUEUE program needs are loaded first, since the error logger and the QUEUE program are both intended to run as long as the system runs. (The QUEUE program needs handlers for the device to which it will copy files, as well as handlers for the devices on which those files are currently stored. The error logger needs no specific handler; it logs errors from any handler that calls it.) The SRUN command is used next to start the more important of the two system jobs (the error logger). Then the second system job (QUEUE) is started, also with SRUN. This ordering of system jobs gives the error logger higher priority by default than the QUEUE program. (Note that if it is not convenient for you to load the higher priority system job first, you can assign priorities to the system jobs with the SRUN/LEVEL:n command.) Lastly, the foreground job, which requires no other handler, is started with the FRUN command. In (FBSYS_FIG), the foreground job, which always has the highest priority, is loaded last, because it will only run for a short time before it is stopped, unloaded, and replaced by a different foreground job. After you stop a job by typing two CTRL/Cs or the ABORT command, you must use the monitor commands to unload it and replace it with another. RT--11 does not provide a way for one foreground job to automatically start another.

Multiple copies of a system job can be run at the same time by assigning, using the /NAME: option, a different logical name to each job. That is described for KEX in the (int_book).

(FB System\FBSYS_FIG) (postscript\mlo-007372b\30.5) (Foreground Stack)

The foreground job's stack is located immediately above the impure area. Its default size is 128(10) bytes. You can change the size of the stack at link time by using the /FOREGROUND:stacksize option.

You can also change the location of the foreground stack. To do this, use the /STACK:n option at link time, and specify either an octal value for the stack pointer or a global symbol name. If you change the stack location, you are responsible for allocating space for the stack in your program.

Be careful not to let the stack overflow during execution. Since RT--11 neither checks for this error nor makes any attempt to correct it, the most likely result is that your program or the impure area will be corrupted. (Foreground Impure Area)

The memory locations just below the foreground job area contain job-dependent information. This area is called the (impure area\bold), and its contents are maintained by RMON. (RMON_CHAP) lists the information contained in this area. (User Service Routine (USR)\USR_SEC)

The (User Service Routine \bold)(USR) is the part of the RT--11 operating system that provides support for the RT--11 file structure. It contains instructions to: (UNNUMBERED) Fetch device handlers Get the status of device handlers Get and set information about files Open existing files Create new files Add queue elements Protect and unprotect files Delete and rename files Close files

In addition, the USR contains the Command String Interpreter (CSI) which interprets device, file, and option specifications. The default memory location for the USR is directly above the background area, or directly below the system jobs, foreground job, and loaded device handlers, if there are any. You can change this default location by setting an address in $UFLOA (offset 46) in low memory.

The USR is always resident in memory under all mapped monitors.

Under an unmapped monitor, the USR does not always have to be resident in memory. In fact, in an unmapped system, the USR is designed to be swappable in order to make as much space as possible available for user jobs. Generally, the USR is then only read into memory when file-oriented operations are required. (Structure)

The USR consists of two basic parts: the buffer area and the permanent code area. The first section, which is two blocks long, contains code when the USR is brought into memory. This area also serves as the buffer in which the USR stores a device directory segment. The second section contains permanent code. (USR_FIG) shows an overview of the USR's structure and its memory location in a single-job system.

The first routine in the USR buffer section consists of initialization code to relocate pointers in the USR and KMON. This relocation code becomes active the first time the USR is entered after it is brought into memory. It relocates internal pointers in the USR that point to RMON and to other important locations within the USR. If the USR was called from KMON, it also relocates pointers to RMON within KMON.

(USR\USR_FIG) (postscript\mlo-007373b\23)

In unmapped monitors, the next section of code handles the .QSET programmed request, followed by a small amount of scratch space, takes up the remainder of the two-block buffer area. In mapped monitors, the .QSET request is handled in the buffer area.

Following the buffer area is the USR's permanent code which starts at offset 2000 from the beginning of the USR. The permanent code consists of routines that process the following programmed requests:

(4\12\12\12) (.CLOSE\.DELETE\.DSTATUS\.ENTER) (.FETCH\.FPROT\.GFDAT\.GFINF) (.GFSTAT\.LOOKUP\.RELEAS\.RENAME) (.SFDAT\.SFINF\.SFSTAT\)

The Command String Interpreter (CSI) occupies the end of the USR, where the .GTLIN, .CSIGEN and .CSISPC programmed requests are processed. (Execution\SCMUEX_SEC)

The general flow of execution in the USR is straightforward. When a fresh copy of the USR is brought into memory, its buffer area contains the code described in the previous section. When a program issues a USR programmed request, the first code to execute is the relocation code. This code then calls the routine to process the particular request that was issued. If the USR stays in memory, subsequent USR requests go directly to the routines that process them. The initialization code is not called again.

Usually, a USR request requires a device directory segment. If the correct segment is already in the USR buffer, the USR does not read in a fresh copy of that segment. If the correct segment is not in memory, or if the USR has no segment at all, the USR reads the directory segment into its buffer. When it does this, the USR stores two words of information in the RMON fixed offset area. $BLKEY, at offset 256, contains the number of the directory segment currently in the USR buffer. $CHKEY, at offset 260, contains the device's unit number in the high byte, and an index into the monitor device tables in the low byte.

It can be useful to you to know under what circumstances the USR reads in a new directory segment. The following conditions cause the USR to read in a new directory segment: (NUMBERED) Anything that causes the USR to swap out. When a fresh copy of the USR is brought into memory, it will have no directory segment in its buffer and will be forced to read one from a device. Executing code in the buffer area. Since the code to process some programmed requests is located in the USR buffer area, attempting to process one of those requests always causes a fresh copy of the USR to be brought into memory. The following requests cause this to happen: (UNNUMBERED) .QSET (unmapped monitors only) .EXIT (if your program was loaded over any part of KMON) Issuing an .ENTER programmed request. This always causes the USR to read a fresh directory segment. Issuing a .LOOKUP programmed request with a different device or file specification from the previous .LOOKUP. Note that doing a .LOOKUP with the same device specification as the previous .LOOKUP does not necessarily cause the USR to read in a fresh copy of the same directory segment. This is why you cannot remove a volume from a given device unit, replace it with another volume, and expect the USR to have the new volume's directory segment in memory. However, in this situation, you can force the USR to read a directory segment from the new volume by locking the USR to gain exclusive use of it, storing a value of 0 in $BLKEY (RMON fixed offset 256), and then issuing a .LOOKUP programmed request with the same arguments as the previous .LOOKUP. Clearing $BLKEY causes the USR to (forget) the current directory segment and read a fresh one from the new volume. (USR Swapping with Unmapped Systems\SCMUSC_SEC)

The USR can be swapped out of memory with only unmapped (SB or FB) systems. Therefore, this entire section (up to (SIM_KMONINT_SEC)) applies only to the SB and FB systems. A copy of the USR is always resident in memory in mapped systems.

Because the USR does not always have to be resident in memory for unmapped systems, you have a variety of options to consider when you design an application program. You can keep the USR in memory at all times (the simplest case), or you can arrange to have the USR swap into memory only when your program needs it. The latter procedure permits your program to use an extra 2K words of memory when the USR is swapped out. The guidelines that follow can help you design programs that handle the USR efficiently. ()In general, the burden of USR swapping should be undertaken by the program, not by the operator who runs it. SET USR NOSWAP is useful to override the default action of programs outside an operator's control (such as FORTRAN), but its use requires operators to understand internal programming details -- a requirement that should be avoided if at all possible. (Keeping the USR Resident in an SB System)

In an SB system, the normal location for the USR is just below RMON and loaded device handlers (see (USR_FIG)). If your program does not need the space the USR occupies, you can force the USR to remain resident while your program is executing by issuing the monitor SET USR NOSWAP command before you run the program. In any case, if the space is not needed, the USR does not swap. Note that the USR can still slide up or down in memory, as (DEVHANFRESPC_SEC) describes.

Keeping the USR resident means that 2K words less memory is available to your program. However, the directory operations involved in file opening and closing and in program loading will be faster because this arrangement eliminates swapping and disk I/O. In addition, the program will have a much simpler design. To keep the USR resident, a MACRO program should avoid issuing a .SETTOP request for memory above the base of the USR.

Remember that even though the USR is set to NOSWAP, there are some programmed requests that can cause a fresh copy of the USR to be brought into memory. For an SB system, these requests are .EXIT, and .QSET. If the USR is swappable and if the background program issues a .SETTOP request for memory above the base of the USR, the USR loads into the area specified by the contents of $UFLOA (location 46) in low memory. If $UFLOA contains 0, as it should when you intend to keep the USR resident, the USR loads in its usual place, below RMON. However, if for any reason you move a different value to location 46 and then execute one of the requests that loads a fresh copy of the USR, the USR will then load into the area you specified. If you execute a program that keeps the USR resident, the monitor ignores the contents of $UFLOA. (Allowing the USR to Swap with an SB MACRO Program)

The only reason to allow the USR to swap in an SB system is to gain access to the extra 2K words of memory that swapping makes available. To enable USR swapping, make sure that the SET USR SWAP command is in effect. (This is the default condition.)

A MACRO program gains access to the 2K words of memory because its high limit requires it, or because it does a .SETTOP to an address within the USR area. (Refer to (RUNCOMM_FIG) for a summary of how the RUN and R commands load programs that overlay the USR area.) When the program issues a programmed request that requires the USR, the part of the program that occupies the USR area is written out to SWAP.SYS, and a fresh copy of the USR is brought into memory from the monitor file on the system volume. $UFLOA (location 46) should contain a value of 0 if you want the USR to swap into memory at its default location. If you want it elsewhere, put the starting address into $UFLOA during your program's initialization routine. When the programmed request completes, the part of the program in SWAP.SYS is copied back into memory, overlaying the USR. This sequence of events occurs for each programmed request that requires the USR, even if your program issues two or more requests in a row.

To make more efficient use of the USR, your program can issue the .LOCK programmed request before any other USR requests. This swaps part of your program out, reads the USR in, and returns to your program. After this, the USR remains in memory at the location you specified in $UFLOA (if any). You can now issue a number of USR programmed requests and avoid the overhead of USR swapping. When your program next needs the 2K words of space, use an .UNLOCK request to release the USR.

When the USR is swappable, it is important that you put it in a safe place in your program. This means that the area the USR will swap over must not contain code or data that will be needed at the same time the USR is in memory. The following is a list of code and data that must not be overlaid by the USR: (UNNUMBERED) Device block and/or CSI or .GTLIN file description string for the current request Active device handlers Active completion routines Active interrupt service routines Active I/O buffers Queue elements from .QSET I/O channels from .CDFN Program stack Trap service routines from .SPFA and .TRPSET Code executed between the .LOCK and .UNLOCK requests

You can control USR swapping by careful use of the .SETTOP request. A typical practice that many system utility programs use is to issue a .SETTOP request to obtain space up to the base of the USR. The programs then perform all their USR operations. Finally, the programs issue an additional .SETTOP request to obtain as much memory as possible, if necessary.

Another situation to be aware of occurs when a program issues a .SETTOP request for more memory than is available. In this case, the program is given only the amount of memory that is available. After issuing a .SETTOP request, a program must always use the value returned in R0 (or $USRTO (location 50) in low memory) as the true high limit of the program. For example, a program can issue a .SETTOP request for memory above the base of the USR when the USR is set to NOSWAP. However, the value returned to the program as its true high limit is just below the base of the USR. (Keeping the USR Resident in an FB System)

As with an SB system, the easier way to deal with the USR in an FB system is to keep it resident. Use the SET USR NOSWAP command. This arrangement is suitable if the background, foreground, and system jobs have enough memory. The USR is brought into memory at its usual place, just below any loaded handlers and below the foreground job and it remains in memory during program execution. Neither job has to allocate program space for the USR, and programs execute faster without the overhead of USR swapping and disk I/O.

The important issue in an FB system with the USR resident is determining which job should have control of the USR. Because only one job can use the USR at a time, both jobs must be aware of sharing this resource. Since a program in an SB system can lock the USR in order to process a number of USR programmed requests, in an FB system, either the background job or the foreground job can lock the USR to gain exclusive use of it.

The .LOCK request gives ownership of the USR to one job. The .UNLOCK request releases the USR, making it available for the other job. The request .TLOCK can determine whether or not the other job has exclusive ownership of the USR. It permits a program to try for a .LOCK, but to continue with execution if the attempt fails.

The LOCK/UNLOCK system permits one job to lock out another for a considerable length of time. During a lockout, interrupt service and completion routines can run, but not mainline code. This could cause serious difficulties in a real-time foreground program. There are some ways to minimize or eliminate this lockout problem: (NUMBERED) Be sure to separate USR operations from real-time operations. Avoid using devices with slow directory operations, such as magtape. Organize your real-time foreground program so that real-time operations are in interrupt service routines and completion routines and will not be affected if the mainline code is locked out with a pending USR request.

Typically, a real-time foreground job can be organized in three parts: an initialization phase, which opens all required channels and begins real-time operations; a real-time phase, which does interrupt service and I/O operations; and a completion phase, which stops real-time activity and closes the channels. With this arrangement, the background program can perform USR operations during the real-time phase without locking out the foreground. The foreground program can use .LOCK and .UNLOCK to prevent interference from the background job during initialization and completion phases.

(Swapping Considerations for Background Jobs)

When either the background job or the foreground job needs the extra 2K words of memory that swapping the USR provides, both jobs must be concerned with USR swapping. The general concerns for background jobs are those listed in the previous sections.

The easiest approach for the background job is to swap the USR into its default location, the highest 2K words of program space. If this is not convenient for any reason, the background job can select any other contiguous 2K words of program space. In this case, it must also put the starting address of the USR swap area into $UFLOA (location 46) in the system communication area. This location is context-switched in the FB system, so it always contains the correct value for the job that is currently executing.

The background job must not place any USR-sensitive code or data in the area where the USR will swap. In addition to the list in (SCMUSC_SEC), the following items must not be in the USR swap area: (UNNUMBERED) Memory list from the .CNTXSW request Active message buffers Code containing the .LOCK or .TLOCK requests

You must also be careful that the background job does not lock the USR for an unreasonable length of time so it can block the foreground job from running. If you lock the USR in a background job, remember to unlock it as well.

(Swapping Considerations for Foreground Jobs)

If the background job issues a .SETTOP that causes the USR to swap, or if the background job is large enough to force the USR to swap, the foreground job must be concerned with USR swapping. However, while the background job can simply allow the USR to swap into its default position (the highest 2K words of the background job area), the foreground job has no default location for the USR. It must allocate 2K words within its program bounds in which to swap the USR - space that must not contain any USR-sensitive code or data. The foreground job must also place the starting address of that space in $UFLOA (location 46) in the system communication area. This location is context-switched during normal foreground/background execution, so it always contains the correct swapping address for whichever program is currently executing.

The foreground program could also be concerned with sharing the USR with the background job. The .LOCK/.UNLOCK requests can give the foreground job exclusive ownership of the USR to prevent interference by the background job. The foreground job should avoid keeping the USR permanently locked, which sometimes happens strictly because of a programmer's oversight. (Keyboard Monitor (KMON)\SIM_KMONINT_SEC)

The (Keyboard Monitor \bold)(KMON) is the part of the RT--11 system that provides the communication link between you at the console terminal and the rest of the RT--11 system. KMON commands permit you to assign logical names to devices, load device handlers, run programs, control foreground/background operations, control system jobs, invoke indirect command files, and examine or modify memory locations. KMON is brought into memory when the background job completes. When KMON is in memory, the USR is also present directly above it.

KMON consists of a root segment and a number of overlays that contain the command processors. KMON runs as an ordinary background job, in user mode. The root segment is contained in the p-sect RT11. See (MONPSECT_TAB) for a summary of all monitor p-sects.

The various command line interpreters (DCL, CCL, UCL, UCF) can be enabled or disabled by using the SET CLI command, as described in the (sug_book). (DCL Command Processing\dcl_comm_sec)

When KMON interprets a command that you type at the terminal, it expands the command text into an internal indirect file. For example, the command COPY MYFILE DL:MYFILE expands internally into: R PIP (RET\TEXT) DL:MYFILE=DK:MYFILE (RET\TEXT) ^C

KMON stores this internal indirect file in the (command expansion buffer area). KMON creates space in memory for this buffer area immediately above the USR. When KMON and the USR slide up or down in memory, the command buffer spaces move with them. (KMON_FIG) shows KMON in memory.

(Keyboard Monitor (KMON)\KMON_FIG) (postscript\mlo-007374b\24)

The (INT_BOOK) gives an overview of KMON command processing. The (INT_BOOK) and (SYG_BOOK) describe how to remove individual commands or groups of commands from a system you create through the system generation process. If you are interested in modifying KMON itself to change the monitor command set, see the (INT_BOOK) for information. (CCL Command Processing)

If KMON does not recognize the first word of an input line as a valid DCL command, it tries to treat the input line as a CCL command by searching for a program of that name on SY and running the program. If a program is found, KMON passes the remainder of the command line to the program in the CSI input buffer as a CSI command string, followed by a ^C. The general format of a CCL command is: command () field1()field2

or command () csistring

If the first form is used, KMON converts it to the second form by reversing the fields and inserting an equal sign: command () field2=field1

For example, you might type: PIP A=B

or PIP B A

Both forms are equivalent to typing: (.)(R SY:PIP) (*)(A=B) (*)(^C)

If the first word on the line is more than six characters, characters after the first six are ignored. (field1 )and (field2 )can contain multiple file names, separated by commas. If you have an application program on SY named EVALUA.SAV to evaluate certain collected data and print a report, you could type: (EVALUATE DU3:DATA16.DAT,DU1:DATA03.DAT LP:)

This is equivalent to: (R SY:EVALUA) (LP:=DU3:DATA16.DAT,DU1:DATA03.DAT) (^C) (Adding New Commands Through UCL)

Using UCL is described in (int_book); you should look there for information on defining UCL commands.

In parsing a command, KMON first checks to see if the first word of the line is a valid DCL command. If not, KMON tries, using the CCL conventions outlined above, to find and run a program of that name. If that also fails, KMON looks for the program UCL.SAV on SY and runs it if present. KMON passes to UCL the entire command line (including the first word) as ASCII text in the chain area starting at location 512. Location 510 contains the number of bytes in the command line. Locations 500 through 507 of the chain area are not used by UCL.

UCL interprets and expands the command line and performs any operations required by the command. UCL can reformat and pass the command to another program by doing a .CHAIN, or UCL can create a new command line and pass the new command to KMON by doing a normal or special chain exit. For example, you could type: (BUILD MYPROG)

UCL.SAV might expand the command into the following series of commands: R MACRO MYPROG,LP:/C=MYPROG ^C R LINK MYPROG=MYPROG ^C RUN MYPROG

These commands could then be passed back to KMON by doing a normal chain exit or a special chain exit. Refer to the following section and sections (JSW_SEC\value) and (chain_sec\value) for information about normal and special chain exits. (User Commands First (UCF) Feature)

Using UCF is described in (int_book); you should look there for information on defining UCF commands.

KMON supports the User Commands First (UCF) feature. UCF allows you to create a KMON preprocessor that will intercept all command line input after KMON has tried indirect file (@) syntax and before DCL parsing. This preprocessor can be used to determine the way KMON processes valid DCL commands and to process commands that KMON would otherwise refuse.

The distributed file UCL.SAV (the User Command Linkage utility) can be copied and renamed to create a functioning UCF utility as explained in the (INT_BOOK).

Once you have created the UCF utility, you make it available to KMON by issuing a SET command (SET CLI (condition)) as described in the (sug_book) or by performing the following customization. The SET command affects only the memory image monitor; the customization patch alters the file copy. Digital recommends you include the SET CLI (condition) command in a start-up command file to 'automatically' set the command line interpreter as you want, rather than perform this patch.

Besides making UCF available to KMON, the customization patch can also selectively inhibit command processors (DCL, CCL, and UCL) from processing KMON commands. Great care must be taken when inhibiting command line processors; if all are inhibited, only the R and RUN commands are recognized. Think again about using the SET CLI (condition) command.

In the customization, (monitr).SYS is the name of the monitor file that you want to modify. The value of the lower four bits of the value represented in (xxxxxx) specifies the command line interpreters: 1 for UCF, 2 for DCL, 4 for CCL, and 10 for UCL. The distributed monitors support DCL, CCL, and UCL command interpreters; the value represented by (xxxxxx) is 177416.

To enable the UCF command line interpreter, set bit 0 (value 001) by specifying 177417 for (nnnnnn). To selectively inhibit distributed command line interpreters DCL, CCL, or UCL, clear ,respectively, bits 1, 2, or 3 in (xxxxxx) by entering the corrected values for (nnnnnn). (.)(R SIPP (RET)) (*)( monitr.SYS (RET)) (Base?)( 0 (ret)) (Offset?)( CLIFLG (RET)) (Base Offset Old New) ( 000000 CLIFLG xxxxxx )(nnnnnn(RET)) ( 000000 CLIFLG+2 xxxxxx )((CTRL/Y)(RET)) (*) (.) (KMON/UCF Communication)

KMON and UCF communicate by means of a 1-word interface in RMON, defined in .CLDDF and .CLIDF in SYSTEM.MLB. The low byte in this word -- CLI.FL -- indicates which command processors can be run. The high byte -- CLI.TY -- indicates which command processor is running. This interface is described in (CLITYPCLIFLG_SEC).

KMON collects a command from the command line and checks for indirect file command syntax. If indirect file command syntax is not found, KMON checks UCF.KM (bit 7) in CLI.FL.

If UCF.KM is set, KMON clears the bit and goes through the normal parsing sequence (DCL, CCL, UCL). If UCF.KM is clear, KMON checks UCF.ON (bit 0).

If UCF.ON is set, KMON places the command line in the chain area (locations 510 through 776) and runs UCF.SAV.

If UCF processes a command line and returns it to KMON, UCF sets UCF.KM in CLI.FL and performs a special chain exit. If UCF executes the command line, it does not set UCF.KM and does not perform a special chain on exit. (Passing Commands Through the Chain Area)

The RUN command and CCL commands cause KMON to load the chain area with a copy of all parameters that appear in the command line (that is, all data following the file name and separator). KMON stores these parameters exactly as they appear in the command line. This feature lets KMON use the chain area to pass unaltered parameters to the program that is being invoked. This is useful for programs that require command input that does not contain a standard RT--11 file specification, such as SETUP commands.

All constructions are valid. KMON stores the unchanged parameters in the chain area beginning at location 512.

A byte count of the contents in the chain area is stored at location 510. The byte count includes all null bytes. A value of 1 at location 510 informs a program that there is no data following the file name.

For example, the following CCL command includes a 2-word string as a parameter. (.)(ECHO HELLOOO THERE)

KMON stores the string in the chain area, beginning at location 512, exactly as it appears in the command line.

To obtain unaltered parameters from the chain area, a program uses the GTLIN SYSLIB routine as described in the (SSL_BOOK).

The .GTLIN programmed request cannot be used to obtain unaltered parameters from the chain area. (Character Case Handling)

The case of characters stored in the KMON input buffer depends on the way TTLC$ (bit 14) in the $JSW is set at the time the characters are typed. KMON does not automatically convert lowercase characters to uppercase from terminal input or command files. If you wish all characters to be upper case, use the SHIFT/LOCK keys or the CAPS/LOCK key.

A program using .GTLIN with the lowercase bit set receives the commands in lowercase if the commands were entered in lowercase.

Since the case of a character depends on the contents of the job status word at the time the character is entered, the case of characters that are entered by means of the type-ahead feature are unpredictable.

For compatibility with earlier versions of RT--11, the USR puts all characters indicating options in uppercase. Even so, Digital recommends that all programs test and convert option characters before processing them. The recommended method for testing and converting lowercase characters to uppercase is:

CMPB @SP,#'A+40 BLT X CMPB @SP,#'Z+40 BGT X BICB #40,@SP X: (Determining Components Size)

Whether you are using a distributed or customized monitor, if you are using a distributed system and you need to know the sizes of the components, you should follow the guidelines in the next few sections. (Size of the USR)

For unmapped systems, the size of the USR is always 2K words. For mapped systems, the USR, which is always resident, is somewhat larger. Your running program can determine the exact size of the USR by examining RMON fixed offset 374, $USRAR, which contains the size of the USR in bytes. You can also determine the size of the USR by issuing the monitor commands SET USR NOSWAP and SHOW MEMORY. (Size of KMON)

The size of KMON is the same as the size of the p-sect RT11. Examine the link map that resulted from the system generation for your system to obtain this value. (Size of RMON)

To determine the size of RMON, issue the SHOW MEMORY monitor command. This command prints the base address of RMON and its size in decimal words. (Size of Device Handlers)

The size of each device handler, in bytes, is contained in H.SIZ (location 52) of the handler's .SYS file. You can also obtain this value by issuing a .DSTATUS programmed request on the device from a running program or by issuing the SHOW MEMORY monitor command, which reports the sizes of all loaded device handlers. (End of Chapter)