ITS DDT Guide
From Computer History Wiki
ITS DDT is the command processor for ITS; it is actually a debugger.
Taken from http://victor.se/bjorn/its/ddtord.1462
Documentation for DDT version 1491 - Table of contents: (For users searching for command names with EMACS, each heading is the second line of its own page. The first line of each page is blank. There are no actual altmodes in this file; dollar signs are used instead. There are no non-formatting control characters; uparrow and a non-control character are used instead) (The DDTDOC program also searches this file, and knows that it uses dollar signs and uparrows rather than altmodes and control characters. So don't change this unless you fix DDTDOC first!) List of DDT commands Colon commands Built-in colon commands Reading of filenames Defaulting of filenames DDT's UNAMEs and SNAMEs Specially used symbols Unsolicited typeouts Unsolicited offers Returning to DDT Symbol table format � List of DDT commands. Note that angle brackets are used to delimit meta-variables. Each of the following commands that takes a prefix arg does so in one of two ways: If the arg is called <name>, <dev>, <user>, <prgm>, <flags>, <fn1>, it is the syllable immediately preceding the operator. If it is a symbol, the symbol's name is used; otherwise it is considered to be SIXBIT for the desired name. eg. FOO$J and $1'FOO$$J are equivalent. All other commands evaluate all the preceding syls and ops to get 1 to 3 arguments (separate them with $,). ^@ will terminate an execute file or valret string. ^A prints the default user's sends file. <user>^A prints <user>'s sends file, and sets the default for ^A and friends. 0^A print your own sends file, and set the default to you. $^A like ^A but for MAIL files. (but see :DDTSYM PMLFLG) $$^A like $^A but for RMAIL, BABYL or OMAIL files. (tries both). ^B is a special interrupt-level character, which turns on output to the wallpaper file if there is one, by zeroing ..LPTFLG. In files and valret strings, one ^B merely counteracts one ^E, by decrementinging ..LPTFLG unless it is zero. When a wallpaper file is open and output to it is on, every character DDT outputs goes to it, as does every character that DDT reads and echoes. ^B, ^E, ^V and ^W are interpreted at interrupt level when typed on the TTY; when present in execute files and valret strings, they are interpreted when read. They will not be seen at any higher level (eg. ASCII type-in); in files and valrets, they will be ignored within :IF conditionals that fail. ^C types a CRLF but doesn't close the open location, terminate an expression, reset the temporary mode, etc. The CRLF will be typed even if ^W has turned off TTY output. ^C being the ITS end-of-file character, it terminates execute files. $$^C half-kills the last symbol typed out (not counting index fields of instructions), then retypes $Q in the current mode (after DDT types JRST FOO(A) , $$^C will half-kill FOO). ^D is a special character which types "XXX?" and flushes any incompletely typed in command. If typed while a $E, $N or $W search is in progress, the search is stopped. ^E is a special interrupt-level character which turns off output to the wallpaper file (if any) but does not close it. Specifically, it increments ..LPTFLG. See ^B. ^F lists the last directory referenced. <dev>^F lists directory of device <dev>, using the :PRINT default sname, and sets default :PRINT device (by special dispensation, that isn't done if <dev> is TTY !). Doesn't work if <dev> is also the name of a directory on DSK:. In that case, you get ... <user>^F lists user <user>'s directory on device DSK:, and makes <user> the default sname for :PRINT, etc. If <user> isn't a directory, and isn't a device name either, the default sname for :PRINT, ^F, etc. is still set. Thus, <user>^F <dev>^F will show the directory of <dev>:<user>; even if <user> isn't a disk directory. 0^F is the same as <msname>^F. $^F: <dev>$^F is like <dev>^F but doesn't set :PRINT defaults; just the default for ^F without argument. <user>$^F is like <user>^F but doesn't set the :PRINT default. $$^F: <arg>$$<n>^F this is a hairy command which uses the DIR: device to print the current default directory. The display is controlled by the table of two-word sixbit entries beginning at DIRFN1 (and DIRFN2) inside your DDT. For numeric argument n, the nth FN1 and FN2 are used as DIR: arguments. If the numeric arg is omitted it is assumed to be zero (and DDT uses the arguments at DIRFN1+0 and DIRFN2+0). If a DIRFN2 slot is zero: if there is no argument, we use the default :PRINT FN1; else if there is an argument we use it and set the default :PRINT FN1. If the DIRFN2 slot has something in it: if there is an argument, we use that argument instead. Here follow the DIR: arguments provided in DIRFN1. You can patch them with :SELF if you have another preference. DIRFN1: SIXBIT /NAME1/ ;Table of $$^F DIR: search options. DIRFN2: SIXBIT /UP/ SIXBIT /FIRST/ ;$$1^F finds FN1 0 SIXBIT /SECOND/ ;$$2^F finds FN2 SIXBIT /BIN/ SIXBIT /CDATE/ ;$$3^F ascending in creation age SIXBIT /DOWN/ SIXBIT /SIZE/ ;$$4^F descending in size SIXBIT /DOWN/ SIXBIT /NOT/ ;$$5^F not backed up SIXBIT /DUMPED/ SIXBIT /ONLY/ ;$$6^F just link pointers SIXBIT /LINKS/ Examples of use: FOO$$1� Shows DIR:FIRST FOO and sets FN1 to FOO LISP$$2� Shows DIR:SECOND LISP $$2� Shows DIR:SECOND BIN $$3� Shows DIR:CDATE DOWN UP$$3� Shows DIR:CDATE UP PACK13$$6� Shows DIR:ONLY PACK13 As an additional feature, if you set the DDT variable DIRDIR to -1, $$^F (without a numeric argument) sets your default :PRINT SNAME and otherwise ignores the argument. This lets you look at other directories. Examples: $$0^F Does DIR:NAME1 UP $$^F Still does DIR:NAME1 UP FOOBAR$$^F Changes default dir to FOOBAR and does DIR:NAME1 UP DOWN$$0^F Changes no defaults (now FOOBAR), does DIR:NAME1 DOWN ^G is a special interrupt level character that aborts any DDT command. It is so powerful that it can leave DDT's data bases in inconsistent states if typed at the wrong instant, so it should be used only when DDT appears to be hung. ^H (back-space) is equivalent to $J $P <prgm>^H continues <prgm>, creating one if necessary. If a job named <prgm> exists, it will be $P'd (or $G'd if it was loaded but never started). Otherwise, <prgm>^K is done: a job <prgm> is created, and <prgm> is loaded in and started. Since ^H only loads <prgm> if no job <prgm> already exists, ^H never clobbers anything useful. If the existing job is disowned, it will be reowned before being continued, of course. $^H: <prgm>$^H like <prgm>^H but loads symbols if a new job is made. ^I (tab) goes to the next line, and then "types and opens the RH of $Q", which involves typing the RH of $Q as an address, typing a slash, and then printing the contents of the address typed (in the current type-out mode), just as if the "/" command had been used. <arg>^I deposits <arg> in the open location if any, then types out and opens the RH of <arg>. $^I and <arg>$^I are like ^I, <arg>^I but use the LH rather than the RH. $$^I and <arg>$$^I are like ^I, <arg>^I but do an effective address calculation on $Q or <arg> to determine the address to type and open. ^J (line-feed) Types out and opens location .+1 (remember that "." is always the last location opened). Unlike ".+1/", ^J does NOT push the old value of "." onto the 'ring buffer of "."'. <arg>^J stores <arg> in the open location, if any, then does ^J. $^J pops the ring buffer of point, then does ^J. After " 100/ 200/ ", $^J would open 101 . See $^M. <arg>$^J stores <arg> in the open location, if any, then does $^J. $<n>^J pops the ring buffer of "." <n> times, then does ^J. <arg>$<n>^J stores <arg> in the open location, if any, then does $<n>^J. ^K: <prgm>^K creates a job named <prgm>, loads TS <prgm> into it without symbols (looking for the file on your directory, the SYS directory, the SYS1, SYS2, and SYS3 directories, the dirs. in the sname search list), and the connected directory, and starts it, giving it the TTY. The program is given a null :JCL command string. If a job named <prgm> already existed, the newly loaded copy of <prgm> overwrites it. Since that can be a screw, if the job was disowned, or if ..CLOBRF is nonzero, DDT will ask the user "--Clobber Existing Job--". After such a query, type a space to tell DDT to go ahead and clobber the job; type anything else to abort. DDT will query "--Reload Protected Job--" if the job is "pro- -tected" (its ..SAFE variable has been set nonzero). $^K loads the current job's symbols from the file which was loaded (eg by ^K) <prgm>$^K is like <prgm>^K but loads the symbols. $$^K disowns the current job. The job becomes a "disowned job" and is no longer DDT's inferior. Anyone who wishes to can "reown" it with $J, making it his inferior. In the mean time, since it is no longer DDT's inferior, it will not be harmed if DDT is logged out or killed. An infix argument is used as the control-bits for the DISOWN system call. Each bit controls a separate option. The meaningful bits are these: $$10^K disowns the job and arranges that if it ever remains stopped or blocked for an hour without being reowned or attached, the system will kill it. $$4^K disowns the current job and starts it, simultaneously (as far as it can tell). $$2^K makes the current job be a disowned job scheduled as part of the system (ie sharing the system job's resource word). It is antisocial to use the "1" and "2" bits for private purposes. $$1^K makes the current job into a non-disowned, top level job (but not console-controlled). Useful for resurrecting dead system demons. $$3^K makes the current job be a non-disowned top level job with the system job's resource word. ^L is a special character that tells DDT to type out any input characters that if been read but not yet fully processed, after first typing a CRLF or clearing the screen. ^L is ignored entirely in execute files and valret strings. ^M (carriage-return) closes the open location if any, without changing it. Resets the temporary (or "current") typeout mode to the permanent mode. <arg>^M deposits <arg> in the open location if any, and closes it. Resets the current typeout mode. $^M pops the ring buffer of ".", then types and opens the new ".", tab-style, on a new line. Does not reset the current typeout mode to the permanent mode. After "30/ 100/ 200/", $^M would pop the ring buffer once, opening location 100 and leaving 30 on the top of the ring buffer. A second $^M would open 30 . <arg>$^M stores <arg> in the open location if any, then does $^M. $<n>^M like "$^M", but pops the ring buffer of "." <n> times instead of once. <arg>$<n>^M stores <arg> in the open location, then does $<n>^M. $$^M does nothing if no location is open. Otherwise, it unpurifies the page containing the open location (by replacing it with an impure copy). $$^M is superfluous unless ..UNPURF has been zeroed. <arg>$$^M like $$^M but deposits <arg> in the location after unpurifying the page. ^N proceeds one instruction, then returns to DDT. <n>^N proceeds <n> instructions, then returns to DDT. In "care" mode, UUOs will be treated specially - the whole UUO handler will be executed. See $^^ command, Y flag. $^N steps the current job one instruction, using breakpoints. If the next instruction is a subroutine call, the whole subroutine is executed. $^N works by putting temporary breakpoints in the two words following the next instruction to be executed, and then restarting the job. The temporary breakpoints go away when either one of them is hit. If the instruction to be executed next is a PUSHJ, the AC used and its contents are remembered and the breakpoints will be conditional on the AC's having the same contents. Thus, if the PUSHJ is a recursive call all the inner recursions will execute and return without stopping on the breakpoint. Actually, the breakpoints don't always go immediately after the instruction to be executed next; they start on the first "reasonable" instruction after it ("reasonable" here means "nonzero op-code field"). This makes it possible sometimes to step over calls taking following arguments without taking any special care. $<n>^N similar but puts the breakpoints <n> words after the insn: at $.+<n>+1 and $.+<n>+2 . Good for calls followed by <n> args. This form of $^N overrides DDT's search for the next "reasonable" instruction by telling it explicitly how many args there are. <pc>$^N like $^N but puts the breakpoints at <pc> and <pc>+1 and does no special hacking for PUSHJ instructions. Also, DDT will not be insubordinate by looking for reasonable instructions, since it has been told explicitly what to do. <p>,$^N puts the breakpoints at the address in the word pointed to by the RH of accumulator <p>. If you accidentally ^N through a PUSHJ, <p>,$^N will proceed until after the subroutine POPJ's. This is not considered to be an explicit specification of where to break, so DDT looks for a reasonable instruction. <p>,$<n>^N is similar, but puts the breakpoints <n> words later, overriding DDT's search for a reasonable instruction. Good for exiting a subroutine with <n> args after the call. -<n>(<p>)$^N uses @-<n> ( <p> ) as the location of the first of the two breakpoints. Like <p>,$^N except that the return address is assumed to be <n> words down in the stack instead of at the top. $$^N executes one instruction at a time until the PC gets to be 1 or 2 larger than it was when the command was given. $^N is usually equivalent, and much faster; $$^N's only advantage is that it does not have to put breakpoints in the program. <pc>$$^N is like $$^N but continues till the PC is <pc> or <pc>+1. In general, $$^N takes the same sorts of arguments as $^N. ^O <file> deletes the specified file. It warns you what it will do, with "(Delete File)" (but see ..DELWARN). $^O <file1>,<file2> link <file1> to <file2>. Whether or not this will delete the file if it exists is controled by ..LINKP (q.v.) if ..DELWARN is 3, or ..LINKP is 0, it is disabled. $$^O <file1>,<file2> renames <file1> to the name <file2>, just like :RENAME. ^P proceeds the job without giving it the TTY. If it's running, does nothing. If it's waiting, lets it return and doesn't start it. Normally, clears the job's %TBWAT bit, so if it tries to use the TTY, it will interrupt and say "Job <jname> wants the TTY". However, this feature can be overridden - see ..TWAITF $^P is like ^P except that %TBWAT is set instead of cleared, so that if the job tries to use the TTY it will hang dumbly until it is $P'd. You can interchange the meaning of ^P and $^P - see ..TWAITF $$^P is like ^P except that the job's %TBOUT is set, giving it permission to type out even though it can't use the TTY for input. ^Q This is the same as ^ and is somewhat easier to type on some terminals. ^R <file> is equivalent to ":PRINT <file>" - the specified file is typed on the terminal. $^R <file1>,<file2> is equivilent to ":COPY <file1>,<file2>" - the contents of the first file are copied into the second file, writing over it if it already exists. ^S is the "shut up" character. It turns off typeout at interrupt level, but turns it on again when read. Thus it turns off typeout for the remainder of the command currently being processed, not permanently. <user>^S sets the current job's sname to <user> $^S like <xuname>$^S; it undoes the effect of <user>$^S. <user>$^S causes the next ^K, ^H or :-command, if it runs a program, to run it "as if <user> were running it". Precisely, its .XUNAME variable will be <user> instead of you and its .HSNAME will be set to <user>'s HSNAME. If the program follows the current convention, it will use <user>'s init file, etc. $^S works by setting the ..TUNAME and ..THSNAME variables. $$^S: <user>$$^S sets the master system name (the "msname"), the :PRINT default sname, and the sname for ^F, to <user>. The master system name is used: To initialize the snames of newly created jobs. To initialize their $L-default snames. Is searched last for ^K and : commands ^T makes filename-translations: <flags>^T <file1>,<file2> creates a translation entry for the current job, translating <file1> to <file2>. The effect will be that if the job tries to open <file1>, it will actually get <file2>. Any of the names in the two files may be *, meaning "translation applies to any name" in <file1>, "translation doesn't alter this name" in <file2>. A translation that specifies only an SNAME in <file1> (aside from *'s) is likely to confuse DDT and screw you. <flags> should contain any subset of "A", "I", "O". "A" means don't retranslate the result of applying this translation. "I" means translate on input, "O" output. If neither I nor O is specified, both are assumed. Example: I^T FOO:*;* * , DSK:FOO;* * will make any attempt by the current job to read a file from device FOO: to read it from the disk directory named FOO; instead. Since all four names default to *, I^T FOO:,DSK:FOO; is a valid abbreviation. $^T: <flags>$^T <file1>,<file2> creates a translation that applies to DDT and all of its inferiors to all levels. $$^T: <flags>$$^T <file1>,<file2> creates a translation for the current job and all of its inferiors to all levels. ^U removes filename translations: <flags>^U <file> deletes any translation the current job may have which says the <file> should be translated. I^U will only remove a translation for input, and won't affect translations for output. It will change a bidirectional translation into an output-only translation. Note that ^U *:FOO;* * removes any translation made on *:FOO;* *. It does NOT remove all translations made on names containing FOO;. It would NOT undo the effect of a ^T *:FOO;A B,C D. If you are not sure what translations you made, do :PEEK T<cr> to see them all. $^U: <flags>$^U <file> removes a translation created by $^T (one which applies to DDT and all its inferiors). $$^U: <flags>$$^U <file> removes a translation created by $$^T (one which applies to the current job and all its inferiors). ^V is a special interrupt-level (see ^B) character that turns on output to the TTY by zeroing ..TTYFLG . In valrets and execute files, merely decrements ..TTYFLG by 1 (unless it is already 0). Thus, one ^V in a valret or file cancels one ^W. ^W special interrupt-level character that turns off typeout on the TTY by AOSing ..TTYFLG . See ^B. ^X is used to stop a job running without the TTY (after being ^P'd). ^X normally does what ^Z would do if the job had the TTY. If the job is waiting to return, it is allowed to do so, but if it is waiting for a chance to commit suicide it will be stopped instead. ^X does nothing to a stopped job, except print out the instruction where it is stopped (and tell you it's stopped). $^X or $^X. (the point is required unless ..CONFRM is zero) deletes ("kills") the current job. All the data in it is lost. The $J command is then used to select another job to be current (if there are any); that job's name is typed out, followed by "$J". If the job to be killed is "protected" (its ..SAFE variable has been set nonzero), DDT will ask for confirmation before killing it. $<n>^X is like $^X., except that after killing the current job, $<n>J rather than $J is used to select another. <job>$^X kills the job named <job>. It asks for confirmation by typing "--Kill--"; a space tells it to go ahead. Whether you confirm the killing or not, the current job afterward is the same as it was before (unless it was the one you killed). $$^X or $$^X. kills all jobs. The "." is required, unless ..CONFRM is zero. Since this command is easily typed by accident instead of $^X., it is normally disabled, but may be turned on by ..MASSCP/-1 ^Y uses $Q as an AOBJN pointer to a symbol table in the current job's core, which should be appended to DDT's symbol table. Make sure that every symbol has either the local bit or the global bit (4.8 or 4.7) set; otherwise, a "DDT bug" message may result (exceptions are allowed if the symbol table being set up contains valid DDT-style block structure, but don't be surprised to find that you made a mistake). See Symbol table format. <arg>^Y is similar but uses <arg> instead of $Q. $^Y is like ^Y but flushes the symbols DDT already has. <arg>$^Y similar to ^Y. $$^Y: <addr>$$^Y puts a copy of the job's symbol table into the job's core. It assumes that <addr> is the location of an AOBJN pointer to an old symbol table, which is to be replaced by DDT's current one. The new symbol table is stored in core so that it ends at the same place as the old one; expansion or contraction occurs at the low end in core. The AOBJN pointer is updated to record the new size. These actions are such that DDT-2$$^Y will give the symbols to a non-timesharing DDT in the job. ^Z is not a DDT command. If given as a command to DDT, it is an error. ^Z IS a command to ITS to give the job that owns the TTY a fatal interrupt, if it is not a top-level job. If the interrupted job's superior is a DDT, it will take control of the TTY and begin reading commands as a response, but the ^Z itself is never seen by the DDT. ^[ is altmode, which is a prefix-modifier for DDT commands. ^\ begins a patch at the location open (the location "being patched"). It is a convenient way to replace one instruction (at the open location) by several (the patch). The instructions in the patch are stored in the job's "patch area", a spare area allocated specifically to such use. Every program should allocate one. The beginning of the patch area is the value of PATCH if it is defined, or the value of PAT if it is defined, or 50 . As patches are made, PATCH will be redefined to point to the next free location in the patch area. A patch started with ^\ must be terminated with some variety of ^] command, which will store first the JUMPAs back from the patch to the patched routine (two of them, in case the patch skips), and then a JUMPA from the location being patched to the patch itself. This order of actions guarantees that the patch will never appear to be "half made" in any way that that might cause trouble in a running program. ^\ begins by typing and opening the first location of the patch area. Then the contents of the location being patched are typed out and left as the argument to the next command. If you wish to include that instruction as the first instruction of the patch, type ^J. If you wish to get rid of it, type <rubout>. Then deposit the other instructions of the patch, and finish with a ^] (which see). While patching, the pseudo-location ..PATCH contains <location being patched>,,<start of patch>. NOTE to users of relocatable programs, and MIDAS or FAIL block structure: PATCH is redefined in the same symbol block that it was found in. This permits some obscure hackery, but normally the whole program will have only one patch area, and it must be visible to ^\ no matter which symbol block is currently selected for type in. That can be guaranteed by defining PATCH as a global symbol (eg, using PATCH": in MIDAS). <arg>^\ deposits <arg> in the open location, then does ^\. Equivalent to ^\<rubout><arg>, except that with <arg>^\, <arg> will be present in the location being patched while the patch is being made. $$^\ unmakes the patch previously made to the open location. $$^\ uses the JUMPA to the patch to find the instruction that the patch replaced. This works only for patches made by ^\, which were either closed by $^], or closed by ^] and having the old instruction as the first instruction of the patch. ^] ends a patch started by ^\. Two JUMPAs back to the locations following the one being patched are stored in the two words starting with the open location (or in location .+1 if no location is open). Then in the location being patched is stored a JUMPA to the beginning of the patch. Finally, PATCH is redefined to point at the word after the second JUMPA back (the first free location of the patch area). <arg>^] stores <arg> in the open location, opens the next location, then does ^]. $^] is like ^] but first stores the contents of the place the patch was made from in the open location and linefeeds. It is useful for putting a patch "before" an existing instruction. <arg>$^] stores <arg> in the open location, opens the next location, then does $^]. $$^] is like $^] but omits the JUMPAs back to the place that the patch was made from. It is useful when a patch is put on top of a JRST or POPJ - it will store an identical JRST or POPJ, and nothing else. $$^\ (unpatch) can't work after $$^] because necessary information isn't there; it can however figure out that it can't win and will complain. If this is important, use $^] instead of $$^]. <arg>$$^] stores <arg> in the open location, if any, then moves down one word and does $$^]. ^^ begins multi-stepping according to the job's stepping flags, and continues indefinitely. Multi-stepping involves printing the next instruction and executing it, repeatedly. Each step is done with a ^N or an $^N depending on the type of instruction and the settings of the stepping flags. Other flags cause stepping to stop before certain kinds of instructions. Errors, breakpoints, and .VALUE 0's will stop stepping. So will typing any character while DDT is typing the next instruction to step over. ..DOZTIM holds the number of seconds that ^^ will insist must elapse between steps, to give the user a chance to decide whether to type a character and stop things. While multi-stepping, the SETAI instruction (a no-op) invokes a special kludge for making specific subroutines appear to be single instructions during multi-stepping. If the first instruction of a subroutine is an appropriately coded SETAI instruction (rules follow below), then after multi-stepping steps through the call to the subroutine, it will see the SETAI and immediately proceed (with $^N) to the subroutine's return address. Note that there is a stepping flag (see $^^ below) that causes ALL subroutine calls to be treated as single instructions; the purpose of the SETAI crock is to make only some subroutines act that way. One might assemble a program with a SETAI at every entry point and patch the SETAI's of some subroutines into JFCL's, when they are themselves being debugged. The SETAI instruction should address a word which contains the subroutine's return address. For subroutines called by PUSHJ P, use SETAI (P). For subroutines called by JSP T, use SETAI T. For subroutines called by JSR use SETAI .-1. Note that SETAI is not special with ^N - only with ^^. <n>^^ like ^^ but will stop after the <n>'th step if nothing stops it earlier. $^^: <flags>$^^ like ^^ but first changes the job's stepping flags according to the letters in <flags> (which must be 6 chars or less). The letters that mean something are: B step over a subroutine call in one step with $^N. C stop before a subroutine call. (subroutine calls are PUSHJ, JSP, JSR, JSA) D step over subroutine calls with ^N and then step through the subroutine. J stop before jump instructions. K ^N over jumps. M stop before monitor calls. N ^N over monitor calls, but $^N over a .VALUE P print each insn before stepping over it (normal state) Q print insn only when stepping stops before it. R stop before subroutine returns (POPJ and JRA). S ^N over subroutine returns. U treat user UUOs as subroutine calls. V $^N over user UUOs. W stop before user UUOs. X ^N thru user UUOs (and step thru UUO handler). Y enter "care" mode in which ^N'ing thru a UUO whether or not as a result of a ^^, will cause the saved PC in the UUO handler to have its 1-proceed flag set, and the whole UUO handler to be executed as if it were one instruction, returning whenever the UUO handler restores the flags (with JRST 2,). Z leaves "care" mode. Each job has its flags, which are updated by $^^ and used by ^^. The flags are initialized when the job is created, from the new-job-default flags, which are initially 'BPUZ' but may be changed with $$^^ (which might well go in an INIT file). <n> <flags>$^^ combines <flags>$^^ and <n>^^ <flags>$$^^ sets the new-job-default stepping flags according to the letters in <flags>. Does not actually do any stepping. <flags>$$0^^ sets the current job's stepping flags according to the new-job-default and the letters in <flags>. $ (altmode-space) separates prefix command arguments, like altmode-comma. ^_ Incluseive or. ! divides. Priority 2. $! floating divides. Priority 2. If unary, reciprocates. $$! or <arg>$$! opens a location as / or <arg>/ would, but doesn't type the contents. $Q is set, however. Future ^J, ^, and ^I commands will also not type the contents of the locations they open, until a /, [ or ] command is used. " retypes $Q in the " typeout mode, initially ASCII mode. <arg>" retypes <arg> in " typeout mode. $" selects the " typeout mode temporarily. The " mode is controlled by the per-job variable ..TDQUOT. Unless explicitly changed, it is full-word ASCII typeout: ASCII/<foo>/ is printed as $0"<foo>$ . ASCII/<foo>/+1 appears as $1"<foo>$ (the digit is the word's low bit). ^Q and ^ are typed out with an extra ^Q in front. Other control characters are typed out as an uparrow followed by the un-controlified character. Rubout is typed out as "^?". See the section on typeout modes. $<n>"<foo>$ is an ASCII syllable whose value is ASCII/<foo>/+1&<n> (that is, <n> specifies the word's low bit). To put a control character in <foo>, use uparrow (eg. uparrow and A for control-A), or preceded the control character with a ^Q. To put in an uparrow or altmode, precede it by ^Q. A rubout typed in immediately after a ^Q will be quoted, but a ^Q will be rubbed out if other characters were typed in and rubbed out in between. Rubout may be typed in as uparrow-questionmark. $$" specifies " typeout mode as the current mode permanently, so that ^M will not undo it. $$<n>" is used for multi-word ASCII type-in. It acts just like $<n>" if 5 or fewer characters are typed. When the sixth character is typed, the first five are deposited in the open location and the location after it is opened. This is repeated for as many words as it takes to store the whole string of characters. # if there is anything before the #, it means exclusive-or; otherwise, it retypes $Q in # mode. $# temporarily selects the # typeout mode, This mode is controlled by the per-job variable ..TNMSGN. Unless it has been explicitly changed, it is single-character ASCII typeout mode. A value types out as $1# followed by the ASCII character in the low 7 bits. Thus MIDAS's "A is typed as $1#A. MIDAS's ^A (uparrow-a) is typed out as $1#^A . Rubout comes out as uparrow-questionmark. If the number to be typed out goes over the bottom 7 bits, the bottom 7 bits are typed as a character and the rest as an instruction; MOVEI B,101 comes out as "MOVEI B, $1#A". $1# used for single character type-in. Follow it by the character (uparrow and ^Q quote as with $1"). The result is a syllable whose value is the ASCII for that character. Thus, "$1#A" means 101 . $$# specifies # typeout mode as the current mode permanently, so that ^M will not undo it. $ (dollarsign) is not a DDT command in itself, since it is a symbol constituent (just like letters). $$ (altmode dollarsign) temporarily selects $ typeout mode. That mode, held in ..TDOLLA, is initially symbolic mode (same as $S). This command is useful only if the $ mode is changed to a user defined typeout mode. $$$ (altmode altmode dollarsign) specifies $ typeout mode as the current mode permanently, so that ^M will not undo it. % is not a DDT command in itself, since it is a symbol constituent (just like letters). $% temporarily selects the % typeout mode. That mode is kept in the current job's ..TPERCE variable and is initially symbolic mode (same as $S). This command is useful only if the % mode is changed to a user defined typeout mode. $$% specifies % typeout mode as the current mode permanently, so that ^M will not undo it. & if not first thing typed, does logical-and, Priority 3. If not preceded by args, retypes $Q in & mode. $& temporarily selects & typeout mode. This mode, held in the current job's ..TAMPER, is initialized to SQUOZE mode in each new job. In SQUOZE mode, SQUOZE <n>,<sym> types out as $<n>&<sym> $<n>&<sym> a syllable whose value is the SQUOZE for <sym>, with <n> in the flags. <n> should be from 0 to 74; the two lowest bits of <n> are ignored. $$& specifies & typeout mode as the current mode permanently, so that ^M will not undo it. ' retypes $Q in ' mode (normally SIXBIT mode). <arg>' retypes <arg> in ' mode. $' temporarily selects ' typeout mode. This mode, held in ..TPRIME, is initially SIXBIT mode, in which SIXBIT/<foo>/ types out as $1'<foo>$ . $1'<foo>$ is a SIXBIT syllable whose value is SIXBIT/<foo>/ . Only the first 6 characters of <foo> are significant. $$' specifies ' typeout mode as the current mode permanently, so that ^M will not undo it. $$1' is used for multi-word SIXBIT type-in. A cross between $1' and $$1". Uparrow is not special. ( and ) are used for putting a value in an instruction's index field, or, more generally, for swapping the halves of a word-long value. DDT treats the value inside the parentheses just as MIDAS does: if the ( is preceded by an arithmetic operator, the parentheses and all between them act like one syllable whose value is the value of that word with its right and left halves interchanged. Otherwise, the two halves of that word are added into the opposite halves of the word within which the parentheses occur, in an otherwise invisible manner. That is, the argument evaluator's state is the same after the ) as it was before the (. $( and $) these are ignored completely (they can't even be rubbed out). useful with conditionals (see :IF) $$( starts a literal. Use this when typing in an expression to stand for the address of a literal whose data you will specify later. DDT will type out a symbol name and a closeparen; the expression you are typing will contain a forward reference to that symbol, which will become the address of the literal. As soon as it is safe (no location is open, and no literal or patch is being defined), DDT will assign that symbol the address of the patch area and open it, so you can fill in the data of the literal. Deposit the last word of the literal with a $$), which will update PATCH and set "." to what it was before DDT opened the literal. This scheme causes recursive literals to work fine - the inner literal will not be opened until you close the outer one, since DDT can't tell where to start a literal while another literal is being typed in. When you have a delay between the $$( and the opening of the literal, the symbol assigned by DDT will allow you to match the definitions up with the uses. $$) Closes a literal. Defines PATCH to be the open location, or, if none is open, to .+1. Says that no literal is in progress, which may cause DDT to ask for the definition of some other literal. <arg>$$) is equivalent to <arg> <linefeed> $$). It deposits <arg>, then sets PATCH to .+1. * multiplies. Priority 2. $* floating multiplies. Priority 2. + adds. Priority 1. $+ floating adds. Priority 1. , (comma) is used to separate fields in a word. Space also does so. The significance of the fields in a word depend on the pattern of spaces and commas. Usually the value of the word is that of the first field, with all the other fields added into the RH. However, if the first field is followed by two commas, it is put in the left half, and otherwise if followed by one comma, it is put in the AC field. If a space separates the first two fields and a comma ends the second the second is added into the AC field rather than the RH. Examples: <lh>,, truncates <lh> to 18. bits and puts it in the left half. <lh>,,<rh> halfword type-in format. <lh> is put in the left half, and <rh> in the right half. Each is truncated to 18. bits first. <insn> <ac>, a format which adds <ac> into the AC field of <insn>. <insn> <ac>,<addr> a format like <insn> <ac>, but adds <addr> to the right half. <ac>, a format which results in <ac> in the AC field. <ac>,<addr> puts <ac> in the AC field and <addr> in the address field. $, separates multiple args to one operator. - subtracts. Priority 1. If unary, negates. $- floating subtracts. Priority 1. Or, floating negates. . is a symbol whose value is usually the last location opened (except that \, etc., open but don't set ). Whenever "." is randomly changed, the old value is saved in a ring buffer with 8 slots. $^M, $^J and $^ reopen the previous value of ., (plus or minus one for $^J or $^) ^J and ^ increment and decrement the current value of ., rather than pushing the old value. $. has as its value the current job's user mode PC. / opens the location addressed by the RH of $Q. This means that various commands including ^M will store into that location. More immediately, it means that the location's contents will be typed out in the current mode and will be the new value of $Q. Also, the location itself will be "pushed onto the ring buffer of ." meaning that .'s value is now that location, but $^M, etc. can reopen the previous value of ".". (This will not be done if the location just opened is the same as the previous value of .) <arg>/ opens the location addressed by the RH of <arg>. $/ or <arg>$/ opens the location addressed by the LH of $Q or <arg>. $$/ or <arg>$$/ does a PDP-10-style address calculation on $Q or <arg> to determine what location to open. : defines symbols: <sym>: defines <sym> to have the same value "." currently has. If the symbol is already defined in the current block or any containing block, it will be redefined in the same block. Otherwise it will be defined in the current block. <arg> <sym>: defines <sym> to have the value <arg>. $: selects symbol table blocks: <block>$: selects the symbols in block or program <block>. $$: <block>$$: like <block>$: but insists on finding a block directly inferior to the currently selected one. Useful for resolving the ambiguity, when several blocks or programs have the same name. ; retypes $Q in the "semicolon mode", temporarily decrementing ..TTYFLG by 1, so it takes two ^W's to suppress the printout. (Useful in execute files that shouldn't echo their contents, but want to type stuff). The semicolon mode is the most recently specified temporary or permanent typeout mode, even if it was only a temporary mode which was later reset to the permanent mode, e.g., $S sets the temporary mode and the semicolon mode to symbolic. A carriage return will reset the temporary mode to the permanent mode but the semicolon mode will remain symbolic. <arg>; is similar but retypes <arg>, not $Q. $; and <arg>$; are like ; and <arg>; but also reset the temporary mode from the semicolon mode, and don't temporarily SOS ..TTYFLG. $$; and <arg>$$; are similar but also set the permanent mode. > and < (angle brackets) are like algebra's parentheses. > can be used to terminate an expression read in by a colon command (as can a carriage return). $< and > surround an expression to be used as an infix argument in an operator. For example, $<1+1>R is equivalent to $2R $$< and > are similar, for operators with two altmodes. = retypes $Q as a number in the current radix. <arg>= retypes <arg> instead. $<r>= retypes $Q as a number in radix <r>. <arg>$<r>= retypes <arg> instead. $= retypes $Q as a floating point number. <arg>$= retypes <arg> instead. $$= retypes up to three arguments in the modes used to input them. $> when changing part of an instruction, saves typing the unchanged parts: <arg>$> takes those parts of <arg> that are nonzero, or which are known to have been explicitly specified; takes the other parts of a word from $Q, and returns the sum. The parts of a word used are: op code 777000,, ac-field 740,, indirect bit 20,, index-field 17,, address right half. The $> may actually appear anywhere within the argument, because it does nothing but set a flag when the evaluation happens. If an undefined symbol is used (with "?") in either half of the argument, it overrides that halfword of $Q. The fields which $> can tell have been explicitly specified are the AC field, the indirect bit ("@@" specs it explicitly as 0), the left half (eg, "0,,$>"), and the right half (eg ",0$>"). some fields may be explicitly zeroed magically: "0$>" zeroes the address field; "0 $>", the op-code field; and "()$>", the index field. If $> can determine that the quantity is an I/O instruction (CONI, etc.) a different set of fields is used: op-code 700340,, device code 77400,, The address, index and indirect fields are the same as usual. In this situation, "<arg>,$>" will use <arg> to specify the device code. ? performs many functions, in different situations: <sym>? used in expressions to refer to a symbol currently undefined which will be defined later. Attempting to do any arithmetic but addition on such objects, or to put them in the AC field, will lose. However, putting one before a ",," will succeed in putting it in the left half. Only two such objects may appear in an expression and they may be used only to deposit in a location. When an undefined-reference is deposited in core, what really happens is that an entry is made in the "undefined symbol table". When a symbol is defined (with "<symbol>:"), the undefined symbol table is searched, and the value is added to the locations that need it. The table entries for those locations are then removed. The undefined symbol table is dumped by $Y, loaded by $L, and merged by $$L. It can be listed by :LISTU. ? right after a "?U?" (undefined symbol) error message creates a reference to that undefined symbol, just as if the "?" had been typed right after the symbol with no other intervening operator. For example, if FOO is an undefined symbol, and "FOO+BAR" is typed, a "?U?" error will occur after the "+". At that point, "?+BAR" will recover, producing an ultimate result equivalent to "FOO?+BAR". ? when there is no current job, types a basic help text. In other circumstances, retypes $Q in $H$? mode (bit typeout mode). <arg>? where <arg> does not end with a symbol (use a space before the "?" to play it safe), retypes <arg> in $H$? mode. $? temporarily reselects bit typeout mode, with the details as they were last specified. <prefix>$? temporarily specifies bit typeout mode, and sets the main bit name prefix to <prefix>. The alternate prefix is set to the previous main prefix. The pattern associated with the new prefix is the value of <prefix> in the symbol table, if it is defined; otherwise, if "..B" followed by the prefix is defined, its value is used; otherwise, the pattern defaults to 525252,,525252. How those settings are used is described in the special section "bit typeout mode". Note that symbols defined for use as prefixes are also good as masks for $T typeout mode. Especially useful prefixes predefined in DDT are .R, .S, ..R, and ..S. If you have a .SUSET or .USET word that is positive (reading), just do .R$?? to see what variable is being read. For a writing .SUSET or .USET, use .S$??. ..R and ..S are good for .BREAK 12's. $<pattern>? temporarily selects bit typeout mode, and sets the pattern for the main bit name prefix to <pat>. <prefix>$<pat>? the same as <prefix>$? $<pat>?. Like <prefix>$? but uses <pat> as the pattern, rather than the value of <prefix> or 525252,,525252. $0? interchanges the main and alternate bit name prefixes. When combined with a <prefix>, this exchange happens first, so <prefix>$0? sets the main bit name prefix, without changing the alternate one. $$? permanently selects bit typeout mode. $$? interprets arguments otherwise the way $? does. @ complements the indirect bit in the word in which it appears. Is otherwise invisible (see parentheses not preceded by operator). $A or $$A temporarily or permanently selects absolute address typeout mode; that is, addresses will be typed as numbers (see $R). Temporarily or permanently deselects bit typeout mode. $B and variants manipulate breakpoints: $B legal if the current job is stopped at a breakpoint; removes that breakpoint. <loc>$B sets breakpoint at location <loc>. Up to 8 breakpoints may be set in any one job. <loc>$<n>B (where <n> is between 1 and 8) sets breakpoint <n> at <loc>. If breakpoint <n> had been set, it is removed first. $<n>B is the "address" of the location inside DDT which begins the 3-word block holding the information about the current setting of breakpoint number <n>. The first word holds <address to open>,,<address broken>, or 0 if the breakpoint is not set. The 2nd word holds the conditional instruction; the 3rd, the proceed count) <adr>,,<loc>$B sets a breakpoint at <loc> that will type out and open <addr> when it is reached by the program. <loc>$0B removes any breakpoint set at <loc>. 0$<n>B removes breakpoint <n>. $$B removes all breakpoints from the current job. <loc>$$B sets an auto-proceeding breakpoint at <loc>. When an auto-proceeding breakpoint is hit, it prints the usual information, but does not stop the job unless the user types a character. <loc>$$<n>B sets breakpoint <n> at <loc> and causes it to be auto-proceeding. $C or $$C temporarily or permanently selects Constant typeout mode. When a location is opened, its contents will be typed out as a number in the current radix. See $S. $D or $$D temporarily or permanently selects decimal typeout of numbers. See $O. $E or $$E temporarily or permanently selects E&S display processor instruction typeout mode. See $S. <n>$E searches current program for locations with effective address of <n>. Starts at addr in lh of ..LIMIT . Stops at addr in RH of ..LIMIT . Typing a ^D will stop the search, leaving "." set to the last location found. <loc>$,<n>$E searches for such locations after <loc>, stopping at RH(..LIMIT). <loc1>$,<loc2>$,<n>$E searches for such locations from <loc1> to <loc2>. When such a location <locx> is found, "<locx> / <contents-of-locx>" is typed, and "." is set to <locx> (pushing the "." ring buffer). $F or $$F temporarily or permanently selects floating point typeout mode. The contents of locations opened will be printed as floating point numbers. $G starts the program at the starting address (which is contained in ..STARTA). The previous PC is put in ..XECP (a DDT location) in case the program wishes to examine it. <loc>$G starts the program at <loc>. $<n>G does <n>^^ starting from the job's starting address. However, the 1st insn to be stepped through is printed and might be stopped before if the stepping flags say so (^^ would not print the 1st insn or stop before it). Note that $0G merely sets the PC and prints the first instruction to be executed - it executes nothing. <loc>$<n>G sets the PC and types the instruction which the new PC points at $$G: <loc>$$G starts the program at <loc>, and make <loc> the default starting address. <loc>$$<n>G is analogous to <loc>$<n>G $H or $$H temporarily or permanently selects half-word typeout mode. The contents of locations opened will be typed as two addresses separated by ",,", each address being the contents of one half-word. $I turns off the current job's MAR. <loc>$I is the same as <loc>$3I <loc>$<n>I sets the MAR at location <loc>. If <n> is 1, a trap will occur on fetching an instruction from <loc>; if <n> is 2, on writing in <loc>; if <n> is 3, on any reference to <loc>. DDT will print MAR; pc>>instruction showing the instruction that tripped the MAR, before printing the next instruction to be executed. (as always). They may or may not be the same, since the MAR may or may not abort the instruction that trips it. Note that the MAR may be made conditional by putting a nonzero instruction in ..MARCON. When the MAR'ed location is referenced, the conditional instruction will be executed in the job's core, and DDT will stop the job if the instruction skips. Otherwise, DDT will rearm the MAR and restart the job. Subroutine calls are often useful conditional instructions. An arbitrary string of commands may be executed whenever the MAR is tripped by putting the string in the job's core and its address in ..MARXCT. Both ..MARCON and ..MARXCT are cleared by the $I command to prevent confusion. Each job has its own MAR, and its own copy of all the related DDT variables. $J switches the current job in a "convenient" way. If there is a job that wants attention from the user (is waiting to return to DDT), it is selected and allowed to return. If no job needs attention, $J chooses from the existing jobs in an arbitrarily chosen cyclic order, so that successive $J's will find all of DDT's jobs. In any case, the name of the newly selected job is typed out, followed by "$J". If the job reached is another user's job that was being examined and which went away in the meanwhile, DDT will purge itself of the memory of the job, type :KILL and try to open the next job in order. <name>$J makes job <name> the new current job. If no such job exists, one is created (In that case, "!" is typed out). If a disowned job exists, it is reowned, and ":$Reowned$" is typed. $<n>J pops the job-selection ring buffer <n> times. Whenever a job is selected by any command other than $<n>J, it is also pushed on the job selection ring buffer (which is internal to DDT), so that $<n>J can be used to retrace the recent history of job selection. $<n>J is most useful in valret strings which wish to reselect the job which did the valret after temporarily selecting other jobs, without having to make any assumption about the jname of the valretting job. For example, one could do DEBUG$J, hack around, and return with $1J. One could also create a new job with :NEW TECO <commands>, and on exiting from the teco do :KILL $2J to return. The "2" is because the :NEW TECO pushes once, and the :KILL pushes again. $1J $1J could not be used, since the first $1J would try to pop to the no-longer-existing TECO, which is an error condition. $$J types the current job's UNAME, JNAME, state, and job number. $$J prints the info on the current job that $$V prints about each job. <name>$$J set current job's name to <name>. This doesn't switch jobs; it gives the same job a new name. The job's XJNAME is not altered. $K is used for killing symbols: <sym>$K half kills symbol <sym> in the current job's symbol table. When a symbol is half-killed, DDT will no longer use it for type out, but it is still recognized when typed in. $$K kills the entire symbol table of the current job. <sym>$$K fully kills the symbol <sym>, which will no longer be accepted as input. $L <file> loads <file> into the current job's core image. Returns the job's core, kills the symbol table, and closes I/O channels before loading. Temporary breakpoints set by $^N are flushed but ordinary breakpoints set by $B are not. DDT remembers the name of the last file loaded or dumped in each job, and uses it to default any names not given explicitly in <file>. The name specified becomes the new default for the next command. $L, $$L, $Y, $$Y, :LOAD, :PDUMP, :PDUMPI, :SL, :SYMLOD, :SYMADD and $^K all use this default. when a job is created by <name>$J, the default is initialzed to DSK:<msname>;<name> BIN. When a job is loaded into by <prgm>^K, etc. the default is set to the name of the file loaded. <arg>$L <file> loads with an offset of <arg>. That is, anything that should load into <loc> loads into <loc>+<arg>. Doesn't work for :PDUMP'd files. $0L <file> like $L but rather than loading a binary program simply reads the contents of the file directly into core. "." is set to the first location not read into, so that "^" will open the last word read. <arg>$0L <file> reads into core starting at <arg>. $1L <file> like $L, but doesn't load symbols. <arg>$1L <file> loads starting at <arg>, without symbols. $$L <file> as $L but does not zero core, kill symbols, or close I/O channels. Can't be done to a running job. $$0L <file> analogous. $M pertains to word-search comparison masks: <mask>$M sets mask number 0 used for $W and $N searches to <mask>. Only those bits that are on in <mask> will be compared. The mask is initially -1. <mask>$<n>M sets mask number <n>. <n> must be from 0 to 7. Each search may speecify any one of the 8 masks. Thus, after (17)$1M 17,$2M, $1W will compare the index field and $2W will compare the AC field. Initially, $1M is 777777; $2M, 777777,,; $3M, 17,; $4M, (17); $5M, (777000); $6M and $7M are -1, like $0M=$M. $<n>M is the pseudo-address of the word in DDT which holds mask number <n> ($M is the same as $0M). $N: <word>$N searches for locations whose contents differ from <word> in one of the bit positions which are selected by <mask>, where <mask> is what is in $M (set by <mask>$M). Locations found are opened in the current mode and pushed on the "." ring buffer. The range searched starts at LH(..LIMIT), and stops at RH(..LIMIT) (see the $E command). <word>$<n>N where <n> is between 0 and 7, uses mask number <n> (the contents of $<n>M, set by <mask>$<n>M). If <n> is not between 0 and 7, <n> itself is used as the search mask. <loc>$,<word>$N searches starting at <loc>. <loc1>$,<loc2>$,<word>$N searches from <loc1> to <loc2>. <loc1> and <loc2> may be addresses inside DDT, in which case DDT will search through itself. <loc2>,,<loc1>$,<word>$N does the same thing. In <loc2>,,<loc1>$,<loc3>$,<word>$n, <loc3> overrides <loc2>. $O or $$O temporarily or permanently selects octal type-out of numbers. See $<n>R. $P proceeds the current job, giving it the TTY. If it is running, gives it the TTY. If it is waiting to return, allows it to return. If its reason was that it needed the TTY or that it wanted to valret, it is proceeded. <n>$P unless the current job is stopped at a breakpoint, identical to $P. Otherwise, sets the proceed count for the breakpoint that stopped the job to <n>. ($P sets it to 1 in that case) $$P like $P but if job was stopped at a breakpoint, sets that breakpoint to auto-proceed. $Q this has the value of the last quantity which either 1) DDT deposited in a location or 2) DDT found in a location that was opened or 3) DDT was specifically told to type out (by =, $=, ', ", ;, $;, $$;, _, etc.) $0Q identical to $Q. $1Q next-to-last value of $Q (and so on up to $7Q). $$Q is $Q with its halves swapped; <($Q)>. $$<n>Q is $<n>Q with its halves swapped. $R or $$R Temporarily or permanently selects relative address typeout mode, and deselects bit typeout mode. Addresses will be typed as <symbol>+<offset> when possible. The symbol whose value is closest to the address is used. The maximum <offset> allowed is kept in ..SYMOFS; an address requiring a larger <offset> is typed numerically. Symbols in current or containing blocks and programs are preferred to symbols in other blocks or programs if they have the same value. The alternative is absolute mode ($A) in which addresses are always typed out as numbers. $<n>R or $$<n>R temporarily or permanently selects output radix <n>. Input radix is always 8 (or 10. for numbers ending in "."). $S or $$S temporarily or permanently selects symbolic typeout mode. Locations that are opened will have their contents printed in the way DDT thinks is most reasonable (usually as an instruction or in halfword format.) When an address is typed, it may be numeric or symbolic according to the $A vs $R selection. $T or $$T temporarily or permanently selects typeout as bytes, using the most recently specified byte size or pattern. $<n>T or $$<n>T (where <n> is between 1 and 36.) temporarily or permanently selects typeout of words as several bytes of <n> bits each. $<pattern>T or $$<pattern>T (where <pattern> is negative) temporarily or permanently selects typeout of words divided into bytes according to <pattern>. The block of consecutive 1's at the front of <pattern> determines the first byte; the block of 0's following, the second; the next block of 1's occupies the third, etc. Each word to be typed out is divided up in that way and each byte is typed in the current radix. $U or $U. (point required if ..CONFRM is non-zero) reloads and re-initializes DDT. All inferiors are destroyed. If there are any running inferiors, DDT will type "--Kill Running Inferiors--", and read a character from the TTY. If it is a space, DDT will go ahead; otherwise it will type "Flushed" and do nothing. If you were logged in, you remain so, and if you have a <hsname>;<xuname> LOGIN file, DDT will type --Init-- and the file will be :XFILE'd iff the next char you type is a space. <user>$U Logs in as <user>. If <user> is logged in elsewhere, <user>0, <user>1, etc. are tried until one succeeds. Then, a :INTEST (which see) is done to initialize things. $U puts 0 in ..CLOBRF and in ..MORWARN, on the theory that anyone who uses $U (as opposed to :LOGIN) must be a winner. <user>$0U is like <user>$U except that it doesn't do a :INTEST. This is useful to avoid running your init file. <user>$1U Logs in without running any init file or read messages or anything. Super-fast login. $$U logs out (you need not be logged in). Console becomes free. If a file <hsname>;<xuname> LOGOUT or <hsname>:* LOGOUT exists, it will be :XFILE'd before logging out. The file need not have in it a command to log out. If there is no such file, DDT will do a :OUTTEST<cr> as a default action, and then log out. (In other words, check for running inferiors (see $U.), delete the files <hsname>;<xuname> OMAIL .TEMP.;<runame> SENDS if they exist, and clear the screen). $$0U is similar to $$U, but always acts as if there were no <xuname> LOGOUT file. It is always performs $$U's default actions. It is useful when the <xuname> LOGOUT file runs into trouble when it is executed. $$1U logs directly out. Does not run the <xuname> LOGOUT file, and does not do the default actions (:OUTTEST) either. $V manipulates the current job's "raid registers" (also redisplays them): Each job has several "raid registers", each of which may be used to display automatically the contents of one location. Each time the job returns to DDT, its raid registers are displayed at the top of the screen. Each raid register remembers one typeout mode and always displays its location that way (each location is also displayed as a constant in the remembered output radix). See also :RAIDFL which turns off all of a job's raid regs, and ..RAID, which starts a block of 3 words that are global parameters controlling raid registers. See also :RATE and :ATB which set up special sorts of raid registers for observing real-time rates of incrementation of counters, etc., and :RAIDRP which redisplays the raid registers continually with a fixed time interval. $V redisplays the raid registers without changing them. Normally, only raid registers which have changed are updated on the screen. But $V with no arguments forces them all to be updated. This is useful if other typeout has overwritten some of them. $0V toggles the switch ..RAID, which controls whether the raid registers are displayed automatically when the job returns. ..RAID is initially zero, enabling automatic display, except on printing terminals. When it is zero, the raid registers are displayed only by $V commands. $<n>V stores the current typeout mode into raid register <n>, without changing the address it is set on. -1$<n>V free raid register number <n>. <addr>$V set any free raid register on <addr>. If there was already a raid register set on <addr>, it is freed up first. The current typeout mode is remembered in the raid register that is set. <addr> may be indexed or indirect, in which case when the raid register is displayed the effective address will be calculated and the addressed location opened, displaying as "<addr> -> <e.a.>/ <contents>". <addr> may be a .USET variable such as .PIRQC, or a DDT location such as ..UPI0. <addr>$0V free the raid register set on <addr>. If there is more than one, only the lowest-numbered is freed. <addr>$<n>V sets raid register <n> on address <addr>. With this command it is possible to have more than one raid register set on a single location. $$V lists jobs that DDT knows about, along with their states. For each job, one line is typed as follows: <uname> <jname> <state> <job number> (where <uname> will be omitted if the job is DDT's inferior). The current job will be identified by a "*". <state> is as follows: P => proceedable (after a random interrupt). R => running. W => waiting to return to DDT ("needs attention"). - => just loaded. <n>B => broken on breakpoint <n>. $W: <word>$W searches for locations whose contents coincide with <word> in those bits that are set in the mask. Since the number of the mask is not specified, mask number 0 (the contents of $M, which may be set by <mask>$M) is used. The locations found are opened and typed inthe current mode. <word>$<n>W and <loc>$,<word>$W and <loc1>$,<loc2>$,<word>$W and <loc2>,,<loc1>$,<word>$W are analogous to similar uses of $N. $X executes a specified instruction: <ins>$X executes instruction <ins> in the current job's core image. Not allowed if the job is running. It types "<SKIP>" if the instruction skips. If <ins> is a DDT-reference (eg. SETZM ..TTYFLG or SETZM :DDTSYM TTYFLG) the insn is executed in DDT. While the instruction is executing, the PC before the $X is remembered in ..XECPC. $Y <file> dumps the current job's nonzero core locations as <file>. Uses and updates the same default as $L (but if the default directory was SYS:, DSK:SYS1;, DSK:SYS2; or SYS3; because the job was loaded by a ^K or :<prgm>, they will be changed to DSK:<msname>; before the filespec in the $Y is processed. This will not be done if SYS:, SYS1;, SYS2; or SYS3; is explicitly specified by the user). If you quit out of a dump, a file _DUMP_ OUTPUT will be left. A previous file with the names being dumped under will not be clobbered. <loc1>$,<loc2>$Y <file> dumps core from <loc1> to <loc2> $0Y <file> writes core out into a file directly, without formatting ($Y dumps as a binary program). $$^Y: <loc1>$,<loc2>$$Y <file> and other combinations of the above are analogous to $^Y. $$Z zeroes core of this job. If the job's ..SAFE is nonzero, asks "--Zero Protected Job--" before zeroing. <loc1>$,<loc2>$,<word>$$Z sets core from <loc1> to <loc2> to <word>. [ is like / but types out as a number, rather than in the current mode. <arg>[, $[, <arg>$[, $$[, and <arg>$$[ are like the corresponding / commands, but type the word opened as a number. \ opens the location addressed by $Q's RH except: does not set "." or push the "." ring buffer. Thus, linefeed will open 1 + the last location opened other than by \ . <arg>\ deposits <arg> in the open location, if any, then opens the location addressed by the RH of <arg> in the same way \ opens a location. $\ and <arg>$\ are similar, but open the LH of $Q or <arg>. $$\ and <arg>$$\ do a PDP-10 address calculation on $Q or <arg>. ] is like / but types out in symbolic mode rather than the current mode. <arg>], $], <arg>$], $$], <arg>$$] are all analogous to the corresponding forms of /. ^ types the value of and opens .-1, on a new line. Sort of the opposite of linefeed. <arg>^ stores <arg> in the open location, then does ^. $^ pops the "." ring buffer, then does ^. <arg>$^ stores <arg>, then does $^. $<n>^ pops the ring buffer of "." <n> times, then does "^". <arg>$<n>^ stores <arg>, then does $<n>^. _ retypes $Q in symbolic mode. <arg>_ retypes <arg> in symbolic mode. $_ left-shifts. Like _ in MIDAS. Priority 3. $$_ floating scales. � Colon commands: The DDT operators ":", "$:", and "$$:", when not preceded by symbols, are prefixes that begin mnemonically named "colon-commands". After the colon comes the command name, followed by the arguments, if any. The command may be built into DDT, or it may run a system program. In fact, if DDT does not recognize the command name as a built in command, it runs the system program with that name. Note that many programs usually run in this way are popularly thought of as "DDT commands". However, only the actual built-in DDT commands are specifically described in this file (on the next page). The general workings of colon commands that run programs are described on this page, but for the format of their arguments the documentation of the individual programs must be consulted. There are the following special hacks: 1) an altmode after a colon starts a comment. Everything from the altmode to the next altmode, inclusive, is ignored. For example, :$ FOO $PRINT BAR<cr> is the same as :PRINT BAR<cr>. 2) :<cr> does nothing but close the open location (There may be a comment between the : and the <cr>). Anything else runs either a built-in command or a program. Colon commands to run programs: 1) :<prgm><cr> where <prgm> is not the name of any built-in colon command, tries to run the program named <prgm>. It looks for TS <prgm> on DSK:<hsname>;, on SYS;, then on SYS1;, then on SYS2;, then on SYS3; and then on all the user directories in the sname search list if it is enabled (see :NFDIR), and then on the connected dir. If the file is found, it is loaded without symbols into the job named <prgm> (which will be created if necessary) and started at its normal starting address. The job's command buffer will be cleared. If the job already existed (was not created fresh by :<prgm>), :<prgm> can behave either like :NEW <prgm> or like :RETRY <prgm>, depending on ..GENJFL's contents. If ..GENJFL is zero, :RETRY <prgm> is done: the pre-existing job is used for running <prgm>, thus overwriting any data that was in that job already. However, before doing this, if ..CLOBRF is nonzero, DDT will ask for confirmation by saying "--Clobber Existing Job--". A space means "yes". If ..GENJFL is nonzero, as it is by default, :NEW <prgm> is done; the old job is left alone and another job is created for the purpose of running <prgm>. See :NEW and :RETRY, below. In any case, the .XJNAME of the job will be <prgm>. Programs that want to be runnable under many names and do different things according to which name was used should check their .XJNAME. 2) :<prgm> <text> is similar, but provides <text> as an argument to <prgm>. As above, <prgm> must not be the name of a built-in command. Also, <text> must end with a <cr> or "^C" or "^_". <text> is put in DDT's command buffer for the job <prgm> (instead of zeroing the buffer, as :<prgm><cr> does). Programs should read the command buffer with .BREAK 12,[..RJCL,,<loc>] and interpret the contents in a useful way (eg, as commands). For example, :MIDAS FOO<cr> will run MIDAS and tell it to assemble FOO >, giving FOO BIN . 3) :<dev>:<prgm><cr> runs <dev>:<msname>;TS <prgm> in a job named <prgm>, zeroing the command buffer. It does not matter if <prgm> is the name of a built-in command when a device is explicitly specified. The job's $L default filename is set to <dev>:<msname>;TS <prgm>. 4) :<dev>:<prgm> <text> is similar but puts <text> in the job's command buffer. <text> is terminated by a carriage-return or "^C" or "^_". 5) :<user>;<prgm><cr> is like 3) but uses file DSK: <user>; TS <prgm>. 6) :<user>;<prgm> <text> figure it out. :<dev>:<user>;<prgm><cr> " :<dev>:<user>;<prgm> <text> " 7) $: and $$: may be used instead of just : in all the patterns described above. They suppress built-in commands, and always try to run a program. In addition, $: causes the program to be loaded with symbols. $$: suppresses even the commands :NEW and :RETRY, but $: causes them to load the programs specified to them with symbols. 8) :NEW <prgm><cr> is similar to :<prgm><cr>, except in what happens when a job named <prgm> already existed. In that case, instead of destroying its old contents, a new job with an incremented (with :GENJOB) name will be created. Thus, :NEW T<cr> when a job named T existed will create job T0; another :NEW T<cr> will create job T1. In any case, the .XJNAME of the job will be <prgm>. Programs that want to be runnable under many names and do different things according to which name was used should check their .XJNAME. :NEW suppresses built-in commands, so that, for example, :NEW START<cr> would load a new copy of a program names START whereas :START by itself is a built-in command. :NEW may be combined with the other options, as in $:NEW MC:SYS;MACSYM command-string<cr> 9) :RETRY <prgm><cr> is similar to :<prgm><cr>, except that if a job named <prgm> already exists a clean copy of ts <prgm> will be loaded into it, clobbering any data from the previous invocation of <prgm>. Even if ..CLOBRF is nonzero, DDT will not ask for confirmation, since the :RETRY is taken to mean that clobbering is desired. :RETRY suppresses built-in commands like :NEW (see above). :RETRY may be combined with the other options, as in $:RETRY MC:SYS;MACSYM command-string<cr> � Built-in colon commands: (NEVER invoked by altmode-colon or altmode-altmode-colon) :6TYPE <expression> will type the expression as sixbit, with no quoting or delimiters. If no <expression> is given, it uses $Q for its arg. :8TYPE <value> or :8TYPE<cr> This is a quick-and-dirty crock to aid CHAOSNET hackers and CRTSTY hackers. If used in the :8TYPE<cr> form, it uses the value of $Q, otherwise it uses the given value, and prints it if it were a word of 8 bit characters. If the 200 bit is on, the character is proceeded by a ~. The characters are separated by spaces. At some point in the future this should be re-done as a typeout mode that you can put on & or % or such. Also, there should be a way to type this stuff in. Suggestions for exactly what it should do are welcome, in the meantime, I offer this crock as a way of getting it into this version. :? prints the file .INFO.;DDT :CMNDS, which is a condensation of the info on this page of DDT orders. :ALARM <hr>:<min>:<sec> (where <hr>, <min> and <sec> are decimal numbers and a <cr> instead of a colon causes all the following fields to be taken as 0) sets an alarm at the time specified. DDT will type bells and a message every 20 seconds from that time on until the alarm is cleared. :ALARM .+<hr>:<min>:<sec> sets an alarm when the specified time interval has elapsed. :ALARM<cr> clears any alarm setting. :ALSO<cr> is a conditional which succeeds if the previous conditional succeeded. It should be followed by conditionalized commands, surrounded by a $( - $) pair, just like :IF. :ASSIGN assigns the microtape which is the current ^F default device. If that device isn't a microtape, it is an error. microtapes must be assigned to be used. :ASSIGN <tape> assigns that microtape. <tape> may be a number or a device name. That microtape becomes the default device, as with <tape>^F. :ATB <addr> sets a raid register to display the average time between increments of the contents of <addr>. Each time the raid register is displayed it will show the average over the time since the previous display. See also :RATE, which will show the average rate of change. :RAIDRP is likely to be useful with this command. :ATTACH makes the current job replace DDT in the job tree. DDT and its other inferiors cease to exist, and the inferior attached takes on DDT's JNAME. :CHUNAME <newuname> changes your UNAME to <newuname>. Kills all jobs (typing "$$^X." if there are any jobs to be killed). Then, resets all user-options by reloading DDT Then, does a :INTEST, to attach <newuname> HACTRO or run <newuname>'s init file or whatever. :CLEAR clears the screen on graphics TTYs. Useful in files and valrets since ^L is ignored in them. Although when the TTY is in scroll mode DDT usually forbears to clear the screen, :CLEAR forces the clear to be done even in scroll mode. :CONTINUE restarts the current job where it last stopped, giving it the TTY. Equivalent to $P. :COPY <file1>,<file2> :COPYD <file1>,<file2> copies <file1> as <file2>, I/O is done in ASCII block mode. For DSK, AI, ML, MC, DM and archive devices, that is the same as image block mode, so :COPY will work for any files on those devices.) The creation date of <file2> is set to that of <file1>, as well as the file author. In addition, the real file names of <file1> are used as the defaults for <file2>, so that :COPYD AI:FOO >,ML: will preserve the FN2. If a <cr> is used instead of a comma, the new defaults will be typed out before <file2> is read. After the :COPYD, the defaults are set to <file1>. :COPYN <file1>,<file2> is like :COPYD except that the new file's creation date is set to right now, and the defaults for <file2> are the names specified for <file1>, not the real names of <file1>. If <file1> was FOO >, then :COPYD would preserve the version number of FOO, while :COPYN would increment the version number present on the target directory. :CORBLK <subcommand> <address> creates, deletes, purifies or unpurifies the current inferior's page containing the address <address>, according to the <subcommand>, which may be FRESH, NONE, PURE or IMPURE. :CORTYP <loc> prints information on the type of page that <loc> is on in the current job. :CORPRT maps :CORTYP over the existing pages of the current job. :CWD <directory> sets the working directory name (MSNAME) to <dir>. Equivalent to <dir>$$^S. :DATPRT <expression> :DATPRT was released earlier using $Q for it's argument. if no <expression> is given, it will still use $Q for it's argument. :DATPRT<cr> retypes $Q as a date. I.e. it assumes that Q is an ITS disk-format date word, and types it in human-readable format. :DATWRD <date> has as a value the ITS disk-format date word corresponding to date, in the same format taken by :SMDATE, :SFDATE, and friends. 100/ :DATWRD 10/15/78 16:40:25<cr><cr> will deposit the date word for October 15, 1978, 4:40:25 pm in location 100. :DDTMODE leaves monit mode. See :MONMODE :DDTSYM <sym> evaluates one of DDT's own symbols (NOT one of the current job's symbols. That needs no special command). The value is returned as a pointer into DDT. The character terminating <sym> is re-read. Thus, :DDTSYM TTYOPT/ will open location TTYOPT in DDT. :DELETE <file> deletes <file> . Uses and updates the same default name as :PRINT, etc. See "filename reading" and "filename defaulting". :DESIGN deassigns the microtape which is the current ^F default device. If that device isn't a microtape, error. :DESIGN <tape> deassigns that microtape. Sets defaults like <tape>^F. :DETACH detaches the entire tree from the console, which becomes free. The tree becomes disowned. It can be reconnected to a terminal with the REATTACH program, or it can be reowned with $J. If the same user logs in again, DDT will automatically offer to attach the detached tree. If the JNAME of the top-level job being detached is HACTRN, it will be incremented at least once, and again until it is unique; thus, it will become HACTRO or HACTRP, etc. :DETACH is illegal if not logged in. :DISOWN turns the current inferior job into a disowned job. It can be reowned later by you or anyone else using the $J or :UJOB commands. Until then, it can continue to run (if it was running when it was disowned) but cannot use the terminal since it does not have one. See the $$^K command. :ELSE<cr> is a conditional which succeeds if the previous conditional failed. It should be followed by conditionalized commands, surrounded by a $( - $) pair, just like :IF. :ERR<cr> prints out the error message associated with the last IOC error or open or symbolic system call failure in the current job. :ERR <chnl> where <chnl> is a channel number, prints out the error message associated with the last error on that channel. :ERR <code> prints out the error message associated with the status word <code>, where <code> might be obtained, for example, by opening .IOS+<chnl>. :EXISTS <file> returns 0 iff <file> can be opened, else the I/O status word containing the open failure code. Uses the same defaults as :PRINT, etc. Useful with conditionals (:IF). :FJOB FOO is like :JOB FOO, but will never reown the job. The job is marked as permenently foreign, and subsequent $J's to it will not reown. To reown it, do :FORGET and :JOB FOO :FJOB FOO BAR is like a combination of :UJOB FOO BAR and :FJOB :FLAP flaps a microtape if it's the ^F default device. :FLAP <tape> flaps that tape; sets defaults like ^F. <tape> may be either the microtape number or its device name. :FORGET tells DDT to forget about the current job. If it is a foreign job, this is equivalent to :KILL (this is stated backwards). For an inferior job, the job remains DDT's inferior, but DDT no longer knows it is there. If it had been $$^P'd, it can still type out. The job can't be killed while forgotten, unless you log out. To make DDT know about the job once again, simply select it explicitly with $J. :GAG <n> if <n> is 0, tells DDT to stop accepting :SEND's. Anyone who tries to :SEND to you will mail instead. If <n> is not 0, DDT will resume accepting messages. :GENJOB rename the current job to a gensymmed name. Programs may wish to valret a :GENJOB when they start up, to make sure that running the program a second time doesn't interfere with the first invocation. :GENJOB does not print the new name. The new name is computed from the current name as follows: the first space in the name, or the last character if there is no space, is the incrementing position. First, put a zero in that position; if that name is in use put a 1 in that position, etc. Loop incrementing that character until a name is obtained that is not in use. That name is the new name of the job. The .XJNAME variable is NOT changed. :GO<cr> starts the current job at its starting address. Same as $G :GO <addr> starts the job at the spcified address, like <addr>$G :GZP<cr> starts the job at its starting addr without giving it the TTY. like $0G ^P. Equivalent to an "instantaneous" sequence of $G, ^Z, ^P (whence the name of the command). :GZP <addr> similar but starts at <addr>. :HELP prints out some very basic information on how to stay alive on ITS (tells what ^S does, lists a few :-commands, where to get more help, etc) :ICHAN <chan> <chan> is taken to be a channel number (it may be an expression) Status info for that channel in the inferior is printed. :IF <condit> <arg> $( <conditionalized stuff> $) (where <condit> is one of "E", "N", "G", "L", "GE", "LE", and "MORE"; and <conditionalized stuff> is balanced in parens) skips up to the $) if the condition is false. ^B, ^E, ^V, ^W are ignored in what is skipped. All the conditions except "MORE" compare the arg to 0. "MORE" enters a --More-- state waiting for a char to be typed in, and succeeds if the --More-- isn't flushed. (--More-- is not typed by this command. If such a message is desired it should be typed before the :IF). The "MORE" conditional needs an arg but ignores it. To conditionalize something not balanced in parens, such as $1#(, use extra $('s and $)'s to make the parens match (since $( and $) are conveniently ignored by everything except false conditionals). Actually, a false conditional skips until the close-paren that matches the first open-paren. The parens need not be part of $( and $); doing that is only to make sure they're ignored if condition is true,which is usually right. :INFLS flushes any pushed execute files and valret strings. :INPOP<cr> useful when a valret or execute file was pushed; pops back into it. :INPOP <line> (where <line> ends with a <cr>) causes <line> to be executed as DDT commands, then pops back to a pushed execute file or valret. eg., :INPOP $P <cr> will proceed the current job and pop into a valret or xfile. :INPUSH useful in a valret or execute file; pushes that input source and allows input from the TTY, until a :INPOP command is given, after which input from the valret or file will resume. An :INPUSH command is executed automatically on any error in DDT, and whenever an inferior returns to DDT in any way that .RESET's TTY input (The only things which don't are: .BREAK 16,'s which specifically say not to, return from a ^N, return from $X, and a .VALUE with nonzero arg, which will cause the file or valret in progress to be pushed while the new valret string is executed) When that happens, DDT will type ":INPUSH ". At those times, DDT will also turn on the typeout flag and type "^V " if it had been off. :INTEST performs the same actions that a $U command which succeeds in logging in takes, except that it doesn't log in. Those actions are: If your home directory is not the same as your <xuname>, DDT will inform you by saying "[Home dir=<hsname>]" If a job <runame> HACTRO exists, and if running, DDT types "--Attach Your Detached Tree--" and does so if the reply is a space. Otherwise, DDT looks for an initialization file (in <hsname>;<xuname> LOGIN, or in <hsname>;* LOGIN if that is not found.) If DDT succeeds in finding one of those files, it considers :XFILE'ing it: if <xuname> equals <runame>, DDT just types "INIT" and :XFILE's it unconditionally, but otherwise it asks "--Init--" and :XFILE's the init file only if the user types a space. However, if the init file which would be run is one of GUEST1;* LOGIN or USERS1;* LOGIN, it is run without asking, so that naive users can always get the "safe" switch settings. Otherwise, if a file <hsname>;<xuname> MAIL exists, DDT types "--Mail--" and reads a character from the TTY. If the character is space, DDT prints the file and renames it to <xuname> OMAIL. Also if there is no init file: if the user has a date entry in the :MSGS database (i.e. if he has ever done a :MSGS), or if he has a directory, a :MSGS command will be executed a :MSGS command will be executed to print any new system messages. If there are any new messages, "--Msgs--" will be typed before each one, and if the user's response is other than space or rubout, DDT will leave the messages for later. If the automatic :MSGS is not done (user has no dir and no database entry), the user will be informed of the existance of the :MSGS command in case he is a new user. A special hack causes a :INTEST given in an execute file or valret string to pretend that there is no init file; it will always try to print mail and messages. It is a useful thing to put in an init file to print mail and messages in the default manner, in addition to the ideosyncratic things the init file is needed for. :INTPRT analyses the value of $Q as a word of interrupt bits, printing out the names of the bits that are set, using the same names used when a job returns to DDT. If the sign is set, the word is interpreted as 2nd word interrupts; otherwise, as 1st word interrupts. :IOPEN <chan>$,<control bits>$,<filename> This opens <filename> with mode <control bits> on channel <chan> in the current job. The resulting TRUENAME is then printed. :JCL<cr> clears the current job's command buffer. (the one that .BREAK 12, can read) Turns off the job's .OPTION variable's bit 4.6 (OPTCMD). :JCL <line> (where <line> ends with a <cr> or "^C" or "^_"). puts <line> in the command buffer, including the terminating <cr> or "^C" or "^_". Sets the .OPTION variable's bit 4.6 (OPTCMD bit) :JCLPRT prints the JCL of a job :JOB <name> like <name>$J except that there may be non-squoze characters in <name>. :JOBP <name> is like :JOB <name> except that it sets $Q to 0 if it succeeds, else nonzero. :JUMP <tag> jumps to a :TAG <tag> in an execute file or valret string. A conditionalized :JUMP to a :TAG which precedes it makes a loop. :JUMP is not allowed to be typed from the terminal unless you are inside a :INPUSH from a valret string or execute file. In that case, :JUMP pops out to the file or valret and jumps to the tag in it. Aside from this case, nonlocal :JUMP's are not allowed. :KILL kills the current job, like $^X. If the job is "protected" (its ..SAFE variable has been set nonzero), DDT will ask for confirmation before killing it. :LFILE prints the name of the last file loaded into the current job (.BREAK 12, can also read this info). :LINK <file1>,<file2> makes a link named <file1> pointing to <file2>. If a file named <file1> exists, :LINK will type an error message rather than delete the file. :LINK uses the same defaults that :PRINT, :DELETE, etc. use. (see defaulting of filenames) the defaults for <file2> will be <file1>. After the :LINK, the defaults will revert to <file1>. Actually, the names in <file2> are subject to "translation" (see $^T) as if they were being opened, and the translated names are used. If <file2> is on a non-disk device, such as another machine, an error message occurs, unless <file1> is on the same device. Thus, it is possible to make links on job devices provided the job device handles the call correctly. The AI:, DM:, MC:, and ML: devices do win. ** This command is disabled with warning if ..DELWARN is set to 3 :LINKF <file1>,<file2> Just like :LINK, except if ..DELWARN is set to 3, it gives warning message rather than being disabled. :LINKN <file1>,<file2> is like :LINK, except no check is made that <file1> does not already exist. Thus, :LINKN may be used to replace an existing file or link. ** This command is disabled with warning if ..DELWARN is set to 3 :LISTB lists all breakpoints set in the current job as follows <n> <addr-to-open>,,<addr-of-bpt> <condit. insn> <count> :LISTF <dir-spec> <cr> lists the specified directory. A dir-spec may contain a device name followed by ":" and/or an sname optionally followed by ";". It is terminated by "," or <cr>. Altmode may be used as in file-specs. The specified directory becomes the default one for :PRINT, :DELETE, etc. :LISTJ lists all the jobs that DDT knows about, along with their states. For each job, one line as typed as follows: <uname> <jname> <state> <job #> (<uname> will be omitted if the job is DDT's inferior). The current selected job will have a "*" before it. <state> is one of: P = Proceedable (after a random interrupt) R = Running W = Waiting to return to DDT ("needs attention") - = just loaded. <n>B = Broken on breakpoint <n> :LISTP prints the block-structure of the current job's symbol table. Each program is indented one space; each block, 2 or more according to its level. The entry for the global block comes first. Every block or program precedes its subblocks. :LISTS lists the names of all the symbols in the current job's symbol table. Block and program names are flush against the left margin. All others are in rows that start with two spaces. :LISTU lists all undefined symbol references (created by <sym>? ) in the current job. :LJCL allows you to give the current job arbitrary length JCL, ended with a control-C, so carriage returns can be included in the JCL. This is useful for mail from init files, for example. It provides the same editing that :SEND does. See also :LRUN :LOAD <file> loads <file> into the current job's core image. Returns the job's core, kills the symbol table, and closes I/O channels before loading. See the $L command for more info. :LOGIN <name> identical to <name>$U except that non-squoze chars may appear in <name> , and does not clear ..CLOBRF and ..MORWRN (ie, a user of :LOGIN is assumed to be naive). :LOGOUT logs you out (you needn't be logged in) -- Console becomes free. If a file <hsname>;<xuname> LOGOUT or <hsname>;* LOGOUT exists, it will be :XFILE'd before logging out. The file need not have in it a command to logout. If there is no such file, DDT will do a :OUTTEST as a default action, and then log out. (In other words, check for running inferiors (see $U), delete the files <hsname>;<xuname> OMAIL and .TEMP.;<runame> SENDS if they exist, and clear the screen). :LRUN <program> <optional line(s) of JCL>^C is not new, but should now work properly, so is being anounced. It is like a cross between :LJCL and :RUN. The editing features of :SEND are also present. :MAILNT <-2, -1, 0, 1, or 2> -- Mail notify This command is only useful if you have already told COMSAT not to bother telling you of mail arivals (or if you gag yourself, but that's not really useful). To turn off COMSAT's notifications, make a NAMES entry of the form: (CSTACY (R-OPTION NO-CLI)) The advantage of :MAILNT is that you can turn off mail notification, but not higher priority :SENDS while in EMACS (see ..SENDRP/-2 and ..URANDM/ %URMAL), and then get the notification of arrival of mail when you return to DDT, while getting your SENDS immediatly. Also, DDT will do a better job (I think) of telling you who sent the mail than COMSAT will with (R-OPTION SMALL-CLI). :MAILNT 0 -- The default, do not notify. :MAILNT -1 -- Beep on arrival of mail, but print nothing. :MAILNT 1 -- Print who the message is from and how long it is. Assumes the message will be the first one in the file. :MAILNT 2 or -2 are like 1 and -1 except mail is deferred while in any inferior. Mail notification can be inhibited while in a specific inferior by doing ..URANDM/ $Q^_100 from DDT or a valret string or by setting the URANDM word with a .BREAK 12, :MASSACRE kills all jobs, like 8 :KILL's. :MONMODE enters monit mode, in which DDT generates a colon whenever it wants input at top level, except in valret strings and execute files. This causes input to be taken as colon-commands. Note that if you rub out one of those colons DDT will not replace it - you will thus leave monit mode temporarily, but any error will make DDT start generating colons again (for example, rubout when there's nothing to rub). :MORE useful in execute files and valrets. First, it turns on typeout by zeroing ..TTYFLG. Then, it reads (and echoes on the TTY) a line from the file, then reads a character from the TTY. If it is a space, continues with the file; otherwise does a :INPOP<cr> . One might want to put this before a command which clears the screen. A similar, more general feature is ":IF MORE". :MOVE <old file>,<new file Copies a file from <old file> to <new file> and deletes the old copy. It does a delete-while-open, so there is no danger of it deleting the new file if it displaces the old, as in :MOVE FOO;BAR BAZ,SECOND: :MSGS<cr> prints system messages. It uses a file SYS:^Q:MSGS TIMES to store a database of login names and the date of the most recent message they have seen, and prints only such messages as have appeared since that time. The messages are printed in chronological order. Before each message, DDT will type "--Msgs--", and read a character from the TTY. Space or rubout will tell DDT to clear the screen and begin the message; anything else tells DDT to stop, and the remaining messages will not be seen until the next :MSGS command. DDT begins to print a message by printing its filenames, followed by the first line of text. After the first line of the message, if there is more, "--More--" will be typed, and a character read. Space will type the rest of the message, rubout will flush the rest and continue with the next message, if there are more. Anything else will be as after "--Msgs--". "^S" typed in while DDT is printing a message will throw away the rest of that message only. ^G'ing out of a :MSGS is safe and will cause all the messages to be seen again. This command is automatically executed by :INTEST and on login unless you have an init file or don't have an entry in the date database. NOTE that :MSGS<cr> will see only messages intended for the machine that you are on, even though .MSGS.; will contain all machines' messages. This is because :MSGS<cr> turns itself into :MSGS *AI<cr> when done on AI;, :MSGS *ML on ML, etc. :MSGS <kwd1>,<kwd2>,<kwd3>,... is like :MSGS<cr>, but prints only messages which have at least one of the specified keywords in the "distrib" field. Messages with no distrib field are for everyone, so :MSGS with keywords will see all of them, too. The keywords so far defined are *AI, *ML, *DM, and *MC. A message's distrib field shows which machines it is "intended" for; messages mailed to *ITS will have all four keywords. Thus, :MSGS<cr> will see only the messages intended for the machine it is done on, but :MSGS *AI,*ML will see all messages intended for AI or ML, and can be run on any machine (even MC!). Someday additional keyword conventions may be implemented. :MSGS * shows all messages, no matter which machine they are for. :NEW <prgm> is similar to :<prgm> except in what happens when a job named <prgm> already exists. In that case, instead of destroying its old contents, a new job with an incremented (with :GENJOB) name will be created. Thus, :NEW T when a job named T already exists will create job T0; another :NEW T will make job T1, etc. :NEWTTY informs DDT that its TTY may have changed its characteristics. DDT will reinitialize all its info on what type of TTY it is using. If the %TOROL bit is on (scroll mode is the default), DDT will enter scroll mode. When in scroll mode, DDT never clears the screen unless it is given an explicit :CLEAR command. :NFDIR <name1>,<name2>,<name3>,... (any number of names) enables the sname search list feature if not enabled, and puts the specified names, in reverse order, at the front of the list, which is searched front to back. A name appears only once in the list, which holds 8 names. When the feature is enabled, ^K, etc., and $L on device DSK with no directory specified look on all the directories in the list if the file isn't found on the default directory. If it is found on a directory in the list, the sname of that directory will be typed out, followed by a semicolon. (This can be silenced by zeroing the NFVRBS variable in DDT.) A separate list of the 8 most recently used snames is also searched. :NOMSG <n> if <n> is 0, turns off all unsolicited typeouts by DDT, including alarms, sends, ITS revived messages, and even system going down messages unless the system is going down in less than 15 minutes. The effect of :GAG 0 is implicit (and the :GAG setting is ignored when :NOMSG 0 is in effect). <n>=1 leaves this mode, and prints out the pending typeouts (a list of waiting jobs, etc.) that couldn't be printed before. Note that if a job sets bit 20 in its ..URANDM word, then :NOMSG 0 is temporarily in effect whenever that job has the tty. :OFDIR <name1>,<name2>,<name3>,... (any number of names) removes those names from the search list. :OFDIR<cr> disables the sname search feature and clears the list. :OLOAD <file> loads certain files whose symbol tables are incorrectly formatted, because they were made by old versions of STINK and had data loaded above 400000. Files produced by recent versions of STINK and MIDAS never have this problem. :OMAIL <user> <message>^C ** This command is semi-obsolete -- use the "MAIL" program ** adds <message> to the front of <user>'s mail file; he will see it when he logs in (unless he has an init file which doesn't print his mail) or when he does :PRMAIL<cr>. When typing in the message, rubout deletes and echoes one character; ^G and ^D cancel the message; ^L causes the characters typed in so far to be printed (after clearing the screen); ^C and ^_ end the message and cause it to be sent. (^_ is useful in xfiles since ^C terminates them). in the mail file, each note looks like: " <sender>@<machine> <date> <time> <message> ^_" :OMAILA <user> <message>^C ** This command is semi-obsolete ** adds to the note this user most recently mailed to <user>; that is, the message etc. is added not at the front of the mail file but just before the ^_ terminating the previous note. If there is no note from this user in <user>'s mail file, the new note is added at the end. :OMSG <topic> <message>^C is the old way of mailing a message to all users. :MAIL *ITS, which runs the mail program, should be used instead. :OMSG writes a file .MSGS.;<topic> > containing your runame, the date and time, and <message>. :MSGS will print the file, so every user ought to see the message once. ^_ may be used instead of ^C. Please do not use this. :OSEND Always runs DDT's :SEND command even if it has been disabled by ..SNDFLG/-1 :OUTTEST performs the actions normally associated with logging out. It does not execute the <xuname> LOGOUT file. :OUTTES always does what $$U and :LOGOUT do if there is no LOGOUT file (except that :OUTTES does not actually log out). Specifically, it checks for running inferiors, querying "--Kill Running Inferiors--" if there are any (and causing an error if the query is flushed), deletes the files <hsname>;<xuname> OMAIL and .TEMP.;<runame> SENDS, and clears the screen. Due to an extremely hairy bug in the logout code, if the file <xuname> LOGOUT exists AND BYERUN is set, :OUTTEST will not behave as advertised, but instead will execute the LOGOUT file and log out. In other words it will act the same as $$U. If you have a LOGOUT file and you want a bye message, just put :BYE in your logout file. :PDUMP <file> like $Y but does a "pure-dump" - all jobs which have that file loaded will share the pure pages in it. If you quit out of a pdump, a file _DUMP_ OUTPUT will be left. A previous file with the names being dumped under will not be clobbered. :PDUMPI <file>,<ifile> like :PDUMP, but writes an indirect symbol table pointer, pointing to <ifile> instead of a regular symbol table. This is useful for dumping programs which map in other files, such as dumped LISP's. :PMDATE prints the date of the last message seen. Only messages new than that will be printed :PRGM prints the name of the currently selected block of symbols. If it is the global block, that's all. If it is a program, types ", program". Otherwise, prints ", level " and the block's level. :PRINT <file> types the file's contents. Uses the same default as :DELETE. :PRMAIL<cr> prints your mail file (<hsname>;<xuname> MAIL and renames it as OMAIL . On display terminals, "No mail" is typed if no mail file exists. Depositing 0 in :DDTSYM OMAILF causes :PRMAIL<cr> not to rename the mail file, but only print it. Depositing a positive number causes it to ask if you'd like to delete it. :PRMAIL <user> prints <user>'s mail file if it exists; else types "No mail". It is not renamed to OMAIL. :PRMAIL <user>@<site> where <site> is one of AI, ML, MC, or DM, forces DDT to look for the mail on that site. Useful for those few people who direct their mail to more than one ITS. :PROCED restarts the current job where it last stopped, but DDT keeps the TTY. The job runs, but can't do any I/O on the TTY, and DDT continues to execute the user's commands. Equivalent to ^P. :PROCEED same as :PROCED - restarts the current job without giving it the TTY. :PRSEND<cr> prints your SENDS file, which contains al the :SEND messages you have received in this session. It is .TEMP.;<uname> SENDS or COMMON;<uname> SENDS if the directory .TEMP.; doesn't exist. :PRSEND <user> print's <user>'s SENDS file. :PRSEND <user>@<site> where <site> is AI, ML, MC, or DM, prints <user>'s SENDS file from that site. :RAIDFLUSH turns off all of the raid registers of the current job. The storage for them is deallocated, so their settings are all forgotten. :RAIDRP <# secs> puts DDT in a loop redisplaying the raid registers of the current job every <n> seconds. Typing any character will cause DDT to exit the loop and process the character. :RATE <addr> sets a raid register to display the rate of change of the contents of <addr>. Each time the raid register is displayed it will show the average rate of change of the contents since the previous display. See also :ATB which shows the inverse rate. :REAP <file> sets <file>'s reference date to long ago, so that if automatic grim reaping is done <file> will be reaped. :RENAME <file1>,<file2> renames <file1> to the name <file2>. Uses the same defaults as :PRINT, :DELETE, etc. <file2> defaults to <file1>. :RETRY <prgm> is similar to :<prgm> except that if a job named <prgm> already exists, a clean copy of TS <prgm> will be loaded into it, clobbering any data from the previous invocation of <prgm>. Even if ..CLOBRF is nonzero, DDT will not ask for confirmation, since :RETRY is taken to mean that clobbering is desired. :RUN <program> <optional one line of JCL><return> (See also :LRUN) <program> can be either a program or a DDT command. If it's a DDT command, it will be performed with one level of ^V turned off. :SELF is equivalent to HACTRN$J except works if the JNAME isn't HACTRN This is the right way to select the running DDT in an XFILE. :SEND <user> <message>^C If <user> is logged in and has not done :GAG 0, prints "[MESSAGE FROM <your uname> at MIT-xx HH:MMxm]", followed by <message>, on his TTY, and puts it at the head of the file .TEMP.;<user> SENDS . Otherwise, types "(Mail) " as soon as you have typed the space after <user>, and then runs the MAIL program to send mail to <user>. (See .INFO.;QMAIL ORDER for info on the MAIL program.) If the :SEND was able to determine the XUNAME of the user you specified, the MAIL is addressed to that XUNAME. Otherwise, it is addressed to the name you specified. The form :SEND <user>@<site> <message>^C where <site> is one of "AI", "ML", "MC", or "DM", will send to the user on that site. While in :SEND, several control characters have special editing meanings: ^W means word kill, ^U = line kill, and ^Y means to unkill. ^Z exits, saving in the kill ring (so that a subsequent ^Y will yank back the saved text). ^R retypes the current line, ^K retypes entire message, ^L clears and retypes entire message. ^_H or [HELP] will give help. If the flag ..SNDFLG is non-zero, this command is disabled, and the program SEND is run instead (SYS2;TS SEND is a link to QSEND). It may still be accessed as :OSEND in this case. :SFAUTHOR <file>,<name> sets <file>'s author's name to <name>, which should be the name of some directory in the system. :SFDATE <file>,<date> sets <file>'s creation date to <date>. <date> should have the same format as dates in dsk directories as typed by ^F; trailing numbers default to 0 if omitted, except for the year, which defaults to the current year. If the date is null, the current date and time are used. :SFDATE uses the same defaults for <file> as :DELETE. :SFDUMP <file>,<0 or 1> sets <file>'s has-been-dumped bit to <0 or 1>. The dumped bit is supposed to mean that the file has been copied onto magnetic tape by the backup system (DUMP). It causes incremental dumps not to copy the file again. "!" in directory listings marks files which "have not been dumped". :SFREAP <file>,<0 or 1> sets <file>'s inhibit-reap bit to <0 or 1>. The DUMP program's automatic GFR will not delete files which have this bit set to 1. :SHOUT <message>^C sends the specified message to all logged-in users who can receive it. Does not send or mail the message to users who are not logged in or are gagged. Also does not send or mail to the shouting user himself. As each user is sent the message, his name is typed out on the terminal of the DDT which is shouting. The actual message sent is <sender's uname> <time> Everybody: <message> but the automatically supplied parts can be rubbed out. :SL <file> Symbol Load - like $L but loads only the symbols, flushing any that are already defined in the current job. :SLEEP <n> sleeps <n>/30. seconds. :SLIST same as :LISTS - List this job's symbols. :SMDATE <date> sets that date. It takes a date in the same format as :SFDATE and friends. (:SMDATE 10/15/78 16:40:25). Notable special cases are :SMDATE 0, which sets it to NOW, and :SMDATE - which sets it to print all of them. :SNARF <job> if the current job (say, FOO) has an inferior named <job>, this command takes <job> away from FOO and then does ":JOB <job> ". Thus, <job> becomes a direct inferior of the DDT executing this command, instead of an indirect inferior. FOO is not told that its inferior is gone, but if it is a DDT it will recover after an $J is done to it. This command is most useful when done to a HACTRO that got detached because of a top- level interrupt, but whose inferiors are valuable. (The thing to do is "HACTRO$J :SNARF TECO ", etc.) :SSTATUS prints system status info, as is done when DDT starts up. On MC, prints the number of MACSYMA's being run. :START <addr> Same as :GO - Start current job at specified address. :SYMADD <file> loads the symbols from <file>, without killing the symbols the current job already has. :SYMLOD <file> Like $L but loads only the symbols, flushing any that are already defined in the current job. Same as :SL :SYMTYPE <sym> returns info on <sym>'s status. Useful in conditionals, since it is 0 iff the symbol is undefined. The character terminating <sym> is re-read. The bits in :SYMTYP's value: 4.9 - sym is half-killed. 4.8 - sym is predefined in DDT. 4.7 - sym defined but not in current block. 4.6 - sym is a DDT-reference (like ..TTYFLG or ..BTAD). 4.5 - sym is a .USET reference (like .SNAME). the RH has the sym tab entry's addr in DDT (but is 0 for PDP-10 instructions, which have none). :TAG <tag> is a label in an execute file or valret string, which a :JUMP can jump to. :TAG is a no-op if executed; its only purpose is to be recognized by a :JUMP. :TERPRI will print a CRLF iff the cursor is not already at the left margin. It will do this even with the TTY off, so it can be done in init files without needing a "^V ^W" to turn it on which would cause it to echo a space and thereby always forcing a CRLF. :TPL <file> causes <file> to be printed on the LPT: eventually. If <file> is on DSK:, makes a link from the TPL: device to <file> . <file> must exist when the attempt is made to print it; if it doesn't exist when the command is given it is an error (the names in <file> are translated as if it were being opened and the translated names are actually used). If <file> is not on DSK:, it is copied to the TPL:. On MC, device TPL just sends files to ML's TPL; it can't hold links. :TPL on MC will always copy the file. :TPLN <file> like :TPL but no error if the file doesn't exist. If it still doesn't exist when the time comes to print it, it will be printed as soon as it is created. :UINIT zeroes the directory of the microtape that is ^F default device. Error if that device isn't a microtape. :UINIT is allowed only after :ASSIGN'ing the tape. :UINIT <tape> similar but uses the specified microtape. Sets defaults as ^F does. :UJOB <uname> <jname> opens the job <uname> <jname>, which presumably belongs to <uname>'s tree instead of your own. The job can be examined only, unless it is reowned when you select it. :UNPURE <addr> unpurifies the page of the current job in which <addr> lies (thus, ":UNPURE 2000 " unpurifies page 1). :UNPURE<cr> unpurifies all shared and read-only pages of the current job, except absolute pages. See the symbol "..UNPURE" for the automatic unpurification feature. :V if read from the TTY, turns on TTY output by zeroing ..TTYFLG. In a valret or file, cancels one ^W, just as a ^V does. :VERSION prints the version numbers of ITS and DDT. Also says which machine you're on, and your TTY number. If logged in, DDT prints its UNAME and JNAME on the next line. This command is executed automatically when DDT starts up. :VK turns on typeout like :V and types a CRLF and a * (V-Kerchink). :VP turns on typeout and proceeds inferior without actually typing anything. Like $P^V . :WALBEGIN <file> opens a wallpaper file. If successful, turns on output to it. The default file names are LPT:WALL PAPER <msname>; see ^B and ..LPTFLG :WALEND closes the wallpaper file if any. Doesn't change ..LPTFLG but its contents become irrelevant. :WALLP <file> opens a wallpaper file. Same as :WALLBEGIN :XFILE <file> executes <file> as DDT commands, after which input will revert to its current source. The current input source is pushed as by :INPUSH and input comes from the file; at eof input will pop back into the source the :XFILE was read from. However, if :XFILE is the last command in an execute file, it will be able to loop without input pdl overflow (the CRLF ending the :XFILE must be absolutely the last thing in the file!). � Reading of filenames: Some commands take filename arguments. These arguments always follow the command itself. Such commands must always be terminated by a carriage-return. An ITS filename has four components: the device name, the sname (or user name), and two filenames, called the FN1 and the FN2 (Yes, "filename" is ambiguous). The device name and sname constitute the directory, and the two filenames specify the file in it. A filespec can specify any or all of the components. Those that are not specified will be given default values, which will usually be whatever values were used for those components in a previous command (see Defaulting of filenames, on the next page). A filespec as understood by DDT is composed of names terminated by delimiters. A name is composed of any SIXBIT characters which are not delimiters, except that delimiters which are SIXBIT characters may be forced into names by preceding them by ^Q. The significance of a name depends on what the terminating delimiter is. If a name is terminated by a colon, it specifies the device name. A name ended by a semicolon specifies the sname. In addition, it forces the default device name to be DSK:, if the default device was one which does not use the sname (such as PTR:). Names terminated by anything other than colon or semicolon are "normal". The first normal name specifies the FN1. The second specifies the FN2. If there are more normal names, the third becomes the device name and the fourth becomes the sname. Further normal names are ignored. A normal name is usually separated from what follows by a space, but a space is not needed before these special effect characters: ^X like typing the default FN1 between spaces. (treats the preceding name if any normally, then treats the default FN1 normally) Thus, if the defaults are FOO BIN, typing TS^X or TS ^X will specify TS FOO. ^XNBIN or ^X NBIN will specify FOO NBIN. ^Y similar but uses the default FN2. It is never necessary to use ^Y explicitly as the FN2, because simply not specifying any FN2 has the same effect. , (comma) ends the file specification. It does not terminate the command, however; only a ^M will do that. Useful in commands that read a file specification and then read something else. $ (altmode) Causes the filenames specified or defaulted thus far to be typed out on a new line, followed by a tab, then reads another file specification using the typed-out names as the defaults. ^M (carriage-return) terminates the file specification and also terminates rubout-processing. Unless the command wants to read more arguments, it will immediately execute. � Defaulting of filenames: When a filename is read in, defaults are provided for any component of the filename that is not specified. Usually, the names that are specified change the default for the next command of the same class (filenames are "sticky"). The commands are divided into classes as follows: 1) Loading and dumping commands $L, $$L, $Y, $$Y, :LOAD, :PDUMP, :SL, :SYMADD, etc. These commands all remember and update the same filename; however each job has its own. When a job is created, that default is set to DSK: <msname>; <jname> BIN . When a job is loaded into by <prgm>^K or :<prgm>, etc., the default is set to the name of the file loaded. Each command in this class updates the default for the job that it loads or dumps to the file that was loaded or dumped. (that is, the next such command in the same job will use the same filenames unless the names are explicitly re-specified). The commands that run system programs (^K, :, :NEW, etc.) set the $L-default filename of the loaded job to the filename of the loaded program. If that program was actually found on SYS;, SYS1;, SYS2;, or SYS3;, a special feature is invoked to prevent accidental overwriting of system programs: although the default is cheerfully set to SYS; or whatever, the first dumping command given will change it to <msname>;. This causes the dumped file to be written on the user's own directory instead of on top of the loaded system program. Of course, if an sname is specified in the dumping command it overrides the change in the default. Also, this feature is activated only by the program-running commands; if SYS; becomes the default via an explicit specification (eg, $L SYS;) DDT will not spontaneously change it. 2) ^O, :DELETE, $$^O, :RENAME, :LINK, :LINKF, :LINKN, :SFDATE, :PRINT, :COPY, :MOVE, :EXISTS, :TPL, :LISTF, ^F. These commands all use and update the same default filenames. There is, however, only one default for these commands rather than one for each job. Logging in sets the default to DSK:<hsname>;.FOO. > ^F is slightly special in that TTY^F, XGP^F and <arg>$^F do not set the default for any of the other commands, but do set it for successive ^F's without argument. 3) ^T, $^T, $$^T, ^U, $^U, $$^U. Defaults for these commands are not sticky between commands. The first file's defaults are always *:*;* *. With those commands that read two filenames (^T, $^T, $$^T) the second defaults to the first. 4) :XFILE remembers and updates its own special default, which starts out as DSK:<hsname>;<xuname> LOGIN. :WALBEG has another default that is initially DSK:<msname>;WALL PAPER. Setting the msname ($$^S) sets the default sname for :XFILE, :WALLP, :DELETE, etc., but not for $L, etc. � DDT's UNAMEs and SNAMEs: DDT remembers several different "user names", each one with its own significance. They are, in order of decreasing significance and increasing frequency of alteration, the RUNAME, the XUNAME, the HSNAME, the MSNAME. 1) The RUNAME The RUNAME is DDT's best idea of what its .UNAME user variable is (in other words, it represents the fruits of DDT's attempts to keep track of what the system thinks DDT's UNAME is). DDT uses the RUNAME as the FN1 of the "SENDS" file to put messages from other users in (see "Unsolicited typeouts"), and also as the UNAME that inferiors must be created with. It is unreasonable to change the RUNAME explicitly. DDT tries hard to detect any change in its .UNAME and update the RUNAME as necessary (see "When DDT determines the RUNAME"). 2) The XUNAME This is "who you really are", as opposed to "what you are logged in as". It is not infrequent for them to be different. The XUNAME lives in the DDT variable ..XUNAME, and in DDT's .SUSET variable .XUNAME; they are both set by logging in, and by depositing in ..XUNAME. When you log in, the XUNAME is normally set to the name you specify, even if you end up logged in under another name (for example, if you say FOO$U and end up as FOO0 because FOO already existed, your XUNAME will still be FOO). However, if you try to log in as "FOO1", and FOO1 has no directory, DDT init file, or _MSGS_ file while FOO does, the XUNAME will be FOO instead of FOO1. DDT uses the XUNAME as the name of the default mail file for :PRMAIL, and as the name of the _MSGS_ file for :MSGS. so, after "FOO1$U", you would see FOO's mail and messages. DDT also uses the XUNAME to decide whose init file to use. If you would like to have different initialization performed depending on whether you log in as "FOO" or "FOO1", you can put conditionals in the init file as follows: :DDTSYM RUNAME/ :IF E $Q-$1'FOO$ $( <commands executed only if you log in as FOO> $) a similar conditional can then specify commands to be executed only if not logged in as FOO - just use "N" instead of "E". Each inferior job also has a .XUNAME variable. When the job is created, DDT will set its .XUNAME from DDT's XUNAME. After that, DDT will never touch it, but the user can alter it at will by depositing in .XUNAME. In addition, the DDT command $^S can be used to cause the next job created to be given a different .XUNAME. Programs that read init files should use the .XUNAME to decide where to look for one. They should read their own .XUNAME variables, rather than trying to read DDT's .XUNAME, so that the user will be able to fake them out with $^S, etc. 3) The HSNAME The HSNAME is your "Home SNAME". It is the same as your normal working directory or MSNAME. However, while you might reasonably select a different working directory temporarily with :CWD or $$^S, you hardly ever want to change your home directory. The home directory is in location ..HSNAME in DDT, and also in the .HSNAME ITS variable of DDT, and copied into the .HSNAME variable of every inferior. However, most programs should use the working directory (which they will find in .SNAME when they are started) rather than the home directory, which is to be used only for things like your RMAIL file which belong to YOU rather than to whatever you are hacking at the moment. 4) The MSNAME "MSNAME" is short for "Master SNAME". It is DDT's super-default SNAME. Whenever an inferior is created or reloaded, its .SNAME variable is initted from the MSNAME. Also, when DDT is about to load a program into a newly created job (one not loaded before), the MSNAME is the first directory DDT looks on for the file (see $L, ^K, :). The MSNAME and HSNAME are set just like the XUNAME at login time. The default init file (which is used if you fdon't have either a directory or an init file of your own) will then run the SETMSN program, which will set the MSNAME and the HSNAME according to your INQUIR entry. The MSNAME may be set explicitly by <name>$$^S, or by depositing in ..MSNAME. Using $$^S or :CWD causes several other default SNAMEs to be set. XUNAME: "Who you are". This is what you normally log in as. However, if you log in more than once, the second time you'll be logged in as a slightly different name, but your XUNAME will still be the same. For example, FOO logs in twice, the second time he becomes FOO0, but his XUNAME is FOO in both instances. HSNAME: A decoding of the XUNAME into a directory. The directory on which a user's mail and init files go. This is a permanent parameter of a given user. (You don't move your mail file from day to day.) There is no command to change this, it must be done through INQUIR. There is, however, a command to use someone else's HSNAME and XUNAME for the next command. FOO^S will use FOO's XUNAME (FOO, of course) and HSNAME for the next program you run. MSNAME: "Master SNAME". This is what directory you are hacking, your "Working directory". I.e. if today you are working on a program kept on LISPM, and tomorrow on a system who's files are on your own directory, the first case you might set your MSNAME to LISPM and the second to your own directory. It's purpose is to tell programs what directory to assume when you don't specify all of a filename. It is subject to whims of convenience, and a command exists to change it: :CWD FOO (or FOO^S) set's the MSNAME to FOO. A program determines the MSNAME from it's SNAME at startup time. NOTE: Normally, one should have a null FILE DIRECTORY entry in INQUIR. It is only in unusual cases where DDT's default actions are inadaquate that they should be over-ridden by your INQUIR entry. When you log in, DDT calculates your HSNAME from your XUNAME, by looking in INQUIR. If you have an INQUIR entry, with a non-null FILE DIRECTORY entry, it parses that. It should consist of entries separated by commas, like VSDB,SIPB@MC,BLAH@MIT-ML The entries are checked one at a time. An entry with no @ or % is taken to be a directory, and if the directory exists, it is taken as the HSNAME and parsing stops. If there is no such directory, the next is tried. Similarly, in an entry with a @ or %, the part before the % or @ is taken as a directory, and the part after the @ or % is taken as the machine on which it is aplicable. The entry is ignored either if it applies to a different machine or the directory does not exist. If none of the entries in INQUIR applies, DDT then checks if there is a directory of the same name as the XUNAME. If so, that is used as the HSNAME. So people with their own directories don't need to have INQUIR entries specifying what directory to use. If none of the above applies, DDT assigns you to one of several public directories, according to your position in the alphabet, and whether or not you are a tourist (MC only). The public directories are called USERS1, USERS2, USERS3, etc. On MC there are also GUEST1 GUEST2 and GUEST3 for tourists. On other machines, no distinction is made. The mailer uses the same algorithm to find what directory to put your mail on. This is how DDT knows where to find your mail with the :PRMAIL command. init files and mail files and the like have the following naming convention: <hsname>;<xuname> <program-ID> where <program-ID> is something like MAIL, LISP, LOGIN, LOGOUT, etc. For example Old regime New Regime ---------- ---------- <random>;.LISP. (INIT) <hsname>;<xuname> LISP (INIT);<xuname> .LISP. <random>;.DDT. (INIT) <hsname>;<xuname> LOGIN (INIT);<xuname> .DDT. <random>;.DDT_ (INIT) <hsname>;<xuname> LOGOUT (INIT);<xuname> .DDT_ As you can see, the new scheme is simpler conceptually. Also, given a person's XUNAME, if you had a way of calculating the HSNAME, you'd be able to run his init files, no matter where he kept them. This was not true of the old scheme. The way to do this is with the <xuname>^S command. This command has the same meaning as it always did, that is, "for the next program you run, pretend you are <xuname>". Howver, it is smart about HSNAME's and set's the HSNAME as well as the XUNAME, so if the program follows the conventions, it will find FOO's init file if you do FOO^S LISP^K Group directories: Often people sharing a single directory wish to share a common init file. This can be done using "*" for the first file name, rather than the XUNAME. "*" means "match any XUNAME". Thus if several people, say A, B, and C, using directory DD, all want the same init file, they can call the file DD;* LISP or DDT;* LOGIN or whatever. If a person F also uses that directory, but wants a different action, he can call his init file DD;F LISP and it will be found in preference to the * LISP. * ..RHSNAME (16) --- Translate an XUNAME into an HSNAME This performs the lookup function of ^S, plus being generalized to inquire about on other ITS's The RH points to a two word block. The first is only read by DDT, not written. If it is zero, the HSNAME of the ITS on which it is running is read. If it isn't zero, it is expected to contain an ITS, and the HSNAME for that site is used. The second word should contain the XUNAME to look up, and DDT will return the HSNAME in that location. * ..RMAIL (17) --- Find a user's mail file. This performs the function of ^A. The RH points to a 3-word block of info. The first is the ITS name, the second is the XUNAME, just like ..RHSNAME. The third is used only to return a value. The value's returned are 1) ITS his mail file would be on. If an ITS was explicitly specified, it will, of course, be the same as specified. The XUNAME is clobbered to be the XUNAME mailed to. If the FOO has a BAR@MC Network Address in INQUIR, the ITS returned would be MC, and the XUNAME would be BAR. BAR's HSNAME would be returned in the third word. The third word is always the HSNAME corresponding to the XUNAME returned in the second word, regardless of whether a XUNAME translation is made because of the Network Address entry. When DDT determines the RUNAME: At various times, DDT checks its .UNAME system variable. If it is not equal to the RUNAME, DDT sets the RUNAME, and also initializes the UNAME. This happens just after logging in. Normally it will never happen again, but if the DDT is detached or disowned, and then reowned with a different UNAME, DDT will eventually find out about it and redetermine its RUNAME. � Specially used symbols: Symbols whose values are variables: (It is reasonable to assemble definitions of these to direct DDT) PATCH the address of the start of the ^\ patch area. (If you use MIDAS block structure, you should define PATCH in the global block, by doing ' PATCH": ') PAT will be used to initialize PATCH if PATCH isn't defined. It is best to define both PAT and PATCH; as patches are made, PATCH will change, but PAT will not. ..D010 if this is defined, something which looks like an I/O-instruction with device code 010 will be typed out in $S mode as an I/O instruction. If it is undefined, such values will be typed out in halfword mode instead. In general, for something with device code <dev>, the symbol ..D<dev> is used. (Except that for devices APR,PI,TTY,DIS I/O-instruction format will always be used) (also, if there is no job, no symbols, or if the job is SYS, PDP6 or PDP-10, the I/O-instruction format will be used for all device codes less than 740, without searching for ..D!dev) ..U010 if this is defined, it tells DDT what to do about UUO opcode 010 -- whether it uses its AC field, whether it addresses memory, etc. This information is relevant when DDT is considering opening the memory locations referenced by a specific instruction (see ..PCPNT). ..U symbols are looked for only for opcodes less than 100 or greater than 700. The value has 3 significant bits: 1.1 this UUO refers to the addressed memory location. 1.2 this UUO refers to the specified ac, unless the AC field is 0 1.3 this UUO always refers to the specified ac. ..BFOO is one place that DDT looks for the bit pattern, when FOO$? is done. See $? for details. Special pseudo-locations (.USET variables): These symbols have values which are the "addresses" of the current job's .USET variables. Those .USET variables are not really in the job's memory, and these "addresses" are not just numbers, but it works to add numbers to them. For more accurate and detailed info on .USET variables, see .INFO.;ITS USETS. .UPC holds current job's PC. .JPC PC before most recent jump instruction. Unfortunately, proceding from a breakpoint clobbers this variable, and so does hitting a breakpoint which does not break because of its proceed count or conditional instruction. There is unfortunately no easy way to fix this. .UUOH PC at last insn that trapped to system's 40 . .SV40 last UUO that trapped to 40 . .UTRP set if system calls should trap to superior instead of normal action (DDT doesn't handle that specially) .SNAME job's default SNAME. Initted by DDT from the MSNAME. .UNAME job's UNAME. .XUNAM job's XUNAME. DDT inits it to your XUNAME (usually, but see $^S), but you can change it to fool the program if you like. .JNAME job's name. .XJNAM job's "intended" name. Tries to do the same thing for a job's JNAME that .XUNAME does for the tree's UNAME - that is, it claims to be what the JNAME would ideally have been. When a job is created by $J, the XJNAME is set up to be the same as the JNAME. If the JNAME is changed by $$J or :GENJOB, however, the XJNAME is not changed. Also, if a job named FOO0 is created by :NEW FOO, the job's .XJNAME will be FOO, not FOO0. Programs that wish to take different actions depending on the user's command should examine this variable. .UIND job's user index (printed by $$J, $$V). .SUPPRO the job's superior's user index, or -1 if job is top-level. .USTP stop bits, nonzero => job not runnable. .MASK mask for 1st-word interrupts. .IMASK when read, like .MASK . When written, IOR'ed into .MASK . .AMASK similar but ANDCAM'd into .MASK when written. .PIRQC pending 1st-word interrupts. .IPIRQ, .APIRQ analogous. .MSK2 mask for 2nd-word interrupts. .IMSK2, .AMSK2 turn on or off bits in .MSK2 .IFPIR pending 2nd-word interrupts. .IIFPI, .AIFPI analogous. .DF1 defer-bits for 1st-word interrupts. .DF2 similar, for 2nd-word interrupts. .IDF1, .ADF1, .IDF2, .ADF2 also exist. .PICLR 0 => PI in progress -1 => PI cleared. .MEMT top of user memory (1+ highest legal address). .MARA address and bits set in MAR .MARPC last PC where MAR stopped program. .BCHN # of channel most recently in error. (the one whose status you might want to look at) .MPVA address of the 1st word of the page that the most recent MPV tried to refer to. .RUNT job's runtime in 4-microsecond units. .OPTIO job's option bits. Bit 4.5 (%OPBRK bit) is set by DDT in all inferiors. The intention is that a superior should set it if it is prepared to handle all .BREAK 12's and .BREAK 16's as DDT does. Bit 4.4 (%OPDDT bit) is also set by DDT in all inferiors. No one else should set this bit. It is cleared in a job which is disowned. The system does not use these bit, or bit 4.6 (%OPCMD bit) which DDT will set iff there is a command available for the inferior. Inferiors should try to read a command from their superiors only if this bit is set. That will facilitate running them under programs which can't handle .BREAK 12, at all. .40ADDR specifies the addresses of the special core locations used by DDT and ITS The right half points to a block used by I.T.S; the left half points to a block used by DDT. The RH normally contains 40 . Whenever the system references locations "40", "41" or "42", etc., specifically (eg, giving the user interrupts, or returning UUOs 50-77), the system really references the block that .40ADDR points to. Thus, if .40ADDR is set to 500, the system expects location 502 to contain the address of the interrupt handler. ITS reserves an 8-word block, but uses only 5 words of it as of now. The words used are (assuming the block starts at the default location, 40): 40 when a UUO is returned, its value is placed here. 41 the address of the returnable UUO handler should be here. See ITS UUOS for details. 42 holds the interrupt handler address or interrupt table AOBJN pointer, if there are interrupts enabled. 43 holds the undo-list for the LOCKS feature if the feature is turned on. 44 holds the critical routine table pointer if the LOCKS feature is turned on. If the LH is nonzero, it is the address of the 20-word block used by DDT. If it is zero, the block starts at location 20 . The uses of these locations are: 25 holds "." when a user-defined typeout mode instruction is run. 26 holds a breakpoint conditional instruction being executed. 27, 30 hold .BREAK 16's for getting control back to DDT after a breakpoint conditional instruction. 31 holds an instruction being executed to proceed from a breakpoint which didn't break (count not out and condition, if any, didn't skip). 32, 33 JRSTs back to the program, or data for the instruction in 31. 34 holds an instruction being $X'd 35, 36 hold .BREAK 16's to return to DDT after the $X'd instruction. 37 holds $Q when a user-defined typeout mode instruction is run. .TTY contains several things uninteresting to examine when the job does not have the TTY, and also contains %TBINT=100000,, if set, the job will interrupt on any attempt to use the TTY when it doesn't have the TTY. DDT sets this bit in all jobs it creates, but will not object if you alter it. %TBNVR==200000,, if set, TTY opens will fail when the job doesn't have the TTY. DDT initially zeroes this bit, but you can alter it. %TBDTY==10000,, not user settable, this bit is 0 iff the job has done a .ATTY not undone by a .DTTY. .TTST, .TTS1, .TTS2 hold the saved values of the TTYSTS, TTYST1 and TTYST2 variables for the job's console, when the job doesn't own the console. .TVCREG holds the job's "console register" that determines what TV it will write on when it deposits in the TV memory, and also what logical operation is used for depositing. .CNSL contains the number of the TTY of the job's tree, whether or not the job has the TTY. Also, will be -1 for jobs "in the system tree" and -2 for disowned jobs. .IOC +<n> is contents of I/O channel <n> .IOS +<n> is contents of I/O status word for channel <n> .IOP +<n> is contents of I/O pdl word <n> .PMAP +<n> is "page-map word" <n> ; see .INFO.;ITS USETS for its format. Special per-job pseudo-locations (DDT's user variables): These symbols have values that are the "addresses" of variables in DDT's memory, pertaining to the current job. The visible numeric part of such an address is in fact the address of the variable in DDT, but there is also a hidden flag. ..UPI0 after the job interrupts DDT, this word says which fatal 1st-wd interrupts the job got to cause DDT to be interrupted. ..UPI1 holds the fatal 2nd-wd ints that the job had. when a job has interrupted DDT, either ..UPI0 or ..UPI1 must contain nonzero (something must have stopped it!). ..PPC PC to restart job at. ..XECP holds the PC saved by the last $G or $X command. $X will (presumably) eventually restore that PC. ..UIWD says why job stopped. -1 => random interrupt. 0 => running. 1 thru 8 => that breakpoint. 16 => .BREAK 16, 21 => never started. ..INCNT number of insns to 1-proceed. ..OIPC nonzero in $$^N mode, in which case PC to stop at. ..USCNT number of times to multi-step, negative => forever. ..USTYPE holds the job's stepping-flags. ..SAFE usually zero. If set nonzero by the user, the job is made "protected". Any attempt to kill or reload a protected job will cause DDT to ask for confirmation. ..BTADR 0 => no temp. bpts in this job. else RH is addr of the 1st; the second is in the next wd. If LH is from 0 to 17, it is addr of an AC whose contents should be compared with those of ..BTPDL , breaking only if they are equal. $<n>B (<n> from 1 to 8) (either altmode or dollar sign is okay) 1st word of a 4 word block describing setting of bpt <n>. zero if bpt <n> not set. else, RH as address of bpt, LH if nonzero is location to open when the breakpoint is hit. $<n>B+1 nonzero if conditional breakpoint, in which case holds conditional instruction (break if insn skips). $<n>B+2 holds proceed count for breakpoint. ..MARA holds the MAR status. after <adr>$<n>I, ..MARA contains 4+<n>,,<adr> when there is no MAR set, ..MARA holds 0. ..MARC the conditional MAR instruction. If this is nonzero, the MAR will break only if this instruction skips when executed in the job. ..MARX if nonzero, this word is considered to be the address of the first word of an ASCIZ string to be executed as DDT commands whenever the MAR is tripped. ..STARTA 0 if no starting address, else JRST to the address. ..LIMIT holds <default low search limit>,,<default high search limit> ..PERMIT -1 => job allowed to execute valret strings, kill itself, or do .BREAK 12,'s that write in DDT. 0 => DDT will stop the job before doing any of those things. $P will make DDT go ahead and do one such attempt, but still stop at the next one. ..SYSUUO if nonzero causes the job to be stopped before each system call. $P at that point will execute the system call, but the job will stop again at the next one. ..SYSUUO is the location after ..PERMIT. ..TPERCE holds the % typeout mode for this job. Initialized from ..MPERCE when the job is created. See ..TDOLLA for details. ..TAMPER holds the & typeout mode for this job. Initialized from ..MAMPER when the job is created. See ..TDOLLA. ..TDOLLA initialized from ..MDOLLA when the job is created, it holds the job's $ (dollarsign) typeout mode. It is either -1,,<addr of routine in DDT> or an insn to $X. The insn can find the value to type out in 37 (but see .40ADDR). The open location's addr will be in 25 (but see .40ADDR). If the insn is a subroutine call it shouldn't skip; otherwise it should return with .BREAK 16,504000 . ..TPRIME holds the job's ' typeout mode. Initialized from ..MPRIME. ..TDQUOT holds the job's " typeout mode. Initialized from ..MDQUOT. ..TNMSGN holds the job's # typeout mode. Initialized from ..MNMSGN. ..PATCH 0 if not patching; else <patched-from>,,<patch-area> ..LITCNT in the RH is the id number of the last literal you asked for (with $$( ). In the LH is the number of the last literal which has been defined (its contents specified). If they are not equal, then there are literals which DDT knows must be defined, and DDT will ask you to define one of them as soon as things are in a state where that is possible. ..UFNAME 4-word block holding the name of the last file loaded. 1st wd holds device, then FN1, FN2, SNAME. All 4 wds are left-justified SIXBIT. ..UFILE a 5-word block containing the default names for loading, dumping etc. ..UNDEFL an AOBJN pointer to the undefined-symbol-reference table (in DDT's address space) for this job. See "?". ..JOBSYM an AOBJN pointer to this job's symbol table. ..PRGM an AOBJN pointer to a final segment of the symbol table, starting at the header for the current block. ..URANDM is a word containing miscelaneous fields. Some of them are read and written by .BREAK 12,[..RRND,,addr] and .BREAK 12,[..SRND,,addr]. Others are internal to DDT, will be read by .BREAK as 0, and can't be set with .BREAK. When depositing with DDT, be sure not to change bits except those of the field you intend to modify. These fields are now defined for the user: bit 1.5 (20) if 1 means that unsolicited typeouts should be inhibited when this job has the tty. When the job returns to DDT, any postponed messages will be printed. bit 1.6 (40) if 1 means that other jobs, even if $$^P'd, should be prohibited from typing out while this job has the tty. They will wait instead. When this job returns to DDT, they will resume typing out. bit 1.7 (100) if 1 means not to print notification of incoming mail while in this job. This applies only to notifications generated by DDT via the :MAILNT command. Special pseudo-locations in DDT: These symbols are like those in the preceding section except that the variables they point at are not per-job. ..DDT location 0 in DDT. ..DDT+<addr> is location <addr> in DDT. $M is the address of the block of 8 words holding the 8 search masks for $N and $W. Their initial values are: -1 ? ,-1 ? -1,, ? 0 17, ? 17,, ? -1 ? -1 ? -1. See the $M command. ..CLOBRF if this flag is nonzero, the user is protected from himself. <prgm>^K typed when a job named <prgm> already exists queries "--Clobber Existing Job--". A space will tell DDT to go ahead and load a new copy of <prgm> over the old. Anything else aborts the operation. This flag is initially nonzero, but is zeroed by "<name>$U". It is not zeroed by :LOGIN, however. The assumption is that anyone who doesn't know about $U probably needs protection from himself. If the DDT is already logged in when it starts (it is an inferior, or was reloaded by $U.), ..CLOBRF is also zeroed. ..GENJFL initially -1, if set to zero ..GENJFL causes :<prgm> to behave like :RETRY <prgm> instead of :NEW <prgm>. ..MORWARN if this flag is nonzero, every unsolicited offer (such as --More--) will say "(Space=yes, Rubout=no)" so the user will know how to respond. ..MORWARN initially holds 1, but it is zeroed by $U and in inferior and reloaded DDT's. ..DELWARN this determines whether single-character file-handling commands should be verbose. If 0, they are all brief. if 1, only ^O (delete) is verbose. If 2, most are verbose. When a command is verbose, as soon as it is typed it will print out a statement of what it will do (such as "(Delete File)"), and then will pretend the user typed an altmode - it will print out the default filenames. A verbose command does not need any extra type-in as confirmation; it just types more out. If ..DELWARN is set to 3, it disables the commands :LINK, :LINKN and ^O. These commands are often mistakenly taken as a way to do a com link. The command :LINKF will work even if ..DELWARN is 3, but will print out a warning message first. The default DDT init file on some machines sets this to 3. The default setting of ..DELWARN is 1. ..CONFRM iff this is non-zero, $$^X., $^X., and $U. require the ".". If zero, they execute immediately. The default is non-zero. ..MASSCP iff this flag is non-zero, the $$^X. command is enabled, doing a :MASSACRE. If zero (the default) this is disabled. The theory is that this command is dangerous, and easily type by accident. ..LINKP If this is >0, $^O will link files, ala :LINKN If it is <0, $^O will link files ala :LINK If it is 0, $^O is an error. :DDTSYM NFVRBS This controls :NFDIR verbosity. If DDT must resort to your :NFDIR search list (SNLIST), it will normally print the name of the directory where it found the program. If you do not want such notifications, set this variable to zero. ..SNDFLG If this is non-zero, :SEND is disabled as a DDT command, and the program SEND will be run instead. This should be a link to the QSEND command. :OSEND will still get the DDT version of the SEND ..UNPUR iff this word holds nonzero, as it does initially, the automatic unpurification feature is enabled. Whenever DDT tries to deposit in the inferior and can't because the page is pure, DDT will unpurify the page and type out ":UNPURE <addr> " where <addr> is the location being deposited into. Absolute pages will not be unpurified and will still cause "PUR? " errors. ..PCPNT iff this word is nonzero, it enables the feature which, whenever DDT prints the next instruction to be executed, automatically opens the AC and memory location referenced by that instruction (but returning due to a ^Z is an exception - the locations are never opened in that case). When this feature comes into play, the locations are opened as if by slash. DDT tries to avoid opening any which the instruction doesn't actually use. The user can supply information on which UUOs use their addressed locations and their specified ACs by defining symbols starting with "..U" (see ..U010). If the instruction doesn't refer to memory but is indexed or indirect, DDT will give the effective address. ..PCPNT is initially nonzero iff the terminal is a display. ..RAID if nonzero, DDT automatically displays the raid registers whenever a job returns. If zero, raid registers are displayed only by $V commands. Initialized to zero on printing consoles, but nonzero on displays. ..RAID+1 holds the number of raid registers to allocate space for. The default is 8. Space for raid registers for a job is allocated the first time a raid register is set in that job. The space is not freed except by a :RAIDFL. increasing the value in ..RAID+1 will not give a job more raid registers if they have already been allocated, unless a :RAIDFL is done to force them to be re-allocated. ..RAID+2 if nonzero (as it is initially), causes raid registers to be displayed at the top of the screen on display consoles. Otherwise, they are just typed out in the normal stream. On printing terminals this flag has no effect. ..MSTYPE holds the new-job-default stepping flags. ..DOZTIM holds the number of seconds to wait between multi-steps and before auto-proceeding a breakpoint. The time delay overlaps the printout describing the next instruction. Its purpose is to prevent the multi-stepping from going so fast that the user can't tell when to stop it. ..DOZTIM initially contains 1. ..SENDRP tells DDT when to print various random typeouts. -1 => if DDT doesn't have the TTY, it waits till it does. 0 => if a random typeout becomes necessary and DDT has given the TTY away, it prints the message immediately, and prints it again when it gets the TTY back. Positive => like 0, but if the TTY is a display, and DDT doesn't have it, DDT repeats the messages at fixed intervals. When DDT gets the TTY back, it prints them one last time. The length of time waited is the contents of ..SENDRP times 1/60 sec. -2 ==> Type each message ONCE as it comes, and if DDT doesn't have the TTY, repeat it when DDT regains the TTY. ..SENDRP initially holds -2 :DDTSYM OMAILF if negative (as normally) causes :PRMAIL<cr> to rename the mail file as OMAIL after printing. If OMAILF is 0, :PRMAIL<cr> leaves the mail file untouched. If positive, :PRMAIL<cr> asks if you'd like to delete the file. :DDTSYM PMLFLG If 0 (the default), $^A just prints your (or some other luser's) mail file. Nonzero means $^A should act like :PRMAIL. ..BELCNT holds the number of bells for DDT to type out when it has something unsolicited to say to you. The default is 5. ..SMLINS initially zero, if nonzero it tells DDT to truncate :SEND messages. See "unsolicited typeouts" for details. ..TWAITF tells DDT how to initialize the .TTY variables of new jobs. If positive, ..TWAITF is copied into the .TTY variable (initializing the %TBINT and %TBNVR bits only). If negative, that says that the default settings - %TBINT on and %TBNVR off - should be used. Initially, ..TWAIT is negative. If a job is created with 0 in ..TWAIT, then even if you ^P the job, thus setting %TBWAT, the job will still do nothing but hang dumbly if it tries to use the TTY and doesn't have it. However, you or the program can alter .TTY in which case ..TWAIT has been overruled. See .INFO.;ITS TTY for what %TBINT, %TBNVR, %TBWAT do and why you might want to use these variables to hack them. ..TWAIT+1 is related to ..TWAIT. It is initially zero. If it is set to -1, the meanings of ^P and $^P are interchanged. ..SYMOFS gives the largest allowed numeric offset in symbolic typeout mode. Rather than print a value as <sym>+<n> with <n> larger than the maximum, it will print the value numerically. ..SCH holds the current temporary typeout mode. ..MPERCE holds the % typeout mode for use when there is no current job. Also used to initialize the ..TPERCE variables of new jobs. Initially set to -1,,..TMS when DDT is loaded. ..MAMPER similar, for & mode. Initially -1,,..TMSQ (SQUOZE mode) thus, $& will cause typeout in SQUOZE mode, unless you explicitly changed the contents of ..MAMPER before the current job (if any) was created, or changed the job's ..TAMPER variable after it was created. ..MDOLLA similar, for $ (dollar) typeout mode. Initially -1,,..TMS . ..MPRIME similar, for ' mode. Initially -1,,..TM6 (SIXBIT typeout) ..MDQUOT similar, for " mode. Initially -1,,..TMA (ASCII typeout) ..MNMSGN similar, for # mode. Initially -1,,..TMCH (single-char. ASCII) ..TMS the address of the symbolic mode typeout routin (in DDT). Put -1,,..TMS in ..TDOLLA to reset it to symbolic mode. ..TMSQ, ..TM6, ..TMA, ..TMCH are the addresses (in DDT) of the SQUOZE, SIXBIT, ASCII, and single-character ASCII routines. ..TMC, ..TMF, ..TMT, ..TMH are the addresses (in DDT) of the constant (numeric), floating point, $T, and halfword mode routines. ..TTYFLG DDT types output on the TTY if this holds zero. Incremented by 1 by ^W; decremented 1 (unless 0) by ^V, :V, :VK or :VP in valret strings or execute files; zeroed by ^V, :V, :VP, :VK when typed on the TTY, and by errors, and abnormal returns from inferiors (the same types of returns that would do a :INPUSH). ..LPTFLG DDT outputs to wallpaper file if any if this holds 0. ^E adds one to it, thus turning off output. ^B in a valret string or execute file subtracts one from it (but doesn't change it if it's 0), canceling one ^E. ^E typed on the TTY zeroes ..LPTFLG. When a wallpaper file is first opened (with :WALBEG) ..LPTFLG is zero. ..ESSYM if contents are zero, E&S display instructions will be defined on type-in. Initially 0 except on DM machine. ..MONMOD if this is nonzero, DDT is in monit mode. DDT generates (and types out) colons, causing input to be treated automatically as :-commands. To leave monit mode temporarily, just rub out one of the colons - DDT will not generate another until there is an error (such as another rubout, when there's nothing to rub). This is initialized to 0 when DDT starts up unless it is on the Dynamod machine and not logged in. ..MSNAME holds your "MSNAME", in SIXBIT. The MSNAME is used as the default $L SNAME of new jobs, as the initial sname for the new jobs themselves, as the first directory to search for programs being run by ^K or :-commands, etc. See "DDT's UNAMEs". ..DIRFN1 holds the FN1 to be given to the DIR: device by the $$^F command. Initially, it is SIXBIT/FIRST/. Another useful setting is SIXBIT/NAME1/. ..DIRFN1+1 holds the FN2 given to DIR: by $$^F. If it is zero, as it initially is, the current default FN1 is used. Thus, putting $1'CDATE$ in ..DIRFN1, and $1'DOWN$ in ..DIRFN1+1, will make $$^F give a directory sorted by creation date. ..XUNAME holds your "XUNAME", in SIXBIT. The XUNAME says who the user is, for the sake of looking at mail and messages, and for DDT init files. In addition, the XUNAME will be put in the .XUNAME variables of inferiors to tell them who is running them. For more information, see "DDT's UNAMEs". :DDTSYM TTYTYP holds the terminal's TTYTYP word. :DDTSYM TCTYP holds the terminal's TCTYP word. :DDTSYM TTYOPT holds the terminal's TTYOPT word. :DDTSYM TTYNUM holds the terminal's number. :DDTSYM GETTY is nonzero if the terminal is a display. :DDTSYM NOERASE is nonzero if the terminal is a storage tube display. :DDTSYM ERASE is non-zero if the TTY can handle ^PX :DDTSYM OSPEED the output speed of the TTY line, in baud. :DDTSYM ISPEED the input speed of the TTY line, in baud. :DDTSYM SMARTS the SMARTS TTY variable for this TTY. The above symbols are useful mainly for :IF conditionals in init files. This is the way to test for being on either a dialup line or a TELNET connection (but NOT a SUPDUP connection). A :TCTYP to the parameters of your favorite remote terminal MUST NOT be put in an init file with out such conditionals - otherwise, you will screw up any local terminals you use! :DDTSYM TTYTYP/ :IF N $Q&<%TYSTY+%TYDIL> $( :DDTSYM TCTYP/ :IF E $Q $( :TCTYP LINEL 69. etc. $)$) ..PROMPT holds the instruction which DDT uses to type out a "*". You can replace it with any other instruction. To use "%" instead of "*", deposit $1#%$> in that location ($> to avoid clobbering the opcode without having to know what it is). :DDTSYM PRMMCH if nonzero causes DDT to type the machine name when it prompts. For example, it might say "AI*" or "ML*". People who SUPDUP a lot may find this helps them orient themselves. ..C.ZPRT initially non-zero, if it is non-zero it prints out the instruction being executed. If zero, it XCT's ..RPRMPT instead ..RPRMPT holds the instruction to XCT when DDT gets control of the TTY via a ^Z, if ..C.ZPRT is zero. ..DDT+<any .uset-variable> holds DDT's variable of that name (just opening the .USET variable would give the current job's value) � Unsolicited typeouts: Unsolicited typeouts are those that occur because of asynchronous conditions detected by DDT, rather than as the response to a user command. They can occur at any time - even if you are in a COM link; even if DDT has given the TTY to an inferior! In that case, on display TTYs, the messages will be repeated every minute until you return to DDT, and then once more immediately. This is to prevent display hacking programs from wiping out the messages by clearing the screen, etc. On printing TTYs, the messages won't be retyped. Those actions are the default. Deposit in ..SENDRP to change them. 1) Job <jname> interrupted: <interrupts> means that an inferior that does not have the TTY has had a fatal interrupt (which may mean a .BREAK 16, or simply that the job attempted to use the TTY which it didn't have) and has interrupted DDT. Since it can't really return to DDT without the TTY, DDT informs you of its desire to return so you can give it the chance if you wish (just type $J at DDT). The job that interrupted is now in a "waiting" state, and will show up with a "W" if $$V is done. $J without argument, or $P, ^P or ^X with that job selected, will make it "return to DDT". Then it will be "stopped" instead of "waiting". 2) :Forgotten job <jname> interrupting means that the job named <jname>, which is DDT's inferior but which you did a :FORGET command on, is trying to return to DDT. It can't do so unless you do :JOB <jname> to make DDT "remember" it again. 3) Job <jname> wants the TTY means that the job tried to use the TTY and couldn't. The job might be waiting for input or for a chance to type out. In either case, $P will start it up again. Just as in case 1), the job is "waiting", and $J, or ^X, will make it return. It will say it got a "DTTY" interrupt, which is true. At this point it will be "stopped", so $P, etc. will work. This case is actually a special case of 1), except that $P has been made more convenient and the message is different. 4) Job <jname> finished means that the job did a .BREAK 16,160000, and is now gone unless it had been the current job, and ^P'd, in which case $P will tell it to die and ^X will stop it. 5) MESSAGE FROM <sender's-uname> <jname> <text (possibly several lines)> This means that someone has done a :SEND to you. The texts of all the messages sent to you are saved in .TEMP.;<your-runame> SENDS, but only until you log out. If the text of the message begins with rubout, the "Message from <uname> <jname>" which DDT normally supplies will be suppressed. DDT uses this to give the "[Message from..." line that heads messages sent with :SEND. If ..SMLINS is nonzero, then under certain conditions (a display terminal not in COM mode) DDT will stop printing a :SEND after that many lines (however many ..SMLINS says), and either say --More-- or say how many lines are left. The whole message always goes in the sends file. This feature needs changes to become a real winner. 6) <machine name> ITS going down in <rel time> means that ITS will stop running in <rel time> from now. When that happens, everyone will be logged off automatically. 7) <machine name> ITS revived means that ITS won't go down after all (we hope). This happens when a request for ITS to go down is cancelled. 8) ITS being debugged! means that ITS is in danger of crashing at any moment. 8a) ITS No longer being debugged! means that 8) above no longer applies. 9) Alarm, type ":ALARM<cr>" to clear means that the time mentioned in the last :ALARM command has arrived. This message will repeat every minute, (or however often ..SENDRP requires) regardless of whether an inferior has the TTY, until you give the command mentioned, which clears the alarm. � Unsolicited offers: At times DDT will think that you might want some service (such as printing of mail), or will wonder whether you really want to execute a command which will have drastic effects that it doesn't usually have (such as starting a new copy of a program when you already have one). In those cases, DDT offers to go ahead, and allows the user to say no or abort. DDT prints a message, which will usually start and end with "--", and then reads a character. Space tells DDT to perform the optional service or go ahead with the command. Rubout tells DDT not to perform the service, or to abort the command. Anything else acts as if it were preceded by a rubout, on the theory that explicit orders should override DDT's attempts to guess. Anything but space causes a message (usually "Flushed") to be printed indicating that the offered service was not performed. For the sake of the naive, if ..MORWARN is nonzero DDT will print "(Space=yes, CR=no)" after every offer. The offers that can be made now are: --More-- when a typeout reaches the bottom of the screen, DDT offers to print more. If flushed, not only the printing but the execution of the command will be aborted. This feature is disabled by :TCTYP NOMORE. --Msgs-- when you log in or do :INTEST or :MSGS, and there are new system messages you have not seen, DDT offers to print one. This offer is unusual in that rubout acts like a space and tells DDT to go ahead; all other characters still tell DDT not to go ahead, but they say "Postponed" instead of "Flushed" since DDT will offer again later. --Mail-- when you log in or do :INTEST, if you have mail DDT offers to print it. If flushed, it says "Postponed" instead of "Flushed". Rubout flushes, as usual, unlike --Msgs--. --Attach Your Detached Tree-- when you log in, if you have a detached tree that appears alive enough to be attached to successfully, DDT offers to do so. If you flush this, it goes about logging in in the normal way, and runs your init file, etc. The detached job is left detached, and DDT says so. If there is a detached tree that is to dead to attach, DDT will inform you but not offer to attach it. You have several attachable detached trees. --Attach A Detached Tree-- is like --Attach Your Detached Tree-- but indicates that you have more than one, and after attaching one the others will still remain, still detached. --Init-- DDT is offering to run your init file, because either DDT was already logged in when started, or your XUNAME doesn't equal your RUNAME. In either case, a space will tell DDT to run your init file, while anything else will tell it to do nothing. These offers are essentially requests for confirmation of a command that would make DDT do something drastic. --Kill Protected Job-- a command has been given which would kill a protected job (one whose ..SAFE variable is nonzero). DDT will go ahead if a space is typed; otherwise, it will err out. --Reload Protected Job-- a command has been given which would destroy the contents of a protected job (eg, $L). --Despite Pending :Alarm-- you tried to log out while a :alarm was pending. This is just to keep you from forgetting whatever the alarm was to remind you of. --No Symbols. Dump Anyway-- you loaded a program without symbols (perhaps with ^K) or killed the symbols, and tried to dump it back out in the same file. If you go ahead, the symbols for the program will be lost, along with the old file you loaded. --Undefined Symbols-- you tried to start a job (with $G) which contained references to symbols yet to be defined (created using the ? command). Presumably, the existence of such symbol references means that you started but did not finish making some patch. The following confirmation-type offers are made only if ..CLOBRF is nonzero. If it is zero, DDT goes ahead without asking. --Kill Running Inferiors-- you attempted to log out or :CHUNAM while some of your inferiors were running. Space causes the command to go ahead, while flushing aborts it (you might :DISOWN the job, or finish using it, and then log out again). --Clobber Existing Job-- you tried to run a program with ^K, and there was already a job with the same name as that program. Running the program would require clobbering that job's contents. --Create Additional Job-- you tried to run a program with :, when you already had a job with that name. Running the program would involve creating a new job. --Reload Running Job-- you tried to $L a running job. � Returning to DDT: When a job gets a class 1 or disabled class 2 interrupt, DDT is interrupted. If the interrupt was due to a breakpoint or MAR, DDT will use the conditional instruction, if any, and the breakpoint proceed count, to decide whether the job should really be stopped. Any other sort of interrupt always causes DDT to decide the job must be stopped. If the job had the TTY it "returns to DDT" immediately. Otherwise it is waiting ($$V will type "W") and will return to DDT when $J with no argument is given, or an $J specifically to that job, or an $P in the job. Returning to DDT involves the following actions: Breakpoints are removed from the job. If the job stopped with a .BREAK 16, requesting death, it will die, saying ":KILL ". Otherwise something may be printed out, depending on what stopped the job. The possibilities are: 1) ^Z (and nothing else) 2) a ^_D or Control-CALL 3) a breakpoint 4) a .VALUE with nonzero address 5) the job tried to use the TTY and didn't have it. 6) any other interrupts. DDT's reactions are (case by case): 1) type <pc>) <next insn>. In this case only, the AC and memory location of the instruction are not opened, regardless of ..PCPNT, since the user is probably not debugging. 2) Type an asterisk. 3) complicated; see below under "breakpoints". 4) if the job is returning immediately (because it had the TTY when it executed the .VALUE), or because of an $P, execute the ASCIZ string pointed to by the .VALUE as DDT commands (this is what .VALUE is for. See "instructions that return to or call DDT"). If the job is returning because of an $J with argument, treat this like case 5). 5) this is impossible if the job is returning immediately. If it is returning because of an $P, give the job the TTY and proceed it. If the job is returning after being $J'd to, treat this like case 5). 6) print the next insn, and the names of the interrupts: <fatal ints> <pc> >> <next insn> then (if ..PCPNT is nonzero) open (as if by "/") the AC and memory location referenced by the instruction just typed. If the insn doesn't use the AC, or the memory location, they won't be mentioned. If the insn doesn't use the memory location, but it is indirect or indexed, the effective address will be typed: " E.A. _ <value>". If the instruction is a UUO, DDT looks for a symbol whose name is "..U" followed by the op-code, to tell whether the AC and memory location are used; see ..U010 for details. The interrupt names are separated by semicolons. A table listing all the interrupt names appears below. In any case, if there are pending non-fatal interrupts (which will be handled by the job, rather than by DDT), DDT prints their names in parentheses before the pc. Breakpoints: A job that hits a breakpoint won't always return to DDT. Upon encountering a bpt, the bpt's proceed count is decremented, and tested for zero. If it has reached zero, the program returns to DDT, typing $<n>B <pc> >> <insn> (and opening the AC and memory location, if appropriate). (A bpt's proceed count is stored in $<n>B+2 and is set by <count>$p after stopping at that bpt.) Otherwise, if the conditional break instruction (in $<n>B+1) is non-zero, it is executed, and if it skips, then the job returns to DDT typing $<n>B <pc> > <insn> (and opening the AC and memory location, if appropriate). Otherwise, the program is continued without typeout. When a breakpoint causes a return to DDT, if the bpt has been set to type out a specific location, (LH of $<n>B has address) that location will be opened. Then, if the breakpoint has been set to auto-proceed, an $P will be done, unless a character has been typed in (Any char. will do; it will be read normally). ..DOZTIM holds the # seconds DDT will insist must elapse from the time the bpt is hit till DDT proceeds the job. A breakpoint is represented by a .BREAK instruction, whose AC field gives the number of the breakpoint. The .BREAK is put into the job when it is started or continued, without changing the address, index or indirect fields of the broken instruction. When the job returns to DDT, for any reason, the .BREAK's are replaced by the remembered original op-codes and AC fields. The index, indirect and address fields, again, are untouched. If DDT finds itself unable to insert a .BREAK, it clears the corresponding breakpoint, typing 0$<n>B to inform you; if a breakpoint is no longer there when DDT tries to remove it (it has been replaced by other than a .BREAK) DDT says "Breakpoint <n> Clobbered". 1st word (.PIRQC) interrupt name table: (The 1st char on each line is " " for a class 3 int., "?" for a class 2 int, and "-" for a class 1 int) ("Should never be typed" means that DDT handles that interrupt specially. Eg, for the .BREAK int, DDT handles the .BREAK. As a result, you will never see ".BREAK;" mentioned). (The master list that this table reflects is in SYSENG;ITS BITS). Code Meaning Bit in ..UPI0 REALTM realtime interrupt (rqd by .REALT) 200000,, RUNTIM run time interrupt (see .RTMR) 100000,, <4/6> something set int. bit. <4.6> 40000,, <4/5> is analogous. ?^_D the job read a ^_D or control-CALL 10000,, ATTY the job was given back the TTY. ?DTTY the job tried to use the TTY and didn't 2000,, have it, when %TBINT was 1 (which is the normal case) -PARERR a parity error in the job's core 1000,, ARFOV floating overflow 400,, ?PURPG wrote in pure page 200,, ?PURINS insn fetch from impure page 100,, (this causes an int. only if a certain bit in the PC is set) -SYSUUO any trapping insn in user trapping mode 40,, SYSDBG system being debugged 2,, -.LOSE .LOSE instruction executed 1,, CLI core link interrupt 400000 PDLOV push down overflow 200000 LTPEN light pen hit on 340 100000 -MAR the MAR (set by $I) was tripped 40000 (This is special in that the instruction that tripped the MAR is printed after "MAR. " and all the remaining messages come on the next line, along with the next insn to do) ?MPV memory protection violation 20000 SCLOCK slow (60cps) clock tick 10000 -1PROC 1-proceed return (should never be typed) 4000 -.BREAK .BREAK executed (should never be typed) 2000 ?ILUAD I don't think this happens since paging 1000 ?IOC input-output channel error 400 (this is special in that it is mentioned on a line by itself, along with the system error message describing the type of error) -.VALUE .VALUE executed (should never be typed) 200 SYSDED system going down 100 ?ILOPR illegal instruction 40 ?DPY 340 or E&S display got an MPV 20 AROV arithmetic over flow 10 -BADPI bad location 42 4 (job got int. but 42 wasn't set up, eg was 0) -^Z ^Z typed on TTY (should never be typed) 2 TYPEIN any interrupt character typed on console 1 (this is obsolete - use 2nd-word ints instead) .VALUE 0. job did a .VALUE 0. 400000,, (note that that bit is not set in .PIRQC by the system but rather by DDT when it sees that the address is 0) 2nd word (.IFPIR) interrupt name table: (All these interupts are class 3. They can still be fatal if the job requests it, using the vectoring interrupt scheme) Code Meaning Bit in ..UPI1 <4.9> shouldn't be seen 400000,, <4.8> something set bit 4.8 of .IFPIR 200000,, (its won't do this itself, but a .SUSET or .USET can do it) <4.7>, <4.6>, ... <4.1>, <3.9> are similar. INF7 bit 3.8 - an interrupt from an inferior job 200,, INF6, INF5, ... INF0 interrupts from other inferiors. (.UTRAN can be used to find what inferior corresponds to a given interrupt bit. Better yet is to read the .INTBIT uset-variable of every inferior when it is created) <2.9> something set bit 2.9 of .IFPIR 400000 <2.8> something set bit 2.8 of .IFPIR 200000 IOCH17 interrupt on I/O channel 17 100000 (possible reasons depend on the device open examples: TTY input - a character was typed TTY output - bottom of screen was reached) IOCH16 interrupt on I/O channel 16 40000 IOCH15, ... IOCH0 similar 20000, ... � Symbol Table Format: Symbol Tables Inside DDT: The symbol table, in DDT, is composed of 0 or more groups of symbols. Each group has one header entry and 0 or more symbol entries, and corresponds to a single relocatable program or a single .BEGIN block (except for one, the "GLOBAL block", which is the "superior" in the hierarchy of everything else). Header Entry WD 1 Squoze name, with flags clear. WD 2 -<Length in words of the group>,,<level> (The level is 0 for the GLOBAL block, 1 for program name, 2 or more for a block name. The length includes 2 for the header itself) Symbol Entry WD 1 Squoze name & flags: 4.9 (%SYHKL) Half killed (these symbols are not! predefined) 4.8 (%SYKIL) Fully killed 4.7 (%SYLCL) Local (either this or 4.6 must be set) 4.6 (%SYGBL) Global (all global syms are in the GLOBAL block) 4.5 and down The squoze itself. WD 2 Value. Order of Groups of Symbols The last group is always the GLOBAL block. Every program name group follows the groups for the program's blocks. Every block group follows the groups of its subblocks. A relocatable block-structured program should have an outermost block whose name is the same as the program name. The program name group itself should be empty; symbols defined outside .BEGIN-.END's should go in the group associated with the program's outermost block. :LISTP prints the names of the groups' headers in the reverse of the order they have in the symbol table. The Undefined Symbol Table in DDT: Inside DDT, the "undefined symbol table" records all unsatisfied forward references to undefined symbols that were "deposited" in a job's core image. It contains one 2-word entry per symbol. The first word of each entry contains the symbol name, in squoze. The second word's RH contains the address deposited in. The sign bit of the second word is set iff the symbol was deposited in the left half. Symbol Table Formats in Files: The "symbol table" of a binary file contains the DDT symbol table and the DDT undefined symbol table, each divided at arbitrary points into "sections" which should be concatenated again when the file is read, or it contains an indirect pointer to another file whose symbol table should be used. Either one is located in the file immediately after the "start instruction" which terminates the data dumped from core (see AI:ITSDOC;BINFMT >). Each section of DDT symbol table has a word containing -<# of data words>,,0 at the beginning, followed by as many data words as specified, and a checksum. The checksum of a symbol table section is computed just like that of an SBLK (see ITSDOC;BINFMT >). Each section of DDT undefined symbol table starts with a word containing -<# of data words>,,1 (not 0!) after which come data words and a checksum. The two types of sections may be interspersed arbitrarily in the file. After the last section of either type should come a positive word, which should be a second copy of the file's start instruction. An indirect file pointer looks just like a symbol table section except that its data consists of four filenames. It starts with a word -4,,2 (2 indicates this is an indirect pointer), followed by the device, fn1, fn2 and sname (each as a word of sixbit), followed by the checksum. A file may contain only one such indirect pointer, and it must be the last block present before the duplicate start instruction which ends the file. In any file dumped by a recent DDT or assembled by a recent MIDAS, the DDT symbol table data (the concatenation of all the DDT symbol table sections) will have exactly the same format as the DDT symbol table proper, described above. Some old files may have that data in a different format. It is not necessary for any new programs to understand such formats, and certainly all new programs should write the correct format. If such an old file is encountered and causes any problem, loading it with DDT and dumping the result should produce a usable new-format file. Some old STINK-loaded files may fail to load with $L. :OLOAD should be used for them.