@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             MTL101
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YMTL101
~S~M~OMUTL IMPLEMENTATION DESCRIPTION
~S~M~OSection 10 Version 1
~S~OSection 10.1 Runtime Diagnostics - Primitives
~S~O1. General Description~
~BThis module is concerned with the provision of a set of primitives
to be used by runtime diagnostic packages.
~S~O2. Interfaces~
~
Other modules used:~
   Section 9.2:   (Diagnostics)~
   Section  24:   (Runtime Diagnostics - Machine Dependent)~
   Section  14:   (High Level Diagnostics)~
~
MUTL Procedures:~
   TL.TRAP~
   TL.INIT~
   TL.NEXT.PROC~
   TL.YIELD.PROC~
   TL.YIELD.LINE~
   TL.NEXT.VAR~
   TL.FIND.VAR~
   TL.SEL.VAR~
   TL.SEL.FLD~
   TL.SEL.EL~
   TL.SEL.ALT~
   TL.UP~
   TL.YIELD.DIMENSION~
   TL.YIELD.VAR.REF~
   TL.YIELD.VEC.REF~
   TL.SEL.DYN.VAR~
   TL.SEL.DYN.VEC~
   TL.PRINT.NAME~
   TL.PRINT.VALUE~
   TL.YIELD.NAME~
   TL.YIELD.VALUE~
   TL.SET.VALUE~
   TL.GO~
   TL.INSERT.BREAKPOINT~
   TL.REMOVE.BREAKPOINT~
   TL.TRACE~
   TL.TRACE.R~
   TL.PRINT.PROFILE~
   TL.PRINT.S.TRACE~
~
Interface Procedures:~
   INIT.10~
   VALIDATE~
   RESTORE.LINE~
~
Interface Data Structures:~
   LT~
   PV~
   CUR.PCS~
   NB~
~
Configuration Parameters:~
   PW0~
   PW1~
   SEGSHIFT~
   SEGM1~
   NAMESHIFT~
   PVSIZ~
   FLAGSHIFT~
   LAST.USER.SEG~
   VARPOS~
   TYPEPOS~
   TYPEMASK1~
   TYPEMASK2~
   FLDSIZE~
~S~O2.1 Hardware Interface
~BAny machine.~
~S~O2.2 Software Interface
~S11) TL.INIT(SEG)
~BThis procedure initialises the property segment for the
library/program running in segment SEG.
~SPROCEDURE SELECTION
~S12) TL.NEXT.PROC(STATIC)TL.ACTIVATION.NAME
~BThis selects the activation of a procedure as specified by STATIC
and sets the currency indicators CURRENT.PROC and CURRENT.ACTIVATION
accordingly. The other currency indicators are reset to undefined.
~V2 10
~SParameters:-~
~
~T# 20
~
STATIC~IA value of -1 means select the procedure that was currently active
when the fault or breakpoint occurred.
A value of 0 means the next procedure in the dynamic chain
associated with the current procedure activation is selected. A
value of 1 means the next procedure in the static chain associated
with the current procedure activation is selected.~
~
TL.ACTIVATION.NAME~IAn RD name containing dynamic information of the
newly selected current procedure activation.~
~V2 0
~BA result of -1 means the end of the static or dynamic
procedure chain has been reached.
~BThe trap procedure makes a call to this procedure with a value
of -1 for STATIC, initialising the MURD system to the procedure/block
in which the program failed.
~S13) TL.YIELD.PROC()TL.PROC.NAME
~BThis procedure supplies the RD name containing the static information
of the current procedure activation.
~BA result of -1 indicates the diagnostic information
of the procedure is not available.
~S4) TL.YIELD.LINE()PAGE.LINE
~BThis procedure yields the page and line of the point within the
currently selected procedure activation that control was last at.
~SVARIABLE IDENTIFICATION~
~S5) TL.NEXT.VAR(TL.VAR.NAME)TL.VAR.NAME
~BThis supplies the RD name of a variable.
~V2 10
~SParameters:-~
~
TL.VAR.NAME~IA value of -1 means supply the name of
the first variable of the currently
selected procedure, otherwise supply
the name of the variable following the
one specified by the parameter.~
~
TL.VAR.NAME~IA result of -1 means that there are no
more variables.~
~V2 0
~S6) TL.FIND.VAR([SYMB.NAME])TL.VAR.NAME
~BThis finds the requested variable and supplies its RD name. Only
variables within the CURRENT.PROC are searched.
~V2 10
~SParameters:-~
~
[SYMB.NAME]~IBounded pointer to character vector
containing symbolic name in characters.~
~
TL.VAR.NAME~IA result of -1 means variable not found.~
~V2 0
~SVARIABLE AND COMPONENT SELECTION
~S7) TL.SEL.VAR(TL.VAR.NAME)TL.TYPE.NAME
~BThis selects the variable as specified by TL.VAR.NAME as the
CURRENT.COMPONENT.
The result indicates the type of the variable. Only variables
within the CURRENT.PROC may be selected.~
~
~BOnce a variable is selected the procedures TL.SEL.FLD, TL.SEL.EL
and TL.SEL.ALT are called to manipulate the position of the
CURRENT.COMPONENT, within the variables data structure and these
procedures yield type and positional information about the CURRENT.COMPONENT.
The TL.SEL procedures may be used to step through the basic components
of a variables data structure, or alternatively select only components
of interest.
~SParameters:-~
~T# 14
~V2 10
~
TL.VAR.NAME~IName of a variable.~
~
TL.TYPE.NAME~IType information is encoded as follows.~
~
Bits   0, 1~
       0  -~IScalar~
       1  -~IPointer to a scalar instance of a type~
       3  -~IBounded pointer to a vector instance of a type~
~
Bit 14  0 -~IBits 2-13 contain a MUTL basic type, the encoding
is described in 23.3 of the MUSS manual.~
        1 -~IBits 2-13 contain a pointer to an aggregate type entry
in the property vector.~
Bit 15  0 -~Iscalar~
        1 -~Ivector~
~V2 0
~S8) TL.SEL.FLD(NO) TL.TYPE.NAME
~BWhen the parameter is non-negative the Nth field, counting from zero,
~Wwithin the current component is selected as the CURRENT.COMPONENT.
The newly selected component is thus one level lower than the previous
selected component in the variables data structure. For a negative
value of N, the [0-N]th field ~Wfollowing the CURRENT.COMPONENT
becomes the new CURRENT.COMPONENT. In this case the new and previous
CURRENT.COMPONENT are at the same level within the variables data
structure.
~BA result of -1 indicates that the component requested does not exist,
but when further alternatives follow at the same level as the component
search a result of -2 is yielded. For unsuccessful selection the
CURRENT.COMPONENT remains unchanged. A positive result indicates
successful component selection and supplies type information.
~SParameters:-~
~
N~
~
TL.TYPE.NAME    Type information as in 7).~
~S9) TL.SEL.EL(N) TL.TYPE.NAME
~BWhen the CURRENT.COMPONENT is a vector a non-negative value of N selects
the Nth element, counting from zero, of the vector as the new
CURRENT.COMPONENT. When the CURRENT.COMPONENT is an element of a
vector a negative value of N selects the [0-N]th following element
as the CURRENT.COMPONENT. Thus in the first case the new CURRENT.COMPONENT
is one level deeper in variables data structure than the previous
CURRENT.COMPONENT, where as in the latter both are at the same level.
~BA result of -1 means the element does not exist, and the CURRENT.COMPONENT
remains unaltered. For successful element selection the result yields type
information.
~SParameters:-~
~
N~
~
TL.TYPE.NAME    Type information as in 7).~
~S110) TL.SEL.ALT(N)TL.TYPE.NAME
~BWhen N is non-negative the first field of the Nth alternative,
counting from zero, ~Wwithin the CURRENT.COMPONENT is selected
as the new CURRENT.COMPONENT. For a negative value of N, the
first field of the [0-N] alternative ~Wfollowing the CURRENT.COMPONENT
becomes the new CURRENT.COMPONENT. Note once again that for a
non-negative N the new CURRENT.COMPONENT is one level deeper, and for a
negative N the level within the variables data structure is the same.
~BA result of -1 means the alternative does not exist in which case
the CURRENT.COMPONENT is unaltered. For successful selection
the result yields the type information of the CURRENT.COMPONENT.
~SParameters:-~
~
N~
~
TL.TYPE.NAME    Type information as in 7).~
~S111) TL.UP()
~BThis procedure reselects the component at one level higher in the
variables data structure that contains the CURRENT.COMPONENT as the
new CURRENT.COMPONENT.~
~S112) TL.YIELD.DIMENSION()DIMENSION
~BWhen the CURRENT.COMPONENT is a vector or element, this
procedure yields the number of elements in the vector.~
~S113) TL.YIELD.VAR.REF()VAR.REF
~BWhen the CURRENT COMPONENT contains a pointer to a
scalar instance of a data structure, this procedure yields
the value of the pointer as a result. Thus dynamic
selection of data structures is possible.~
~S114) TL.YIELD.VEC.REF()VEC.REF
~BSimilar to TL.YIELD.VAR.REF except that CURRENT.COMPONENT
contains a bounded pointer to a vector. The result is
a bounded pointer.~
~S115) TL.SEL.DYN.VAR(VAR.REF,TL.TYPE.NAME)
~S116) TL.SEL.DYN.VEC(VEC.REF,TL.TYPE.NAME)
~BThese procedures select the typed data item as specified by the
parameters as the CURRENT.COMPONENT.~
~SParameters:-~
~3
~
VAR.REF        As yielded by TL.YIELD.VAR.REF~
VEC.REF        As yielded by TL.YIELD.VEC.REF~
TL.TYPE.NAME   RD type name of pointer.~
~0
~SPRINTING~
~S117) TL.PRINT.NAME(TL.NAME)PRINT.WIDTH
~BOutputs the symbolic name associated with the
TL.NAME of a procedure, variable, or the field name of the current component.
~SParameters:-~
~3
~
TL.NAME       RD name of a procedure or variable.~
              0 means print name of CURRENT.COMPONENT.~
PRINT.WIDTH   Number of characters output.~
~0
~S118) TL.PRINT.VALUE()PRINT.WIDTH
~BOutputs a value of the CURRENT.COMPONENT in a suitable
format as dictated by its type.
~SParameters:-~
~3
~
PRINT.WIDTH   Number of characters output.~
~0
~S119) TL.YIELD.NAME(TL.NAME)[SYMB.NAME]
~BSupplies a bounded pointer to a vector
containing the symbolic name of the requested
RD name.
~SParameters:-~
~3
~
TL.NAME      RD name of a procedure, variable or type.~
             0 means name of CURRENT.COMPONENT required.~
[SYMB.NAME]  Bounded pointer to a byte vector.~
~0

~SDYNAMIC DEBUGGING~
~BThese procedures allow components of a variable
to be yielded or modified.~
~S120) TL.YIELD.VALUE()
~BYields the value of a variable/component typed in.~
~S121) TL.SET.VALUE()
~BSets the value typed in into the current component.~

~SBREAKPOINT HANDLING~
~BBreakpoints may be inserted dynamically into a program and
subsequently removed. When a breakpoint is entered the dump,
variable printing and variable modification facilities may then
be continued.
~S122) TL.INSERT.BREAKPOINT()
~BInserts a breakpoint at the start of a line
number typed in, either <page>.<line> or <line> for the current page.
When the breakpoint is executed TL.TRAP is entered and a
single line printed. The user may then print or alter variables
using TL.DEBUG and use TL.GO to resume execution.~
~S123) TL.REMOVE.BREAKPOINT()
~BRemoves a breakpoint from the start of the
line typed in as either <page>.<line> or <line> of the current page.~
~S124) TL.GO(LINE.NO)
~BRestarts the program after a breakpoint.
To resume at the failed instruction a parameter of zero is sufficient.
It is possible to restart at other points in a program.
~STRACING~
~BIt is possible to trace the control flow through an
executing program at the procedure, flowchart box or line
level. It is also possible to trace all changes of designated
variables.~
~BIn most (but not necessarily all) implementations, tracing
requires recompilation of the program with trace information
specified to MUTL at compile time. When this is done the
production of trace information can be switched on and off
dynamically at run time by the following procedures.~
~S125) TL.SET.TRACE(I)
~BThe parameter controls the type and amount
of tracing information produced.
The trace options provided are as follows:~
~0
~T% 10
~
%Option 0 : print as trace proceeds~
%Option 1 : print last 100 trace elements after failure~
%Option 2 : profile of elements printed after failure
%Option 3 : trace procedure entry~
%Option 4 : trace flowchart box entry~
%Option 5 : trace every line~
~0
~
Bits 8-15 of P1 specify which trace options are to be altered and
bits 0-7 specify how they are altered. Thus if bit 8 is 1 trace option
0 is turned on if bit 0 is 1 and turned off is bit 0 is 0. Whereas if
bit 8 is 0 trace option 0 remains unaltered.
~S126) TL.TRACE.R()
~BThis procedure does the tracing as specified above.
~S127) TL.PRINT.PROFILE()
~BThis procedure prints the profiles of elements.
~S128) TL.PRINT.S.TRACE()
~BThis procedure prints out the stored traceback of elements.
~S129) INIT.10
~BThis procedure is called to initialise all data structures before
each run of the program.
~S130) VALIDATE()OK
~BThis procedure will look at the address of CUR.COMP to test
whether it is valid. The result is 0 for a valid address, otherwise
-1, accompanied by an error message for segment overflow or illegal access
~S131) FINDLINE()BP.LT.LINE
~BThis procedure reads in a line number in either of the formats
<line> or <page>.<line> from stream 0. The current page is assumed if one is
not typed in. This line is searched for in the LINE.TABLE and the
corresponding entry is returned, otherwise -1 if it is not found.
This procedure is used by the breakpoint handling routines.
~S132) RESTORE.LINE()
~BThis procedure is used after a run-time breakpoint has been executed to
replace the code originally moved out to insert the breakpoint.
~S133) SV (symbol vector)~
34) LT (linetable)~
35) PV (property vector)~
~BThese variables are bounded pointers pointing to the symbol vector,
 linetable and property vector.
~S136) CUR.PCS
~BThis is the current principle code segment of the program
containing the procedure that is currently under consideration.
~S137) NB~
~BThis is the frame pointer of the current procedure.
~S~O3. Implementation
~S~O3.1 Outline of Operation
~S11) SEARCH.LT(LINK.ADDR)LTE
~BThis procedure searches a linetable for LINK.ADDR. Provided that the
segment is located in SEG.VECTOR, the corresponding linetable is
searched for the code address. Once found, the currency indicators
CUR.LT.LINE, CUR.LT.PAGE and CUR.LT.PROC (linetable entries
corresponding to the current line, page and procedure) are reset
and CUR.LT.PROC is returned, otherwise -1.
~S12) INBSTR()[NAME]
~BThis procedure reads in an alphanumeric name from the input stream
(zero) and returns a bounded pointer to this name.
~S13) FINDFNAME([NAME])FLD
~BThis procedure searches through the field names of the aggregate
type of CUR.COMP until NAME is found. The value returned is 100 *
alternative + field, otherwise -1 if NAME is not found.
~S4) SHORTCUT()NUM
~BThis procedure searches CUR.COMP, a vector, for trailing zeros which
need not be printed out. The value returned is the number of elements
required to be printed out.
~S~O3.2 Data Structures
~S11) PROFILE.P~
2) PROFILE.L~
3) PROFILE.B~
~BThese three vectors are used by the tracing routines and hold
profiles for procedures, lines and flowchart boxes respectively.
~S4) TRACE.P~
5) TRACE.L~
6) TRACE.B~
~BThese three vectors are used by the tracing routines to hold
stored tracebacks of procedures, lines and flowchart boxes
respectively.
~S7) COMP.STACK~
8) COMP.ENTRY~
~BCOMP.STACK is the vector which holds information for each CUR.COMP
of a variable as it is selected and pushed onto the stack. It consists
of the following fields:-~
~T# 15
~3
~
  :CS.FIELD~Ifield information.~
  :CS.ADDR~Iaddress of component.~
  :CS.TYPE~Itype information.~
  :CS.CUR.EL~Icurrent element number if the previous CUR.COMP
is a vector.~
  :CS.DIM~Idimension if CUR.COMP is a vector or element of vector.~
  :CS.ELSIZE~Isize of elements in bytes if CUR.COMP is a vector.~
~0
~S 9) CUR.LT.PROC~
10) CUR.LT.PAGE~
11) CUR.LT.LINE~
~BThese variables are the currency indicators for the entries into
the linetable of the current procedure, page and line under consideration.~
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                MTL101
~V9 -1
~F
@TITLE MTL10/1(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
IMPORTS
@BOX 2.0
@BOX 3.0
@BOX 1.1
::MODULE 10 IMPORTS
@BOX 2.1
PSPEC INIT.24();
PSPEC PRINT.PROC.LINE();
PSPEC SETSTACK($IN);
PSPEC PROCTYPE()/$IN;
PSPEC GET.NEXT.LINK(ADDR,$IN)/ADDR;
PSPEC REALADDR(ADDR)/ADDR;
PSPEC TYPECONV($IN)/$IN;
PSPEC WRITE(ADDR,$LO64,$IN);
PSPEC GET.FAULT.LINK()/ADDR;
PSPEC SETNB(ADDR);
PSPEC ACCESS(ADDR,$IN)/$LO64;
PSPEC TSIZE($IN32)/$IN;
PSPEC TL.DUMP();
PSPEC TL.DEBUG();
LSPEC ENTER.TRAP($IN,$IN);
LSPEC OPEN.FILE(ADDR [$LO8],$LO64,$IN,$LO);
LSPEC LOOK.UP.LIB($IN)/ADDR[$LO8];
LSPEC CREATE.SEGMENT($IN,ADDR);
LSPEC RELEASE.SEGMENT($IN);
LSPEC READ.SEGMENT.STATUS($IN);
LSPEC CHANGE.SIZE($IN,ADDR);
LSPEC CHANGE.ACCESS($IN,$LO);
LSPEC OUTLINENO($IN32);
LSPEC READ.RECOVERY.STATUS($IN)/$IN;
LSPEC SET.RECOVERY.STATUS($IN,$IN);
LSPEC READ.TRAP($IN)/ADDR ENTER.TRAP; ::ADDR OF ANY TRAP PROC
LSPEC SET.TRAP($IN,ADDR ENTER.TRAP); ::WITH TWO $IN PARAMS
LSPEC IN.NAME()/$LO64;
LSPEC IN.BACKSPACE($IN);
LSPEC PROMPT(ADDR[$LO8]);
LSPEC PPC.CMD();
LSPEC OUT.M($IN,$IN);
LSPEC OMODE()/$IN32;
LSPEC OUT.STACK(ADDR,ADDR);
LSPEC OUT.I($IN32,$IN);
LSPEC INREAL()/$RE64;
LSPEC IN.HEX()/$LO64;
LSPEC OUTHEX($LO32,$IN);
LSPEC OUTNAME($LO64);
LSPEC INI()/ADDR;
LSPEC IN.CH()/$IN;
LSPEC NEXT.CH()/$IN;
LSPEC OUT.CH($IN);
LSPEC SPACES($IN);
LSPEC CAPTION(ADDR[$LO8]);
LSPEC NEWLINES($IN);
LSPEC OUTREAL($RE64,$IN,$IN);
LSPEC CURRENT.INPUT()/$IN;
LSPEC CURRENT.OUTPUT()/$IN;
LSPEC SELECT.OUTPUT($IN);
LSPEC SELECT.INPUT($IN);
LSPEC STOP($IN);
@BOX 3.1
TYPE BPT.ENTRY IS $LO32 CA $LO8 CODE $IN CUR,MAX;
BPT.ENTRY [10] BPT;
TYPE FENTRY IS $LO16 FFLAG,FDISP,FTYPE,FDIM;
ADDR PW0,PW1,PW2;
$LO64 PWW1,PWW2;
IMPORT LITERAL SEGSHIFT,SEGM1,NAMESHIFT,PVSIZ,
VARPOS,FLAGSHIFT,LAST.USER.SEG,TYPEPOS,FLDSIZE,TYPEMASK1,TYPEMASK2,
FILED.PROP.SEG,PROG.PROP.SEG,MURD.WORK.SEG,SHIFT.MCADDR.TO.BYTE;
@END

@TITLE MTL10(1,7)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
MODULE 10
EXPORTS
@BOX 2.0
@BOX 3.0
@BOX 1.1
#MTL10/1
MODULE(NEXTADD,CUR.PCS,TL.RESET.TRAPS,TL.SET.TRAPS,
TL.TRAP,TL.INIT,VALIDATE,INIT.10,TL.INSERT.BREAKPOINT,TL.REMOVE.BREAKPOINT,
TL.NEXT.PROC,TL.YIELD.PROC,TL.YIELD.LINE,
TL.NEXT.VAR,TL.FIND.VAR,TL.SEL.VAR,TL.SEL.FLD,TL.SEL.EL,TL.SEL.ALT,
TL.UP,TL.YIELD.DIMENSION,TL.YIELD.VAR.REF,TL.YIELD.VEC.REF,TL.SEL.DYN.VAR,
TL.SEL.DYN.VEC,TL.PRINT.NAME,TL.PRINT.VALUE,TL.YIELD.NAME,TL.YIELD.VALUE,
TL.SET.VALUE,TL.GO,TL.TRACE,TL.PRINT.PROFILE,TL.PRINT.S.TRACE,
TL.TRACE.R,INITIALIZE,PV,SV,LT,INCPC,RESTORE.LINE,
CUR.LT.PROC,CUR.LT.LINE,CUR.LT.PAGE,PV,LT,
NB,CUR.LT.PROC,SCREEN,MODE,SHORTCUT,CUR.LINK,TR,RN);
@BOX 2.1
#MTL10/2
@BOX 3.1
*END
**IN -1
@END
@TITLE MTL10/2(1,7)
@COL 1S-2R-3R
@COL 4R-5R-6R-7F
@FLOW 1-2-3
@FLOW 4-5-6-7
@BOX 1.0
MUTL DIAGNOSTIC PRIMITIVES
@BOX 2.0
PROCEDURE SPECS OF PRIMITIVES
@BOX 3.0
GLOBAL TYPE DECLARATIONS
@BOX 4.0
GLOBAL VARIABLE DECLARATIONS
@BOX 5.0
GLOBAL DATA STRUCTURE DECLARATIONS
@BOX 6.0
PROCEDURES
@BOX 7.0
END
@BOX 1.1
@BOX 2.1
LSPEC TL.SET.TRAPS();
LSPEC TL.TRACE($IN);
PSPEC SEARCH.LT($IN32)/$IN;
PSPEC INBSTR()/ADDR[$LO8];
PSPEC FINDFNAME(ADDR[$LO8])/$IN;
PSPEC SHORTCUT()/$IN;
PSPEC FINDLINE()/ADDR;
PSPEC VALIDATE()/$IN;
PSPEC RESTORE.LINE();
PSPEC INIT.10();
PSPEC TL.TRAP($IN,$IN);
PSPEC TL.RESET.TRAPS();
PSPEC TL.INIT($IN);
PSPEC TL.NEXT.PROC($IN)/$IN;
PSPEC TL.YIELD.PROC()/$IN;
PSPEC TL.YIELD.LINE()/$IN32;
PSPEC TL.NEXT.VAR($IN)/$IN;
PSPEC TL.FIND.VAR(ADDR[$LO8])/$IN;
PSPEC TL.SEL.VAR($IN)/$IN;
PSPEC TL.SEL.FLD($IN)/$IN;
PSPEC TL.SEL.EL($IN)/$IN;
PSPEC TL.SEL.ALT($IN)/$IN;
PSPEC TL.UP();
PSPEC TL.YIELD.DIMENSION()/ADDR;
PSPEC TL.YIELD.VAR.REF()/ADDR;
PSPEC TL.YIELD.VEC.REF()/$LO64;
PSPEC TL.SEL.DYN.VAR(ADDR,$IN)/$IN;
PSPEC TL.SEL.DYN.VEC($LO64,$IN)/$IN;
PSPEC TL.PRINT.NAME($IN)/$IN;
PSPEC TL.PRINT.VALUE()/$IN;
PSPEC TL.YIELD.NAME($IN)/ADDR[$LO8];
PSPEC TL.YIELD.VALUE();
PSPEC TL.SET.VALUE($IN,ADDR);
PSPEC TL.GO($IN32);
PSPEC TL.INSERT.BREAKPOINT();
PSPEC TL.REMOVE.BREAKPOINT();
PSPEC TL.TRACE.R();
PSPEC TL.PRINT.PROFILE();
PSPEC TL.PRINT.S.TRACE();
@BOX 3.1
*GLOBAL 9;
TYPE COMP.ENTRY IS $IN16 CS.FIELD,CS.TYPE
$IN32 CS.ADDR,CS.CUR.EL,CS.DIM,CS.ELSIZE;
TYPE PROFILE.ENTRY IS $IN L,N;
@BOX 4.1
LITERAL LSIZE = %400,BSIZE = %200,PSIZE = %40;
$IN32 FAULTLINK,CURLINK,NB,DPV,DST,LAST.PCS,TR,RN,
FAULT.LT.LINE,TEMPCODE,FAULT.PC,INCPC,LASTLINE,
LASTPROC,LASTBOX,PROPSEG,FAILED.PCS,
CUR.PCS,CUR.LT.LINE,CUR.LT.PROC,CUR.LT.PAGE,
CUR.COMP,MODE,REPLY,RST,SCREEN,CNT.TP,CNT.TL,CNT.TB,
LFLAG,BFLAG,PFLAG,TRACE,NOPRINT,CURRENTIN,CURRENTOUT;
LITERAL /ADDR [$LO8] NIL =;
$IN [40] TRACE.L,TRACE.P,TRACE.B;
ADDR ENTER.TRAP[9] OLD.TRAPS;
$IN [48] VEC;
$LO8[%30] STRING;
ADDR [$LO16] PV,LT;
ADDR [$LO8] SV;
@BOX 5.1
COMP.ENTRY [20] COMP.STACK;
PROFILE.ENTRY [PSIZE] PROFILE.P;
PROFILE.ENTRY [BSIZE] PROFILE.B;
PROFILE.ENTRY [LSIZE] PROFILE.L;
*GLOBAL 0;
@BOX 6.1
#MTL10.1.1
#MTL10.1.2
#MTL10.1.3
#MTL10.4.1
#MTL10.5.1
#MTL10.5.2
#MTL10.5.3
#MTL10.6.1
#MTL10.6.2
#MTL10.7.1
#MTL10.7.2
#MTL10.7.3
#MTL10.7.4
#MTL10.7.5
#MTL10.7.6
#MTL10.7.7
#MTL10.7.8
#MTL10.7.9
#MTL10.7.10
#MTL10.8.1
#MTL10.8.2
#MTL10.8.3
#MTL10.9.1
#MTL10.9.3
#MTL10.10.1
#MTL10.10.2
#MTL10.10.3
#MTL10.11.1
#MTL10.11.3
#MTL10.11.7
#MTL10.11.8
#MTL10.3.1
#MTL10.3.2
#MTL10.3.3
#MTL10.3.4
#MTL10.3.5
#MTL10.3.6
#MTL10.3.7
#MTL10.3.8
@BOX 7.1
@END
@TITLE MTL10.1.1(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROC TL.SET.TRAPS
@BOX 2.0
SET TRAPS
@BOX 3.0
END
@BOX 1.1
PROC TL.SET.TRAPS;
INIT.10();
INIT.24();
@BOX 2.1
$IN I;
FOR I<9 DO READ.TRAP(I)=>OLD.TRAPS[I] OD;
FOR I<4 DO SET.TRAP(I,^TL.TRAP) OD;
SET.TRAP(6,^TL.TRAP);
SET.TRAP(8,^TL.TRAP);
@BOX 3.1
END
@END
@TITLE MTL10.1.2(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROC TL.RESET.TRAPS
@BOX 2.0
RESET TRAPS
@BOX 3.0
END
@BOX 1.1
PROC TL.RESET.TRAPS;
@BOX 2.1
$IN I;
FOR I<9 DO SET.TRAP(I,OLD.TRAPS[I]) OD;
@BOX 3.1
END
@END

@TITLE MTL10.1.3(1,8)
@COL 10R
@COL 1S-2T-12T-3R-4T-5R-6T-7T-8R-9F
@COL 13R-14R-15T-16R-11R
@ROW 3-13
@ROW 5-11
@ROW 10-3
@FLOW 1-2N-12N-3-4N-5-6-7N-8-9
@FLOW 2Y-10-9
@FLOW 4Y-14-15N-11-6
@FLOW 7Y-9
@FLOW 12Y-13-9
@FLOW 15N-16-11
@BOX 1.0
PROC TL.TRAP
@BOX 2.0
TRACING?
@BOX 3.0
SELECT STREAMS
GET FAULT LINK
@BOX 4.0
BREAKPOINT?
@BOX 5.0
PROGRAM FAULT
@BOX 6.0
DUMP OR DEBUG
@BOX 7.0
BREAKPOINT?
@BOX 8.0
EXIT
@BOX 9.0
SETSTACK
END
@BOX 10.0
TRACE
@BOX 11.0
BREAKPOINT
@BOX 12.0
BPT TO REINSERT BPT AT LINE ABOVE?
@BOX 13.0
REINSERT BPT AT LAST LINE
AND ORIGINAL CODE AT THIS LINE
@BOX 14.0
SEARCH BPT ARRAY FOR FAULTPC
@BOX 15.0
BPT INSERTED AT COMPILE?
@BOX 16.0
DOES RUNTIME BPT WANT EXECUTING?
@BOX 1.1
PROC TL.TRAP(P1,P2);
$IN I;
TL.RESET.TRAPS();
IF GET.NEXT.LINK(GET.FAULT.LINK()
=>FAULT.LINK,1)=> FAULTPC ->>SEGSHIFT =>FAILED.PCS/= LAST.PCS
THEN
 TL.INIT(FAILED.PCS)
 FI;
@BOX 2.1
P2=>RN;
IF P1=>TR=0 AND RN=512,
@BOX 3.1
CURRENT.INPUT()=>CURRENT.IN;
CURRENT.OUTPUT()=>CURRENT.OUT;
SELECT.INPUT(0);
SELECT.OUTPUT(0);
(IF OMODE()->>8&1 =>MODE =0 THEN 120 ELSE 80) =>SCREEN;
IF TR/=0 OR RN /=256 THEN OUTM(TR,RN) FI;
IF TRACE&2 =2 THEN
TL.PRINT.STRACE() FI;
GET.NEXT.LINK(FAULT.LINK,0)<<-NAMESHIFT =>NB;
TL.NEXT.PROC(-1)=>I;
@BOX 4.1
IF TR=0 AND RN=256,
@BOX 5.1
IF I=-1 THEN
WHILE GET.NEXT.LINK(FAULT.LINK,0)=>FAULT.LINK /=0 DO
IF TL.NEXT.PROC(-1) /=-1, ->FIND;
OD;
->FAIL FI;
@BOX 6.1
FIND:IF MODE=0 THEN
TL.DUMP() ELSE;
PRINT.PROC.LINE();
CAPTION(%"$LType Q to quit diagnostics,H for help");
TL.DEBUG() FI;
SELECT.INPUT(CURRENT.IN);
SELECT.OUTPUT(CURRENT.OUT);
@BOX 7.1
IF TR=0 AND RN=256,
@BOX 8.1
FAIL:TL.RESET.TRAPS();
ENTER.TRAP(TR,RN);
@BOX 9.1
E:SETSTACK(INCPC);
END;
@BOX 10.1
TL.TRACE.R();
1=>INCPC;
@BOX 11.1
CAPTION(%"$LBREAKPOINT");
1=>INCPC;
@BOX 12.1
IF TR=0 AND RN=256 AND TEMPCODE/=0,
@BOX 13.1
CHANGE.ACCESS(FAILED.PCS,%1E);
WRITE(LASTLINE,%03,1);
WRITE(FAULT.PC,TEMPCODE,1);
CHANGE.ACCESS(FAILED.PCS,%1D);
0=>INCPC=>TEMPCODE;
@BOX 14.1
-1=>I;
WHILE 1+>I<10 AND CA OF BPT[I]/=FAULTPC
DO OD;
CUR.LT.LINE=>FAULT.LT.LINE;
@BOX 15.1
IF I=10,
@BOX 16.1
IF 1+>CUR OF BPT[I] <MAX OF BPT[I] THEN
RESTORE.LINE();
->E ELSE
0 =>CUR OF BPT[I] FI;
@END

@TITLE MTL10.3.1(1,6)
@COL 1S-2R-3T-4R-5R-12T-13R-10T-6R-11T-7R-9F
@COL 8R
@ROW 7-8
@FLOW 1-2-3N-4-5-12N-13-10N-6-11N-7-9
@FLOW 11Y-8-9
@FLOW 3Y-8
@FLOW 12Y-8
@FLOW 10Y-8
@BOX 1.0
SEARCH.LT(LINK.ADDR)LTE
@BOX 2.0
GET SEGMENT NO.AND ADDRESS
@BOX 3.0
SEGMENT > 63?
@BOX 4.0
SET SV,LT
FIND LINE.TABLE
@BOX 5.0
SEARCH LINE.TABLE FOR SEGMENT
@BOX 6.0
IF CUR.LT.PROC IS A NESTED PROC,
GET CORRECT CUR.LT.PROC
@BOX 7.0
RETURN LTE
@BOX 8.0
RETURN -1
@BOX 9.0
END
@BOX 10.0
CODE ADDRESS NOT FOUND IN LINE.TABLE?
@BOX 11.0
CUR.LT.PROC NOT FOUND?
@BOX 12.0
SEGMENT NOT FOUND?
@BOX 13.0
SEARCH LINE.TABLE FOR PAGE,LINE,PROC ENTRIES
@BOX 1.1
PROC SEARCH.LT(LINK.ADDR);
$IN F,I,T,LT.SEG,ACTUAL.SEG,AD,EP;
@BOX 2.1
LINKADDR -1 &%F(4) =>AD;
LINK.ADDR ->> SEGSHIFT => ACTUAL.SEG;
LINK.ADDR ->> 16 => LT.SEG;
@BOX 3.1
IF ACTUAL.SEG > LAST.USER.SEG OR ACTUAL.SEG = 0,
@BOX 4.1
IF CUR.PCS /=ACTUAL.SEG THEN
TL.INIT(ACTUAL.SEG=>CURPCS);
MAKE($LO16,1<<-SEGM1,PROPSEG<<-SEGSHIFT=>DPV) => PV;
MAKE($LO16,1<<-SEGM1,PV^[0]+DPV) => LT;
MAKE($LO8,1<<-SEGSHIFT,PV^[1]+DPV) => SV;
FI;
@BOX 5.1
0 => I;
WHILE LT^[2+>I] => T /=%FFFA AND [T /= %FFFD OR LT^[I+1] /= LT.SEG] DO OD;
@BOX 13.1
-1 =>F => EP => CUR.LT.PROC => CUR.LT.LINE => CUR.LT.PAGE;
WHILE LT^[2+>I] => T /= %FFFA /= %FFFD AND F < 0 DO
IF T=%FFFF THEN
 I=>CUR.LT.PAGE ELSE
IF T=%FFFE THEN I=>CUR.LT.PROC ELSE
IF T=%FFFC THEN I=>EP ELSE
IF T > 0 THEN IF T>AD THEN 0=>F ELSE
I=>CUR.LT.LINE FI FI FI FI FI OD;
IF CUR.LT.PAGE<0 OR CUR.LT.LINE<0
THEN -1 => F FI;
@BOX 6.1
IF EP >= CUR.LT.PROC THEN
IF EP < 0 THEN CUR.LT.LINE=>I
ELSE LT^[EP+1] => I FI;
WHILE F = 0 AND LT^[2->I] => T /= %FFFB DO
IF T = %FFFC THEN LT^[I+1] => I ELSE
IF T = %FFFE THEN 1 -> F FI FI OD
I => CUR.LT.PROC ELSE
-1 => F FI;
@BOX 7.1
CUR.LT.PROC => SEARCH.LT;
@BOX 8.1
IF NOPRINT=0 THEN
IF ACTUAL.SEG > LAST.USER.SEG THEN
CAPTION(%"$LIn System Library at address ")
ELSE
CAPTION(%"$LLink not found for address ");
FI;
OUTHEX(LINKADDR,8) FI;
-1 => SEARCH.LT;
@BOX 9.1
END;
@BOX 10.1
IF F < -1,
@BOX 11.1
IF F = 0,
@BOX 12.1
IF T = %FFFA,
@END
@TITLE MTL10.3.2(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROC INBSTR
@BOX 2.0
READ ALPHANUMERIC CHARACTERS
INTO STRING
@BOX 3.0
END
@BOX 1.1
PROC INBSTR;
$IN N,CH;
-1 => N;
@BOX 2.1
WHILE NEXTCH() < %41 DO INCH() OD;
GO:WHILE NEXTCH() => CH > %40 AND CH< %5B
OR [CH > %2F AND CH < %3A]
OR [CH > %60 AND CH < %7B]
DO INCH() => STRING[1+>N] OD;
IF CH = %2E THEN
INCH();
-> GO FI;
PART(^STRING,0,N) => INBSTR;
@BOX 3.1
END;
@END

@TITLE MTL10.3.3(1,6)
@COL 1S-2R-3R-4T-6T-8R-9R
@COL 5F-7R
@ROW 6-5
@ROW 8-7
@FLOW 1-2-3-4N-6N-8-9-3
@FLOW 4Y-5
@FLOW 6Y-7
@BOX 1.0
PROC FINDFNAME(NAME)
@BOX 2.0
DECLARATIONS
@BOX 3.0
SELECT TYPE
@BOX 4.0
FIELD FOUND?
@BOX 5.0
RETURN ALT*100 + FIELD
@BOX 6.0
END OF TYPE?
@BOX 7.0
NAME NOT FOUND
@BOX 8.0
NEXT ALTERNATIVE
@BOX 9.0
NEXT FIELD
@BOX 1.1
PROC FINDFNAME(NAME);
@BOX 2.1
$IN FOUND,SF,SN,TYPENAME;
TYPE FLDENTRY IS $LO16 FNAME $IN16 FFLAG,FDISP,FTYPE;
ADDR FLDENTRY FLDF;
0 => FOUND;
SIZE(NAME) => SN;
2-TYPECONV(CS.TYPE OF COMPSTACK[CURCOMP]) => TYPENAME;
@BOX 3.1
MAKE(FLD.ENTRY,0,TYPENAME*PVSIZ+DPV) => FLDF;
SELECT FLDF^;
@BOX 4.1
IF SV^[FNAME] => SF = SN THEN
WHILE 1->SF>=0 AND SV^[FNAME+SF+1]=NAME^[SF] DO OD;
FI;
IF SF = -1,
@BOX 5.1
FOUND=> FINDFNAME;
END;
@BOX 6.1
IF FFLAG = 1,
@BOX 7.1
-1 => FINDFNAME;
EXIT;
@BOX 8.1
1 +> FOUND;
IF FFLAG = 2 THEN
FOUND/100 + 1 * 100 => FOUND FI;
@BOX 9.1
(IF FTYPE < 0 THEN 5 ELSE 4) +> TYPE.NAME;
@END

@TITLE MTL10.3.4(1,11)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
PROC SHORTCUT
@BOX 2.0
DECLARATIONS
@BOX 3.0
GET DIMENSION
@BOX 4.0
GET SIZE OF ELEMENTS
@BOX 5.0
WORK OUT WHERE TRAILING ZEROS BEGIN
@BOX 6.0
RETURN NO OF NON-ZERO ELEMENTS
@BOX 1.1
PROC SHORTCUT;
@BOX 2.1
SELECT COMP.STACK[CUR.COMP];
$IN T,EL;
$IN32 D;
@BOX 3.1
IF CS.DIM => D < 0 THEN
1 => D FI;
@BOX 4.1
IF TYPECONV(CS.TYPE) =>T >=0 THEN
T & %F + 1 => T ELSE
PV^[1-T] => T FI;
@BOX 5.1
T*D /4 +1 => EL;
REALADDR(CSADDR)=>CSADDR;
WHILE 1->EL >=0 AND ACCESS(EL*4+CS.ADDR,4) =0 DO OD;
@BOX 6.1
-1 => D;
WHILE 1 +> D * T < (EL+1*4) DO OD;
(IF D > CS.DIM AND CS.DIM > 0 THEN CS.DIM  ELSE D) => SHORTCUT;
END;
@END

@TITLE MTL10.3.5(1,11)
@COL 1S-2R-3R-4R-5T-6R-7T-8F
@COL 9R
@ROW 8-9
@FLOW 1-2-3-4-5N-6-7N-8
@FLOW 5Y-9
@FLOW 7Y-9
@BOX 1.0
PROC FINDLINE
@BOX 2.0
DECLARATIONS
@BOX 3.0
INPUT <LINE> OR <PAGE>.<LINE>
@BOX 4.0
SEARCH LINETABLE FOR PAGE
@BOX 5.0
PAGE NOT FOUND?
@BOX 6.0
SEARCH LINETABLE FOR LINE
IF EXACT LINE NOT PRESENT IN
LINETABLE, CHOOSE PREVIOUS LINETABLE
ENTRY.
@BOX 7.0
LINE NOT FOUND?
@BOX 8.0
RETURN CODE ADDRESS OF LINE
@BOX 9.0
EXIT
@BOX 1.1
PROC FINDLINE;
@BOX 2.1
$IN PAGE,LINE,I,T,F;
@BOX 3.1
INI() => PAGE;
IF NEXTCH() = '. THEN
INCH();
INI() => LINE
ELSE PAGE => LINE;
-1 => PAGE FI;
@BOX 4.1
0 => I => T;
WHILE LT^[2+>I] /= %FFFD OR LT^[I+1] /= CUR.PCS DO OD;
IF PAGE < 0 THEN
CUR.LT.PAGE => I ELSE
WHILE LT^[2+>I] => T /= %FFFA /= %FFFD AND
[T /=%FFFF OR LT^[I+1] /= PAGE] DO OD;
FI;
@BOX 5.1
IF T = %FFFA OR T = %FFFD,
@BOX 6.1
-1 => F;
WHILE F < 0 AND LT^[2+>I] => T /=%FFFA /=%FFFF /=%FFFD DO
IF T & %FFF0 /= %FFF0 THEN
IF LT^[I+1] = LINE THEN
0 => F FI
IF LINE < LT^[I+1] AND LINE > LT^[I-1] THEN
   0 => F;
   2 -> I;
   IF LT^[I] & %FFF0 = %FFF0 THEN
        CAPTION(%"$LLINE NOT AN EXECUTABLE STATEMENT ");
        -1 => FINDLINE;
        EXIT;
        FI
   CAPTION(%"$LWARNING - LINE SELECTED INSTEAD AT ");
   IF PAGE < 0 THEN CAPTION(%"CURRENT PAGE ")
     ELSE
     CAPTION(%"PAGE ");
     OUT.I(PAGE,0);
   FI
   CAPTION(%" LINE ");
   OUT.I(LT^[I+1],0);
FI
FI OD;
@BOX 7.1
IF F < 0,
@BOX 8.1
I => FINDLINE;
END;
@BOX 9.1
CAPTION(%"$LLINE NOT IN PROG");
-1 => FINDLINE;
EXIT;
@END

@TITLE MTL10.3.6(1,6)
@COL 1S-2R-3R-4R-6T-7T-8F
@COL 9R-10R-11R
@ROW 7-9
@ROW 8-11
@FLOW 1-2-3-4-6N-7N-8
@FLOW 6Y-9-11
@FLOW 7Y-10-11
@BOX 1.0
PROC VALIDATE
@BOX 2.0
DECLARATIONS
@BOX 3.0
GET START ADDRESS
@BOX 4.0
GET SIZE OF VARIABLE
@BOX 6.0
UNABLE TO READ SEGMENT?
@BOX 7.0
VARIABLE RUN OFF END OF SEGMENT?
@BOX 8.0
END
@BOX 9.0
SEG UNDEFINED
@BOX 10.0
SEG OVERFLOW
@BOX 11.0
EXIT
@BOX 1.1
PROC VALIDATE;
@BOX 2.1
SELECT COMP.STACK[CUR.COMP];
$IN S,LENGTH;
@BOX 3.1
IF CS.ADDR /=-1 THEN
IF REALADDR(CS.ADDR)=> CS.ADDR ->> SEGSHIFT =>S =0,->E;
ELSE -1 =>S FI;
@BOX 4.1
IF CS.TYPE<0 THEN CS.DIM=>LENGTH
ELSE 1 => LENGTH FI;
TSIZE(CS.TYPE) *> LENGTH;
@BOX 5.1
@BOX 6.1
READ.SEGMENT.STATUS(S);
IF PW0/=0 OR PW2 & %4 = 0,
@BOX 7.1
IF CS.ADDR & %FFFF + LENGTH > PW1,
@BOX 8.1
E: 0 => VALIDATE;
END;
@BOX 9.1
TL.PRINT.NAME(0);
CAPTION(%" NO READ ACCESS ");
@BOX 10.1
TL.PRINT.NAME(0);
CAPTION(%" SEG OFLO ");
@BOX 11.1
NEWLINES(0);
-1 => VALIDATE;
EXIT;
@END

@TITLE MTL10.3.7(1,6)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
PROC INIT.10
@BOX 2.0
DECLARATIONS
@BOX 3.0
INITIALIZE VARIABLES FOR TRACING/PROFILING
@BOX 4.0
END
@BOX 1.1
PROC INIT.10;
@BOX 2.1
$IN I;
CREATE.SEGMENT(MURD.WORK.SEG,%10000);
@BOX 3.1
0 =>TEMPCODE =>NOPRINT =>LFLAG =>PFLAG =>BFLAG;
-1 => CNT.TP => CNT.TL => CNT.TB => LASTPROC =>LASTBOX=>CUR.PCS=> LAST.PCS;
FOR I < LSIZE DO
-1 => L OF PROFILE.L[I];
0 => N OF PROFILE.L[I]
OD;
FOR I < PSIZE DO
-1 => L OF PROFILE.P[I];
0 => N OF PROFILE.P[I]
OD;
FOR I < BSIZE DO
-1 => L OF PROFILE.B[I];
0 => N OF PROFILE.B[I]
OD;
@BOX 4.1
END;
@END

@TITLE MTL10.3.8(1,6)
@COL 1S-2R-3T-4R-6F
@COL 5R
@ROW 4-5
@FLOW 1-2-3N-4-6
@FLOW 3Y-5-6
@BOX 1.0
PROC RESTORE.LINE
@BOX 2.0
SEARCH BPT FOR FAULTPC
@BOX 3.0
NOT THERE?
@BOX 4.0
RESTORE ORIGINAL CONTENTS OF LINE
BEFORE BREAKPOINT WAS INSERTED
@BOX 5.0
NO ACTION - BPT INSERTED
AT COMPILE TIME
@BOX 6.0
END
@BOX 1.1
PROC RESTORE.LINE;
$IN I,NEXTLINE;
@BOX 2.1
-1 =>I;
WHILE 1+>I<10 AND CA OF BPT[I] /=FAULT.PC DO OD;
@BOX 3.1
IF I=10,
@BOX 4.1
CHANGE.ACCESS(CUR.PCS,%1E);
WRITE(FAULTPC,CODE OF BPT[I],1);
ACCESS(CUR.PCS<<-SEGSHIFT!LT^[FAULT.LT.LINE+2]=>NEXTLINE,1)=>TEMPCODE;
WRITE(NEXTLINE,%03,1);
CHANGE.ACCESS(CUR.PCS,%1D);
FAULT.PC=>LASTLINE;
0=>INCPC;
@BOX 5.1
(IF ACCESS(FAULTPC,1)=%03 THEN 1 ELSE 0)=>INCPC;
@BOX 6.1
END;
@END

@TITLE MTL10.4.1(1,11)
@COL 1S-2R-4F
@FLOW 1-2-4
@BOX 1.0
PROC TL.INIT(SEG)
@BOX 2.0
FIND LIBRARY ASSOCIATED WITH SEGMENT
@BOX 4.0
END
@BOX 1.1
PROC TL.INIT(SEG);
ADDR [$LO8] LIB.NAME;
$IN TRAP.STATUS,I,J;
$LO64 PTWO,TEMP;
$LO8 CH;
$LO8 [32] FILE.N;
@BOX 2.1
IF SEG=LAST.PCS,->E;
LOOK.UP.LIB(SEG=>LAST.PCS)=> LIB.NAME;
IF SIZE(LIB.NAME) =0 THEN
PROG.PROP.SEG =>PROPSEG ELSE
READ.RECOVERY.STATUS(4)=>TRAP.STATUS;
SET.RECOVERY.STATUS(4,1);
RELEASE.SEGMENT(FILED.PROP.SEG);
0 => TEMP => PTWO => I;
WHILE I < SIZE(LIB.NAME)  AND LIB.NAME^[I] => CH /= 0 DO
    IF CH = ': THEN
        0 => J;
        1 +> I;
        TEMP => PTWO;
        WHILE I < SIZE(LIB.NAME) DO
           LIB.NAME^[I] => FILE.N[J];
           1 +> I;
           1 +> J;
        OD
    ELSE
        CH => FILE.N[I];
        TEMP <<-8 ! CH => TEMP;
        1 +> I;
    FI;
    OD;
    'R => FILE.N[I];
    'D => FILE.N[1+>I];
OPEN.FILE(PART(^FILE.N,0,I), PTWO, FILED.PROP.SEG=>PROPSEG,%1E);
IF PW0 /= 0 THEN CAPTION(%"$LNO PROPERTIES FOR ");
CAPTION(LIB.NAME);
PROG.PROP.SEG =>PROPSEG FI;
SET.RECOVERY.STATUS(4,TRAP.STATUS) FI;
@BOX 4.1
E:END;
@END
@TITLE MTL10.5.1(1,7)
@COL 1S-2T-3T-16R-4T-7T-5T-6T-8R-9F
@COL 10T-11T-12T-13R-14R-15C
@ROW 3-10
@ROW 16-11
@ROW 9-15
@ROW 4-12
@FLOW 1-2N-3N-16-4N-7N-5N-6N-8-9
@FLOW 2Y-10N-11N-13-8
@FLOW 3Y-12Y-14-15
@FLOW 4Y-15
@FLOW 5Y-9
@FLOW 7Y-9
@FLOW 6Y-5
@FLOW 10Y-15
@FLOW 11Y-14
@FLOW 12N-13
@BOX 1.0
TL.NEXT.PROC(STATIC)TL.ACTIVATION.NAME
@BOX 2.0
IS STATIC 0?
@BOX 3.0
IS STATIC -1?
@BOX 4.0
NO SURROUNDING PROC?
@BOX 5.0
GET NEXT DYNAMIC LINK.
NO DYNAMIC LINK?
@BOX 6.0
SEARCH LINE.TABLE FOR LINK ADDRESS.
NOT THE REQUIRED PROC?
@BOX 7.0
BLOCK?
@BOX 8.0
SET CUR.ACT
@BOX 9.0
END
@BOX 10.0
END OF STACK?
@BOX 11.0
SEARCH LINE.TABLE FOR LINK ADDRESS
@BOX 12.0
GET INITIAL LINK AND
SEARCH LINE.TABLE FOR LINK ADDRESS.
NOT FOUND?
@BOX 13.0
SET CUR.PROC
@BOX 14.0
SET CUR.PROC = -1
@BOX 15.0
END -1
@BOX 16.0
GET LT.PROC ENTRY OF PROC THAT
STATICALLY SURROUNDS CUR.PROC
@BOX 1.1
PROC TL.NEXT.PROC(STATIC);
ADDR L;
$IN T,F,S,I,OLDPCS,OLDP,OLDG,OLDL,FLAG.VECNB;
ADDR [$LO8] OLDSV;
ADDR [$LO16] OLDLT;
ADDR [$LO16] OLDPV;
ADDR $IN ASP;
SV => OLDSV;
LT => OLDLT;
PV =>OLDPV;
CUR.PCS=>OLDPCS;
CUR.LT.PROC => OLDP;
CUR.LT.PAGE => OLDG;
CUR.LT.LINE => OLDL;
IF STATIC=0 THEN IF
PROCTYPE()=2
THEN 2 =>STATIC FI FI;
@BOX 2.1
IF STATIC = 0,
@BOX 3.1
IF STATIC = -1,
@BOX 4.1
IF F < 0,
@BOX 5.1
IF I => L =0,
@BOX 6.1
GET.NEXT.LINK(L,0)<<-NAMESHIFT => I;
1 => NOPRINT;
IF SEARCH.LT(GET.NEXT.LINK(L,1)) /= CUR.LT.PROC
OR LT /= OLDLT,
@BOX 7.1
IF STATIC=2,
@BOX 8.1
0=>NOPRINT;
GET.NEXT.LINK(L=>CUR.LINK,0) <<- NAMESHIFT => NB;
IF PROCTYPE()=>FLAG.VECNB =2
THEN CUR.LT.PROC=>S;
WHILE TL.NEXT.PROC(0)/=-1 AND
PROCTYPE() =>FLAG.VECNB =2
DO OD;
S =>CUR.LT.PROC;
FI;
@BOX 9.1
CUR.LINK => TL.NEXT.PROC;
END;
@BOX 10.1
IF NB => L =0,
@BOX 11.1
IF SEARCH.LT(GET.NEXT.LINK(L,1)) < 0,
@BOX 12.1
GET.NEXT.LINK(FAULT.LINK=>L,0) <<-NAMESHIFT =>NB;
;
IF SEARCH.LT(GET.NEXT.LINK(L,1)+1) < 0,
@BOX 13.1
@BOX 14.1
@BOX 15.1
OLDSV => SV;
OLDLT => LT;
OLDPV =>PV;
OLDP => CUR.LT.PROC;
OLDG => CUR.LT.PAGE;
OLDL => CUR.LT.LINE;
OLDPCS=>CURPCS;
-1 => TL.NEXT.PROC;
EXIT;
@BOX 16.1
-1 => F;
WHILE F < 0 AND LT^[2->CUR.LT.PROC]=>T /= %FFFB DO
IF T = %FFFC THEN
LT^[CUR.LT.PROC+1] => CUR.LT.PROC
ELSE
IF T = %FFFE THEN
0 => F FI FI OD;
NB => I;
@END
@TITLE MTL10.5.2(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.YIELD.PROC()TL.PROC.NAME
@BOX 2.0
RETURN CUR.PROC
@BOX 3.0
END
@BOX 1.1
PROC TL.YIELD.PROC;
@BOX 2.1
LT^[CUR.LT.PROC+1] => TL.YIELD.PROC;
@BOX 3.1
END;
@END
@TITLE MTL10.5.3(1,6)
@COL 1S-3R-4F
@FLOW 1-3-4
@BOX 1.0
TL.YIELD.LINE()PAGE.LINE
@BOX 3.0
RETURN PAGE.LINE
@BOX 4.0
END
@BOX 1.1
PROC TL.YIELD.LINE;
@BOX 3.1
LT^[CUR.LT.PAGE+1]<<-16 ! LT^[CUR.LT.LINE+1] => TL.YIELD.LINE;
@BOX 4.1
END;
@END
@TITLE MTL10.6.1(1,6)
@COL 1S-3T-4R-6T-7R-9F
@COL 5R-8R
@ROW 4-5
@ROW 7-8
@FLOW 1-3N-4-6N-7-9
@FLOW 3Y-5-6
@FLOW 6Y-8-9
@BOX 1.0
TL.NEXT.VAR(TL.VAR.NAME)TL.VAR.NAME
@BOX 3.0
IS TL.VAR.NAME -1?
@BOX 4.0
SKIP OVER TL.VAR.NAME ENTRY IN PROPERTY.VECTOR
TO NEXT.VAR ENTRY
@BOX 5.0
GET FIRST VARIABLE OF CUR.PROC => NEXT.VAR
@BOX 6.0
IS THE ADDRESS OF NEXT.VAR -1?
@BOX 7.0
RETURN TL.NAME OF NEXT.VAR
@BOX 8.0
RETURN -1
@BOX 9.0
END
@BOX 1.1
PROC TL.NEXT.VAR(TL.VAR.NAME);
@BOX 3.1
IF TL.VAR.NAME= -1,
@BOX 4.1
(IF PV^[TL.VAR.NAME+TYPEPOS] < 0 THEN 1 ELSE 0) +FLDSIZE +> TL.VAR.NAME;
@BOX 5.1
LT^[CUR.LT.PROC+1] + VARPOS => TL.VAR.NAME;
@BOX 6.1
IF PV^[TL.VAR.NAME] = -1,
@BOX 7.1
TL.VAR.NAME => TL.NEXT.VAR;
@BOX 8.1
-1 => TL.NEXT.VAR;
@BOX 9.1
END;
@END
@TITLE MTL10.6.2(1,6)
@COL 1S-2R-3T-8R-4T-5R-7F
@COL 6R
@ROW 5-6
@FLOW 1-2-3N-8-4N-5-7
@FLOW 3Y-6-7
@FLOW 4Y-3
@BOX 1.0
TL.FIND.VAR([SYMB.NAME])TL.VAR.NAME
@BOX 2.0
INITIALIZE VARIABLES
STARTING POINT FOR SEARCH IS THE
CUR.PROC IN THE PROPERTY.VECTOR
@BOX 3.0
PICK UP NEXT VARIABLE NAME
HAS IT AN ADDRESS OF -1?
@BOX 4.0
COMPARE VARIABLE NAME WITH
[SYMB.NAME]
IS IT DIFFERENT?
@BOX 5.0
RETURN TL.NAME OF THIS VARIABLE
@BOX 6.0
RETURN -1
@BOX 7.0
END
@BOX 8.0
REMOVE ANY NULLS
@BOX 1.1
PROC TL.FIND.VAR(NAME);
$IN Z,NZ,VAR,P;
-1 => VAR;
;
@BOX 2.1
SIZE(NAME) => NZ;
@BOX 3.1
IF TL.NEXT.VAR(VAR) => VAR = -1,
@BOX 4.1
IF Z = NZ THEN
WHILE 1 -> Z >= 0 AND SV^[P+Z+1] = NAME^[Z] DO OD;
FI;
IF Z > -1,
@BOX 5.1
VAR => TL.FIND.VAR;
@BOX 6.1
-1 => TL.FIND.VAR;
@BOX 7.1
END;
@BOX 8.1
SV^[PV^[VAR] => P] => Z;
WHILE SV^[P+Z] = '$N DO 1 -> Z OD;
@END
@TITLE MTL10.7.1(1,6)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
TL.SEL.VAR(TL.VAR.NAME)TL.TYPE.NAME
@BOX 2.0
SET TL.VAR.NAME TO THE CUR.VARIABLE
INITIALIZE CUR.COMP TO ZERO
@BOX 3.0
TAKING INFORMATION FROM THE PROPERTY.TABLE
ABOUT THE VARIABLE, FILL THE BASE POSITION
OF THE COMP.STACK
@BOX 4.0
RETURN TL.TYPE.NAME
@BOX 5.0
END
@BOX 1.1
PROC TL.SEL.VAR(TL.VAR.NAME);
@BOX 2.1
SELECT COMP.STACK[0 => CUR.COMP];
@BOX 3.1
IF PV^[TL.VAR.NAME+3] => CS.TYPE < 0 THEN
PV^[TL.VAR.NAME+4] => CS.DIM;
TSIZE(CSTYPE) => CS.ELSIZE;
ELSE
-1 => CS.DIM => CS.ELSIZE FI;
PV^[TL.VAR.NAME+1]<<-16 ! PV^[TL.VAR.NAME +2] => CS.ADDR;
-1 => CS.CUR.EL;
TL.VAR.NAME => CS.FIELD;
@BOX 4.1
CS.TYPE => TL.SEL.VAR;
@BOX 5.1
END;
@END
@TITLE MTL10.7.2(1,6)
@COL 1S-2T-3R-5R-6T-10R-11R-12R-13F
@COL 4R-7T-8R
@COL 9R
@ROW 3-4
@ROW 7-10
@ROW 8-9-12
@FLOW 1-2N-3-5-6N-10-11-12-13
@FLOW 2Y-4-5
@FLOW 6Y-7N-8-13
@FLOW 7Y-9-13
@BOX 1.0
TL.SEL.FLD(N)TL.TYPE.NAME
@BOX 2.0
N >= 0?
@BOX 3.0
GET CUR.COMP FIELD ENTRY
@BOX 4.0
GET POINTER TO FIRST FIELD
OF TYPE OF CUR.COMP
@BOX 5.0
SEARCH ALONG TYPE FOR FIELD
@BOX 6.0
DOES IT EXIST?
@BOX 7.0
FURTHER ALTERNATIVE?
@BOX 8.0
RETURN -1
@BOX 9.0
RETURN -2
@BOX 10.0
IF THE COMP
LEVEL IS NOW LOWER
(I.E. N>=0) ALLOCATE A
COMP.STACK ENTRY
@BOX 11.0
PUT INFORMATION
FOR CUR.COMP
ON COMP.STACK
@BOX 12.0
RETURN TL.TYPE.NAME
@BOX 13.0
END
@BOX 1.1
PROC TL.SEL.FLD(N);
ADDR FENTRY FLD.P;
$IN I,NO,SF.FLAG,PTR;
SELECT COMP.STACK[CUR.COMP];
@BOX 2.1
IF N >= 0,
@BOX 3.1
CS.FIELD => PTR;
0-N =>NO;
@BOX 4.1
2-TYPECONV(CS.TYPE) =>PTR;
N => NO;
@BOX 5.1
0 => SF.FLAG;
WHILE NO > 0 AND
PV^[PTR+1] ->> FLAGSHIFT => SF.FLAG = 0 DO
(IF PV^[PTR+TYPEPOS] < 0 THEN 1 ELSE 0)+FLDSIZE +> PTR;
1 -> NO OD;
@BOX 6.1
IF NO /= 0,
@BOX 7.1
IF SF.FLAG = 2,
@BOX 8.1
-1 => TL.SEL.FLD;
@BOX 9.1
-2=> TL.SEL.FLD;
@BOX 10.1
IF N >= 0 THEN 1 +> CUR.COMP FI;
@BOX 11.1
BEGIN;
SELECT COMP.STACK[CUR.COMP];
PTR => CS.FIELD;
-1 => CS.CUR.EL;
MAKE(FENTRY,0,PTR+1*PVSIZ+DPV) => FLD.P;
SELECT FLD.P^;
CS.ADDR OF COMP.STACK[CUR.COMP-1] + F.DISP => CS.ADDR;
IF F.TYPE => CS.TYPE < 0 THEN
F.DIM => CS.DIM;
TSIZE(FTYPE) => CS.ELSIZE;
ELSE
-1 => CS.DIM => CS.ELSIZE FI;
@BOX 12.1
CS.TYPE => TL.SEL.FLD;
END;
@BOX 13.1
END;
@END
@TITLE MTL10.7.3(1,6)
@COL 1S-2R-3T-5T-6R-7R-8R-10F
@COL 4R-9R
@ROW 3-4
@ROW 8-9
@FLOW 1-2-3N-5N-6-7-8-10
@FLOW 3Y-4-5
@FLOW 5Y-9-10
@BOX 1.0
TL.SEL.EL(N)TL.SEL.EL
@BOX 2.0
INITIALIZE VARIABLES
@BOX 3.0
N < 0?
@BOX 4.0
GET REQUIRED ELEMENT.NO
@BOX 5.0
COMPARE ELEMENT.NO WITH DIMENSION OF VECTOR
DOES THIS ELEMENT NOT EXIST?
@BOX 6.0
IF THE LEVEL OF THE COMP IS NOW LOWER
(I.E. N>=0) ALLOCATE A COMP.STACK ENTRY
@BOX 7.0
PUT INFORMATION FOR CUR.COMP ON STACK
@BOX 8.0
RETURN TL.SEL.EL
@BOX 9.0
RETURN -1
@BOX 10.0
END
@BOX 1.1
PROC TL.SEL.EL(N);
@BOX 2.1
$IN EL.NO;
N => EL.NO;
@BOX 3.1
IF N < 0,
@BOX 4.1
CS.CUR.EL OF COMP.STACK[CUR.COMP] -N => EL.NO;
@BOX 5.1
IF EL.NO>=CS.DIM OF COMP.STACK[CUR.COMP],
@BOX 6.1
IF N >= 0 THEN 1 +> CUR.COMP FI;
@BOX 7.1
SELECT COMP.STACK[CUR.COMP];
EL.NO => CS.CUR.EL;
-1  => CS.ELSIZE;
CS.FIELD OF COMP.STACK[CUR.COMP-1] => CS.FIELD;
CS.DIM OF COMP.STACK[CUR.COMP-1] => CS.DIM;
CS.CUR.EL *CS.ELSIZE OF COMP.STACK[CUR.COMP-1]
+ CS.ADDR OF COMP.STACK[CUR.COMP-1] => CS.ADDR;
CS.TYPE OF COMP.STACK[CUR.COMP-1] & TYPEMASK1 => CS.TYPE;
@BOX 8.1
CS.TYPE => TL.SEL.EL;
@BOX 9.1
-1 => TL.SEL.EL;
@BOX 10.1
END;
@END
@TITLE MTL10.7.4(1,6)
@COL 1S-2T-3R-5R-6T-7R-8R-9R-11F
@COL 4R-10R
@ROW 3-4
@ROW 9-10
@FLOW 1-2N-3-5-6N-7-8-9-11
@FLOW 2Y-4-5
@FLOW 6Y-10-11
@BOX 1.0
TL.SEL.ALT(N)TL.TYPE.NAME
@BOX 2.0
N < 0?
@BOX 3.0
GET FIRST FIELD OF TYPE
OF CUR.COMP
@BOX 4.0
GET CUR.COMP FIELD ENTRY
@BOX 5.0
SEARCH ALONG TYPE FOR THIS ALTERNATIVE
@BOX 6.0
DOES IT NOT EXIST?
@BOX 7.0
IF LEVEL OF COMP IS NOW LOWER
(I.E.N>=0) ALLOCATE COMP.STACK ENTRY
@BOX 8.0
PUT INFORMATION FOR CUR.COMP
ON COMP.STACK
@BOX 9.0
RETURN TL.TYPE.NAME
@BOX 10.0
RETURN -1
@BOX 11.0
END
@BOX 1.1
PROC TL.SEL.ALT(N);
ADDR FENTRY FLD.P;
$IN NO,SF.FLAG,PTR;
SELECT COMP.STACK[CUR.COMP];
@BOX 2.1
IF N < 0,
@BOX 3.1
2-TYPE.CONV(CS.TYPE) =>PTR;
N=>NO;
@BOX 4.1
0-N => NO;
CS.FIELD => PTR;
@BOX 5.1
0 => SF.FLAG;
WHILE NO > 0 DO
PV^[PTR+1] ->> FLAGSHIFT => SF.FLAG;
(IF PV^[PTR+TYPEPOS] < 0 THEN 1 ELSE 0) +FLDSIZE +> PTR;
IF SF.FLAG = 1 THEN
-1 => NO ELSE
IF SF.FLAG = 2 THEN
1 -> NO FI FI OD;
@BOX 6.1
IF NO /= 0,
@BOX 7.1
IF N >= 0 THEN
1 +> CUR.COMP FI;
@BOX 8.1
BEGIN;
SELECT COMP.STACK[CUR.COMP];
PTR => CS.FIELD;
-1 => CS.CUR.EL;
MAKE(FENTRY,0,PTR+1*PVSIZ+DPV) => FLD.P;
SELECT FLD.P^;
CS.ADDR OF COMP.STACK[CUR.COMP-1] + F.DISP => CS.ADDR;
IF FTYPE => CS.TYPE < 0 THEN
F.DIM => CS.DIM;
TSIZE(FTYPE) => CS.ELSIZE;
ELSE
-1 => CS.DIM => CS.ELSIZE FI;
@BOX 9.1
CS.TYPE => TL.SEL.ALT;
END;
@BOX 10.1
-1 => TL.SEL.ALT;
@BOX 11.1
END;
@END
@TITLE MTL10.7.5(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.UP
@BOX 2.0
RESET CUR.COMP
@BOX 3.0
END
@BOX 1.1
PROC TL.UP;
@BOX 2.1
1 -> CUR.COMP;
@BOX 3.1
END;
@END
@TITLE MTL10.7.6(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.YIELD.DIMENSION()DIMENSION
@BOX 2.0
RETURN DIMENSION(FROM CUR.COMP
ENTRY ON COMP.STACK)
@BOX 3.0
END
@BOX 1.1
PROC TL.YIELD.DIMENSION;
@BOX 2.1
CS.DIM OF COMP.STACK[CUR.COMP] => TL.YIELD.DIMENSION;
@BOX 3.1
END;
@END
@TITLE MTL10.7.7(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.YIELD.VAR.REF()VAR.REF
@BOX 2.0
RETURN VAR.REF(FROM CUR.COMP
ENTRY ON COMP.STACK)
@BOX 3.0
END
@BOX 1.1
PROC TL.YIELD.VAR.REF;
@BOX 2.1
ACCESS(CS.ADDR OF COMP.STACK[CUR.COMP],4) => TL.YIELD.VAR.REF;
@BOX 3.1
END;
@END
@TITLE MTL10.7.8(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.YIELD.VEC.REF()VEC.REF
@BOX 2.0
RETURN VEC.REF(FROM CUR.COMP
ENTRY ON COMP.STACK)
@BOX 3.0
END
@BOX 1.1
PROC TL.YIELD.VEC.REF;
@BOX 2.1
ACCESS(CS.ADDR OF COMP.STACK[CUR.COMP],8) => TL.YIELD.VEC.REF;
@BOX 3.1
END;
@END
@TITLE MTL10.7.9(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.SEL.DYN.VAR(VAR.REF,TL.TYPE.NAME)
@BOX 2.0
INITIALIZE CUR.COMP TO ZERO
PUT VARIABLE ON COMP.STACK
@BOX 3.0
END
@BOX 1.1
PROC TL.SEL.DYN.VAR(VAR.REF,TL.TYPE.NAME);
@BOX 2.1
SELECT COMP.STACK[1+>CUR.COMP];
-1 => CS.CUR.EL => CS.DIM => CS.ELSIZE;
-2 => CS.FIELD;
VAR.REF ->> SHIFT.MCADDR.TO.BYTE  => CS.ADDR;
TL.TYPE.NAME & TYPEMASK2 => CS.TYPE => TL.SEL.DYN.VAR;
@BOX 3.1
END;
@END
@TITLE MTL10.7.10(1,8)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.SEL.DYN.VEC(VEC.REF,TL.TYPE.NAME);
@BOX 2.0
PUT VECTOR ON TOP OF COMP.STACK
@BOX 3.0
END
@BOX 1.1
PROC TL.SEL.DYN.VEC(VEC.REF,TL.TYPE.NAME);
$IN T;
@BOX 2.1
SELECT COMP.STACK [1 +> CUR.COMP];
-1 => CS.CUR.EL;
-2 => CS.FIELD;
VEC.REF & %F(8) ->> SHIFT.MCADDR.TO.BYTE => CS.ADDR;  ::RATHER MC DEPENDENT
VEC.REF ->> 32 & %F(6) => CS.DIM;
IF TYPECONV(TL.TYPE.NAME => CS.TYPE) => T < 0 THEN
PV^[1-T] => CS.ELSIZE
ELSE CS.TYPE ->>2 & %F +1 => CS.ELSIZE FI;
CS.TYPE & TYPEMASK2 ! %80(3) => CS.TYPE => TL.SEL.DYN.VEC;
@BOX 3.1
END;
@END
@TITLE MTL10.8.1(1,6)
@COL 1S-2T-3R-8T-4T-5R-7F
@COL 6R
@ROW 5-6
@FLOW 1-2N-3-8N-4N-5-7
@FLOW 8Y-6
@FLOW 2Y-4
@FLOW 4Y-6-7
@BOX 1.0
TL.PRINT.NAME(TL.NAME)PRINT.WIDTH
@BOX 2.0
IS TL.NAME NOT 0?
@BOX 3.0
FIND NAME
@BOX 4.0
NIL NAME?
@BOX 5.0
PRINT OUT NAME
RETURN PRINT.WITDTH
@BOX 6.0
PRINT <NO.NAME>
RETURN PRINT.WIDTH OF 9
@BOX 7.0
END
@BOX 8.0
NO NAME?
@BOX 1.1
PROC TL.PRINT.NAME(TL.NAME);
$IN I,T,N;
0 => N;
@BOX 2.1
IF TL.NAME /= 0,
@BOX 3.1
CS.FIELD OF COMP.STACK[CUR.COMP] => TL.NAME;
CUR.COMP => T;
WHILE TL.NAME=-2 AND 1->T>=0 DO
CS.FIELD OF COMP.STACK[T] => TL.NAME;
1 => N OD;
@BOX 4.1
IF PV^[TL.NAME] => T < 2,
@BOX 5.1
FOR I < SV^[T] DO
OUTCH(SV^[T+1+I]) OD;
FOR N DO OUTCH('^) OD;
SV^[T] + N => TL.PRINT.NAME;
@BOX 6.1
ALTERNATIVE T FROM
CAPTION (%"<NO.NAME>");
CAPTION(%"<EXPORTS>") END;
9 => TL.PRINT.NAME;
@BOX 7.1
END;
@BOX 8.1
IF TL.NAME = -1,
@END
@TITLE MTL10.8.2(1,6)
@COL 1S-2R-4T-5T-6T-7T-15T-16R-17N
@COL 10R-11R-12R-13R-8R-18N
@COL 14F
@ROW 5-10
@ROW 6-11
@ROW 7-12
@ROW 15-13
@ROW 16-8
@ROW 17-18-14
@FLOW 1-2-4N-5N-6N-7N-15N-16-14
@FLOW 4Y-10-14
@FLOW 5Y-11-14
@FLOW 6Y-12-14
@FLOW 7Y-13-14
@FLOW 15Y-8-14
@BOX 1.0
TL.PRINT.VALUE()PRINT.WIDTH
@BOX 2.0
DECLARE TWO 64-BIT VARIABLES
GET THE TYPE AND ADDRESS OF THE CUR.COMP
FROM THE TYPE GET THE MODE AND SIZE
PUT VALUE INTO V1
@BOX 4.0
REAL MODE?
@BOX 5.0
SIZE > 32-BIT?
@BOX 6.0
32-BIT INTEGER MODE?
@BOX 7.0
SIZE > 8-BIT?
@BOX 8.0
PRINT AS CHARACTER AND
PAIR OF HEX DIGITS
RETURN PRINT.WIDTH OF 4
@BOX 10.0
PRINT V1 AS REAL NUMBER
RETURN PRINT.WIDTH OF 16
@BOX 11.0
PRINT AS 2 32-BIT HEX NOS
RETURN PRINT.WIDTH OF 16
@BOX 12.0
PRINT AS INTEGER
RETURN PRINT.WIDTH
@BOX 13.0
PRINT AS 32-BIT HEX NO
RETURN PRINT.WIDTH OF 8
@BOX 14.0
END
@BOX 15.0
LO8?
@BOX 16.0
PRINT LO1
@BOX 1.1
PROC TL.PRINT.VALUE;
DATAVEC CHS($LO8)
"0123456789ABCDEF"
END;
@BOX 2.1
$LO32 LO32;
SELECT COMP.STACK[CUR.COMP];
$IN VMODE,VSIZE;
$LO64 V1;
TSIZE(CSTYPE) => VSIZE;
IF CSTYPE &3 =0 THEN CSTYPE ->>6 &3=>VMODE
ELSE 2 => VMODE FI;
IF VSIZE > 8 THEN
8 => VSIZE FI;
ACCESS(CS.ADDR,VSIZE) => V1;
@BOX 4.1
IF VMODE = 0,
@BOX 5.1
IF VSIZE > 4,
@BOX 6.1
IF VSIZE = 4 AND VMODE = 1,
@BOX 7.1
IF VSIZE > 1,
@BOX 8.1
OUTCH('%);
V1=>LO32;
OUTCH(CHS[LO32->>4]);
OUTCH(CHS[LO32&%F]);
3=> TL.PRINT.VALUE;
@BOX 10.1
OUTREAL(V1,10,0);
10 => TL.PRINT.VALUE;
@BOX 11.1
OUTHEX(V1 ->> 32,8);
OUTHEX(V1 & %F(8),8);
16 => TL.PRINT.VALUE;
@BOX 12.1
OUTI(V1=>LO32=>VSIZE,11);
12 => TL.PRINT.VALUE;
@BOX 13.1
OUTHEX(V1,8);
8 => TL.PRINT.VALUE;
@BOX 14.1
END;
@BOX 15.1
IF VSIZE > 0,
@BOX 16.1
CAPTION(%"LO1?");
4 => TL.PRINT.VALUE;
@END
@TITLE MTL10.8.3(1,6)
@COL 1S-2T-3R-4R-5F
@FLOW 1-2N-3-4-5
@FLOW 2Y-4
@BOX 1.0
TL.YIELD.NAME(TL.NAME)[SYMB.NAME]
@BOX 2.0
IS TL.NAME NOT ZERO?
@BOX 3.0
GET POINTER TO FIELD FROM TOP OF COMP.STACK
@BOX 4.0
RETURN BOUNDED POINTER TO NAME
@BOX 5.0
END
@BOX 1.1
PROC TL.YIELD.NAME(TL.NAME);
$IN T;
@BOX 2.1
IF TL.NAME /= 0,
@BOX 3.1
CS.FIELD OF COMP.STACK[CUR.COMP] => TL.NAME;
@BOX 4.1
PV^[TL.NAME] => T;
PART(SV,T+1,T+SV^[T]) => TL.YIELD.NAME;
@BOX 5.1
END;
@END
@TITLE MTL10.9.1(1,6)
@COL 1S-2R-3R-6T-4T-26R-12R
@COL 18R-16F
@ROW 4-18
@FLOW 1-2-3-6Y-18-16
@FLOW 6N-4N-26-3
@FLOW 4Y-12-3
@BOX 1.0
PROC TL.YIELD.VALUE
@BOX 2.0
DECLARATIONS
@BOX 3.0
TYPE INSTRUCTIONS
@BOX 4.0
VARIABLE NOT EXIST?
@BOX 6.0
TERMINATOR
@BOX 12.0
TYPE IGNORE MESSAGE
@BOX 16.0
END
@BOX 18.0
INPUT CHAR
CHECK FOR ** COMMAND
@BOX 26.0
SELECT VARIABLE
@BOX 1.1
PROC TL.YIELD.VALUE;
@BOX 2.1
$IN TL.NAME,CH,VECPTR;
@BOX 3.1
NEXT>:WHILE NEXTCH() /= %A DO INCH() OD;
CAPTION(%"$LTYPE VAR NAME,**COMMAND OR *$L");
WHILE NEXTCH()=>CH ='$L OR CH=" " DO INCH() OD;
@BOX 4.1
IF TL.FIND.VAR(INBSTR()) => TL.NAME = -1,
@BOX 6.1
IF NEXTCH() = %2A,
@BOX 12.1
CAPTION(%" VAR NOT FOUND ");
@BOX 16.1
END;
@BOX 18.1
INCH();
IF NEXTCH() = %2A THEN
INCH();
PPCCMD();
-> NEXT FI;
@BOX 26.1
PSPEC VPRINT($IN)/$IN;
#MTL10.9.2
TL.SEL.VAR(TL.NAME);
IF VALIDATE() < 0 THEN -> NEXT FI;
FOR VECPTR < 48 DO
-2 => VEC[VECPTR] OD;
-1 => VECPTR;
VPRINT(-2);
@END

@TITLE MTL10.9.2(1,6)
@COL 1S-2R-8T-9T-10T-6R-7F
@COL 3R-4R-5R-11N
@COL 13N-14N
@ROW 7-11-14
@ROW 2-3
@ROW 10-4
@ROW 6-5-13
@FLOW 1-2-8N-3-13-14-11-7
@FLOW 8Y-9N-4-13
@FLOW 9Y-10N-5-11
@FLOW 10Y-6-7
@BOX 1.0
PROC V.PRINT
@BOX 2.0
DECLARATIONS
@BOX 3.0
DEREFERENCE IF
NEXT CHAR ^
@BOX 4.0
ELEMENTS REQUIRED
[] ALL ELEMENTS
[n] ELEMENT n
@BOX 5.0
AGGREGATE TYPE-
GET FIELD OR @ FOR ALL
@BOX 6.0
RESET VALUE IF NEXT CHAR /
PRINT OUT VALUE
@BOX 7.0
END
@BOX 8.0
NOT POINTER?
@BOX 9.0
NOT VECTOR?
@BOX 10.0
BASIC TYPE?
@BOX 1.1
PROC V.PRINT(P1);
@BOX 2.1
SELECT COMP.STACK[CUR.COMP];
$IN T,CH,I,J,K;
@BOX 3.1
IF P1 = -1 OR VEC[P1*3+2] = -1,->L1;
IF P1 = -2 THEN
1 +> VECPTR => P1;
IF NEXTCH() = '^ THEN
INCH();
1 => VEC[P1*3+2] ELSE
-1 => P1 FI FI;
IF P1 > -1 AND VEC[P1*3+2] = 1 THEN
IF T = 1 THEN
TL.SEL.DYN.VAR(TL.YIELD.VAR.REF(),CS.TYPE);
ELSE
TL.SEL.DYN.VEC(TL.YIELD.VEC.REF(),CS.TYPE)
FI;
V.PRINT(-2)=>P1;
ELSE VPRINT(-1) => P1;
FI;
@BOX 4.1
IF P1 = -2 THEN
1 +> VECPTR => P1;
IF INCH() => CH = '( OR CH = '[ THEN
IF NEXTCH() => CH = ') OR CH = '] THEN
-1 => VEC[P1*3+1];
ELSE
INI() => VEC[P1*3+1] FI;
INCH();
ELSE CAPTION(%"$LERROR,LAST CHAR=");
IN.BACKSPACE(1);
OUTCH(INCH());
-> NEXT FI FI;
IF P1 = -1 OR VEC[P1*3+1] = -1 THEN
NEWLINES(0);
TL.SEL.EL(0);
V.PRINT(VEC[P1+1*3] => J)=>J;
FOR SHORTCUT()-1 DO
TL.SEL.EL(-1);
V.PRINT(J) OD;
ELSE
TL.SEL.EL(VEC[P1*3+1]);
V.PRINT(VEC[P1+1*3])=> J
FI;
TL.UP();
@BOX 5.1
IF P1 = -2 THEN -2 => J;
1 +> VECPTR => P1;
IF NEXTCH() = '@ THEN
INCH();
-1 => VEC[P1*3] => VEC[P1*3+1] => VEC[P1*3+2];
ELSE
FINDFNAME(INBSTR()) => VEC[P1*3];
IF NEXTCH() = '^ THEN
INCH();
1 => VEC[VECPTR*3+2] FI;
IF NEXTCH() => CH = '[ OR CH = '( THEN
INCH();
IF NEXTCH() => CH = '] OR CH = ') THEN
-1 => VEC[VECPTR*3+1] ELSE
INI() => VEC[VECPTR*3+1] FI;
INCH() FI;
FI FI;
IF P1 = -1 OR VEC[P1*3] = -1 THEN
-1 => I;
WHILE TL.SEL.ALT(1+>I) /= -1 DO
NEWLINES(0);
TL.PRINT.NAME(0);
VPRINT(-1) => J;
WHILE TL.SEL.FLD(-1) /= -1 /= -2 DO
SPACES(1);
TL.PRINT.NAME(0);
VPRINT(-1) => J OD;
TL.UP() OD;
ELSE
VEC[VECPTR*3] => K;
TL.SEL.ALT(K/100);
IF K/100 * 100 -K=> K < 0 THEN
TL.SEL.FLD(K) FI;
VPRINT(P1);
TL.UP();
FI;
@BOX 6.1
L1:WHILE NEXTCH() = %20 DO INCH() OD;
IF NEXTCH() => CH = '/ THEN
INCH();
TL.SET.VALUE(CSTYPE,CSADDR)
ELSE
IF NEXTCH() = '* THEN INCH() FI FI;
SPACES(1);
TL.PRINT.VALUE();
@BOX 7.1
P1 => VPRINT;
END;
@BOX 8.1
IF CS.TYPE&3 =>T /=0,
@BOX 9.1
IF CS.TYPE < 0,
@BOX 10.1
IF TYPECONV(CS.TYPE) <0,
@END

@TITLE MTL10.9.3(1,6)
@COL 1S-2R-13R-25R-27C-28R-29R-30R-31R-40F
@FLOW 1-2-13-25-27
@BOX 1.0
PROC TL.SET.VALUE(VTYPE,VADDR)
@BOX 2.0
DECLARATIONS
@BOX 13.0
ASK FOR NEW VALUE
@BOX 25.0
RESET VALUE
@BOX 27.0
SWITCH ON MODE
@BOX 28.0
REAL
@BOX 29.0
INTEGER
@BOX 30.0
LOGICAL
@BOX 31.0
DECIMAL
@BOX 40.0
END
@BOX 1.1
PROC TL.SET.VALUE(VTYPE,VADDR);
@BOX 2.1
$IN I,P,VMODE,VSIZE;
IF VALIDATE() < 0 ,-> E;
@BOX 13.1
TSIZE(VTYPE) => VSIZE;
IF VTYPE &3 =0 THEN VTYPE ->>6 &3=>VMODE
 ELSE 2 => VMODE FI;
@BOX 25.1
REALADDR(VADDR) =>P;
@BOX 27.1
SWITCH VMODE\
M0,M1,M2,M3;
@BOX 28.1
M0:IF VSIZE>8 THEN 8 =>VSIZE FI;
-> E;
@BOX 29.1
M1:WRITE(P,INI(),VSIZE);
-> E;
@BOX 30.1
M2:IF NEXTCH()='% THEN INCH() FI;
IF VSIZE=1 THEN
WRITE(P,INCH(),1) ELSE
WRITE(P,INHEX(),VSIZE) FI;
-> E;
@BOX 31.1
M3:
@BOX 40.1
E:END;
@END

@TITLE MTL10.10.1(1,6)
@COL 1S-2R-3R-4T-5R-6T-7R-9F
@COL 8R
@ROW 7-8
@FLOW 1-2-3-4N-5-6N-7-9
@FLOW 4Y-7
@FLOW 6Y-8-9
@BOX 1.0
PROC TL.GO(P,L)
@BOX 2.0
DECLARATIONS
@BOX 3.0
GET NB FOR RETURN
@BOX 4.0
P < 1?
@BOX 5.0
SEARCH LINE.TABLE
FOR P.L IN CURRENT PROC
@BOX 6.0
NOT FOUND?
@BOX 7.0
RESTART PROG AT P.L
@BOX 8.0
ERROR MESSAGE
@BOX 9.0
END
@BOX 1.1
PROC TL.GO(P);
@BOX 2.1
$IN F,I,J,J1,K,T,L;
ADDR $LO16 RETURN;
@BOX 3.1
P & %FFFF => L;
IF P->>16 =>P =0 THEN
LT^[CUR.LT.PAGE+1] => P FI;
TL.NEXT.PROC(-1) & %FFFF => I;
@BOX 4.1
IF L=0,
@BOX 5.1
LOOK: -1 => F;
CUR.LT.PAGE => K;
CUR.LT.PROC => J;
WHILE F < 0 AND LT^[2+>J] => T /= %FFFA DO
LT^[J+1] => J1;
IF LT^[K+1] = P THEN
IF T = %FFFC AND J1 =< CUR.LT.PROC THEN
0 => F
ELSE
IF J1 = L THEN
J => CUR.LT.LINE;
K => CUR.LT.PAGE;
1 => F FI FI
ELSE
IF T = %FFFF AND J1 = P THEN
J => K FI FI OD;
@BOX 6.1
IF F < 1,
@BOX 7.1
TL.SET.TRAPS();
WRITE(I+16,LT^[CUR.LT.LINE],2);
SETNB(I->>NAMESHIFT);
@BOX 8.1
1 =>NOPRINT;
IF TL.NEXT.PROC(0) > 0,->LOOK;
0 =>NOPRINT;
CAPTION(%"$LLINE NOT FOUND");
@BOX 9.1
END;
@END
@TITLE MTL10.10.2(1,6)
@COL 1S-2R-3R-4R-6R-7R-9R-10R-11R-12R-13F
@FLOW 1-2-3-4-6-7-9-10-11-12-13
@BOX 1.0
PROC TL.INSERT.BREAKPOINT
@BOX 2.0
DECLARATIONS
@BOX 3.0
INVALID LINE TYPED IN?
@BOX 4.0
FIND EMPTY LOCATION IN BPT
@BOX 6.0
BPT FULL?
@BOX 7.0
INSERT ENTRY INTO BPT
@BOX 9.0
@BOX 10.0
MOVE CODE INTO BPT ARRAY
@BOX 11.0
@BOX 12.0
INSERT BREAKPOINT CALL
@BOX 13.0
END
@BOX 1.1
PROC TL.INSERT.BREAKPOINT;
@BOX 2.1
$IN I,T,T2,JMP,OLD,BP.LT.LINE;
@BOX 3.1
IF FINDLINE() => BP.LT.LINE = -1,->E;
@BOX 4.1
LT^[BP.LT.LINE] => T;
-1 => I;
WHILE 1 +>I <10 AND CA OF BPT[I] /=-1 /=CUR.PCS<<-SEGSHIFT+T DO OD;
@BOX 6.1
IF I = 10 THEN
CAPTION(%"$LTOO MANY BREAKPOINTS");
->E FI;
@BOX 7.1
SELECT BPT[I];
IF NEXTCH() = '$L THEN
0 => MAX ELSE
INI() => MAX FI;
IF CA = -1 THEN
CUR.PCS<<-SEGSHIFT+T => CA;
ELSE ->E FI;
@BOX 9.1
CHANGE.ACCESS(CUR.PCS,%1E);
@BOX 10.1
ACCESS(CA,1) =>CODE;
WRITE(CA,%03,1);
@BOX 11.1
@BOX 12.1
CHANGE.ACCESS(CUR.PCS,%1D);
@BOX 13.1
E:END;
@END


@TITLE MTL10.10.3(1,6)
@COL 1S-2R-3R-4R-6T-5R-7R-9R-10F
@COL 8R
@ROW 5-8
@FLOW 1-2-3-4-6N-5-7-9-10
@FLOW 6Y-8-7
@BOX 1.0
PROC TL.REMOVE.BREAKPOINT
@BOX 2.0
DECLARATIONS
@BOX 3.0
INVALID LINE TYPED IN?
@BOX 4.0
LOOK IN BPT ARRAY FOR BREAKPOINT
@BOX 5.0
SELECT BPT ELEMENTS
@BOX 6.0
NOT IN BPT?
@BOX 7.0
MOVE ORIGINAL CODE BACK
@BOX 8.0
ERROR
@BOX 9.0
DELETE ENTRY IN BPT ARRAY
@BOX 10.0
END
@BOX 1.1
PROC TL.REMOVE.BREAKPOINT;
@BOX 2.1
$IN T,I,OLD,REPLACE,BP.LT.LINE;
@BOX 3.1
IF FINDLINE() => BP.LT.LINE = -1,->E;
@BOX 4.1
LT^[BP.LT.LINE] => T;
-1 => I;
WHILE 1+>I<10 AND CUR.PCS<<-SEGSHIFT+T=>REPLACE /=CA OF BPT[I] DO OD;
@BOX 5.1
SELECT BPT[I];
CODE =>OLD;
-1 =>CA=>CUR;
@BOX 6.1
IF I = 10,
@BOX 7.1
CHANGE.ACCESS(CUR.PCS,%1E);
WRITE(REPLACE,OLD,1);
CHANGE.ACCESS(CUR.PCS,%1D);
@BOX 8.1
IF ACCESS(REPLACE,1) /=%03 THEN
CAPTION(%" NO BREAKPOINT HERE ");
->E;
ELSE %01 =>OLD FI;
@BOX 9.1
@BOX 10.1
E:END;
@END

@TITLE MTL10.11.1(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROC TL.TRACE(TMODE)
@BOX 2.0
SET TRACE VARIABLE
@BOX 3.0
END
@BOX 1.1
PROC TL.TRACE(P1);
@BOX 2.1
$IN T;
P1 ->>8 => T & P1 ! (T -= %FF & TRACE) => TRACE;
@BOX 3.1
END;
@END

@TITLE MTL10.11.3(1,6)
@COL 1S-2R-3T-4R-5R-6R-7F
@FLOW 1-2-3N-4-5-6-7
@FLOW 3Y-7
@BOX 1.0
PROC TL.TRACE.R
@BOX 2.0
DECLARATIONS
@BOX 3.0
TRACE NOT REQUIRED OR LINE NOT IN LINETABLE?
@BOX 4.0
TRACE LINE
@BOX 5.0
TRACE BOX
@BOX 6.0
TRACE PROC
@BOX 7.0
END
@BOX 1.1
PROC TL.TRACE.R;
@BOX 2.1
$IN T,LINE,BOX,PROC.NAME;
@BOX 3.1
IF TRACE&7 = 0 OR SEARCH.LT(FAULT.PC)=-1,
@BOX 4.1
#MTL10.11.4
@BOX 5.1
#MTL10.11.6
@BOX 6.1
#MTL10.11.5
@BOX 7.1
END;
@END

@TITLE MTL10.11.4(1,6)
@COL 1A-3T-4T-5R-6T-7R-8T-9R-10F
@FLOW 1-3N-4N-5-6N-7-8N-9-10
@FLOW 3Y-10
@FLOW 4Y-6Y-8Y-10
@BOX 3.0
TRACE LINES?
@BOX 4.0
TRACE OFF?
@BOX 5.0
OUTPUT LINE
@BOX 6.0
PROFILE OFF?
@BOX 7.0
INCREMENT LINE'S PROFILE
@BOX 8.0
STORED TRACE OFF?
@BOX 9.0
ADD TO STORED TRACE LIST
@BOX 3.1
IF TRACE & %20 = 0,
@BOX 4.1
TL.YIELD.LINE() => LINE;
IF TRACE &1 = 0,
@BOX 5.1
NEWLINES(0);
OUTLINENO(LINE);
@BOX 6.1
IF TRACE &4 = 0,
@BOX 7.1
-1 => T;
WHILE 1+> T < LSIZE AND L OF PROFILE.L[T] /= LINE /= -1 DO OD;
IF T = LSIZE AND LFLAG=0 THEN
CAPTION(%"$L??PROFILE.L OFLO??");
1 => LFLAG ELSE
LINE => L OF PROFILE.L[T];
1 +> N OF PROFILE.L[T] FI;
@BOX 8.1
IF TRACE &2 = 0,
@BOX 9.1
IF 1 +> CNT.TL = 40 THEN
0 => CNT.TL FI;
LINE => TRACE.L[CNT.TL];
@BOX 10.1
@END

@TITLE MTL10.11.5(1,6)
@COL 1A-3T-4T-5R-6T-7R-8T-9R-10F
@FLOW 1-3N-4N-5-6N-7-8N-9-10
@FLOW 3Y-10
@FLOW 4Y-6Y-8Y-10
@BOX 3.0
NO PROC CHANGE?
@BOX 4.0
TRACE OFF?
@BOX 5.0
OUTPUT PROC NAME
@BOX 6.0
PROFILE OFF?
@BOX 7.0
INCREMENT PROC'S PROFILE
@BOX 8.0
STORED TRACE OFF?
@BOX 9.0
ADD PROC INTO STORED TRACE
@BOX 3.1
IF TRACE &8 =0 OR TL.YIELD.PROC()=>PROC.NAME =LAST.PROC,
@BOX 4.1
PROC.NAME=>LAST.PROC;
IF TRACE &1 = 0,
@BOX 5.1
NEWLINES(0);
TL.PRINT.NAME(PROC.NAME);
@BOX 6.1
IF TRACE &4 = 0,
@BOX 7.1
-1 => T;
WHILE 1 +> T < PSIZE AND L OF PROFILE.P[T] /= PROC.NAME /= -1 DO OD;
IF T = PSIZE AND PFLAG=0 THEN
CAPTION(%"$L??PROFILE.P OFLO??");
1 => PFLAG ELSE
PROC.NAME => L OF PROFILE.P[T];
1 +> N OF PROFILE.P[T] FI;
@BOX 8.1
IF TRACE &2 = 0,
@BOX 9.1
IF 1 +> CNT.TP = 40 THEN
0 => CNT.TP FI;
PROC.NAME => TRACE.P[CNT.TP];
@BOX 10.1
@END

@TITLE MTL10.11.6(1,6)
@COL 1A-3T-4T-5R-6T-7R-8T-9R-10F
@FLOW 1-3N-4N-5-6N-7-8N-9-10
@FLOW 3Y-10
@FLOW 4Y-6Y-8Y-10
@BOX 3.0
NO BOX CHANGE?
@BOX 4.0
TRACE OFF?
@BOX 5.0
OUTPUT BOX
@BOX 6.0
PROFILE OFF?
@BOX 7.0
INCREMENT BOX'S PROFILE
@BOX 8.0
STORED TRACE OFF?
@BOX 9.0
ADD TO STORED TRACE LIST
@BOX 3.1
IF TRACE &%10 =0 OR LT^[CUR.LT.PAGE+1]<<-16 ! (LT^[CUR.LT.LINE+1] /100) => BOX =
 LASTBOX,
@BOX 4.1
BOX=>LASTBOX;
IF TRACE &1 = 0,
@BOX 5.1
CAPTION(%"$LBOX ");
OUTLINENO(BOX);
@BOX 6.1
IF TRACE &4 = 0,
@BOX 7.1
-1 => T;
WHILE 1+> T < BSIZE AND L OF PROFILE.B[T] /= BOX /= -1 DO OD;
IF T = BSIZE AND BFLAG=0 THEN
CAPTION(%"$L??PROFILE.B OFLO??");
1 => BFLAG ELSE
BOX => L OF PROFILE.B[T];
1 +> N OF PROFILE.B[T] FI;
@BOX 8.1
IF TRACE &2 = 0,
@BOX 9.1
IF 1 +> CNT.TB = 40 THEN
0 => CNT.TB;
FI;
BOX => TRACE.B[CNT.TB];
@BOX 10.1
@END

@TITLE MTL10.11.7(1,6)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
PROC TL.PRINT PROFILE
@BOX 2.0
DECLARATIONS
@BOX 3.0
PRINT LINE PROFILE
@BOX 4.0
PRINT PROC PROFILE
@BOX 5.0
PRINT BOX PROFILE
@BOX 6.0
END
@BOX 1.1
PROC TL.PRINT.PROFILE;
@BOX 2.1
$IN I,LAST;
@BOX 3.1
IF L OF PROFILE.L[0] >0 THEN
BEGIN
CAPTION(%"$LLINE PROFILE$L");
-1 => I => LAST;
WHILE 1 +> I < LSIZE AND L OF PROFILE.L[I] /= -1 DO
SELECT PROFILE.L[I];
IF N /= LAST THEN
NEWLINES(0);
OUTLINENO(L);
OUTI(N=>LAST,6);
FI OD END FI;
@BOX 4.1
IF L OF PROFILE.P[0] > -1 THEN
BEGIN
CAPTION(%"$LPROC PROFILE$L");
-1 => I;
WHILE 1 +> I < PSIZE AND L OF PROFILE.P[I] /= -1 DO
SELECT PROFILE.P[I];
NEWLINES(0);
TL.PRINT.NAME(L);
OUTI(N,6);
OD END FI;
@BOX 5.1
IF L OF PROFILE.B[0] > 0 THEN
BEGIN
CAPTION(%"$LFLOWCHART BOX PROFILE");
-1 => I;
WHILE 1+>I < BSIZE AND L OF PROFILE.B[I] /= -1 DO
SELECT PROFILE.B[I];
CAPTION(%"$LBOX ");
OUTLINENO(L);
OUTI(N,5);
OD END FI;
@BOX 6.1
END;
@END

@TITLE MTL10.11.8(1,6)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
PROC TL.PRINT.S.TRACE;
@BOX 2.0
DECLARATIONS
@BOX 3.0
PRINT LINE TRACEBACK
@BOX 4.0
PRINT PROC TRACEBACK
@BOX 5.0
PRINT BOX TRACEBACK
@BOX 6.0
END
@BOX 1.1
PROC TL.PRINT.S.TRACE;
@BOX 2.1
$IN I;
@BOX 3.1
CAPTION(%"$LLINE TRACEBACK$L");
FOR I < CNT.TL+1 DO
NEWLINES(0);
OUTLINENO(TRACE.L[CNT.TL-I]) OD;
IF TRACE.L[39] > 0 THEN
FOR I < 39-CNT.TL DO
NEWLINES(0);
OUTLINENO(TRACE.L[39-I]) OD FI;
@BOX 4.1
CAPTION(%"$LPROC TRACEBACK$L");
FOR I < CNT.TP+1 DO
NEWLINES(0);
TL.PRINT.NAME(TRACE.P[CNT.TP-I]) OD;
IF TRACE.P[39] > 0 THEN
FOR I < 39-CNT.TP DO
NEWLINES(0);
TL.PRINT.NAME(TRACE.P[39-I]) OD FI;
@BOX 5.1
CAPTION(%"$LFLOWCHART BOX TRACEBACK$L");
FOR I < CNT.TB+1 DO
NEWLINES(0);
OUTLINENO(TRACE.B[CNT.TB-I]) OD;
IF TRACE.B[39] > 0 THEN
FOR I <39-CNT.TB DO
NEWLINES(0);
OUTLINENO(TRACE.B[39-I]) OD FI;
@BOX 6.1
END;
@END


