This chapter describes how to use the major Pascal/MT+ programs contained on the distribution disk.
Before compiling and running the sample program described in this section, MAKE A BACKUP of all of the disks included with this software release.
The following is a step-by-step guide to the basic operation of the Pascal/MT+ system. You will create a system compiler disk, compile, link, and execute a sample program under the CP/M operating system. If you have problems with compilation or linking, read the rest of the manual for further help before calling or writing your distributor.
The following discussion assumes that the computer on which you are about to execute Pascal/MT+ has two 8-inch single density floppy disks. If you have other than this configuration, then make the appropriate adjustments. Please read all of the steps below before attempting to operate the software so you have an idea of what is being done.
The following 7 files are required to compile CALC.
MTPLUS.COM | Executable compiler | |
MTPLUS.000 | Root program | |
MTPLUS.001 | } | |
MTPLUS.002 | } | |
MTPLUS.003 | } | Overlays for the compiler |
MTPLUS.004 | } | |
MTPLUS.005 | } |
MTERRS.TXT is not mandatory but is useful.
It contains error messages.
The following four files are used to link CALC.ERL (generated by the compiler) to create an executable CALC.COM:
LINKMT.COM | Linker |
TRANCEND.ERL | Transcendental function module |
FPREALS.ERL | Floating point real library |
PASLIB.ERL | Pascal run time library |
Create another disk which contains LINKMT.COM, CALC.SRC, FPREALS.ERL, TRANCEND.ERL, and PASLIB.ERL. This contains all of the files necessary to link CALC.
MTPLUS B:CALC<cr>
CALC should compile free of syntax and semantic errors. If you get errors of this type you probably have a bad copy and should re-copy CALC from your masters and try again.
Depending on your memory and hardware configuration, you may get memory limitation errors or disk write errors. Memory limitation errors are either 'recursion stack overflow' or error 407 which is symbol table overflow. Section 2.2.5 describes what steps may be taken to alleviate these errors. If you get a disk write error in the first pass such as 'Error writing PASTEMP.TOK, disk probably full,' then use the $T command switch discussed in Section 2.2.2. You may get errors writing out CALC.ERL which means you need more space on your data disk.
Another type of error which may be encountered in this compilation is that the overlay manager cannot find a procedure in an overlay or cannot find an overlay. It will generate a '?' followed by the name of the procedure or overlay which is missing. If the overlay is missing, check that it is the correct name and is on-line. If a procedure is missing, the file which contains it is corrupt. See Section 2.2.5.
Pascal/MT+ Release V.xx (c) 1981 MT MicroSYSTEMS, Inc. CP/M-80 version +++++ {syntax / token file generation} Source lines: 109 V.xx Phase 1 Available Memory: nnnnn {total symbol table space} User Table Space: nnnnn {after predefined symbols} #### {one # for each routine body} Remaining Memory: nnnnn {after user symbols} V.xx Phase 2 8080 SUBREAL 18 ADDREAL 54 TF 88 {decimal offset from beginning} CALC 161 MENU 1096 CALCULAT Lines : 109 Errors: 0 Code : 2050 Data : 48 Pascal/MT+ V.xx Compilation Completed
B: CALC ERL
LINKMT CALC,TRANCEND,FPREALS,PASLIB/S
followed by the return key. The linker should find no errors in the .ERL files it is linking. If any errors such as 'Duplicate symbol found' or 'Undefined symbols' are listed, one or more of the .ERL files is bad. Recopy all of the files from the master and re-compile CALC and link again before contacting your distributor. If you have a disk write error you probably do not have enough room on the destination disk. You should see the following output:
LINK/MT+ V.xx Processing file- CALC .ERL Processing file- TRANCEND.ERL Processing file- FPREALS .ERL Processing file- PASLIB .ERL Undefined Symbols: No Undefined Symbols nnnn (decimal) records written to CALC .COM Total Data: nnnnH bytes Total Code: nnnnH bytes Remaining : nnnnH bytes Link/MT+ processing completed
B: CALC COMfrom CP/M.
'B:CALC' ENTER FIRST OPERAND? '5.5<CR>' R1= 5.5OOOOE+00 ENTER SECOND OPERAND? '99.256<CR>' R2= 9.92560E+01 ENTER OPERATOR S:SIN C:COS A:ARCTAN L:LN E:EXP 1:SQR $SQRT +, -, *, / ARITHMETIC OPERATORS M:NEGATE =:EQUAL N:NOT EQUAL <:LESS THAN >:GREATER THEN Z:LESS THAN OR EQUAL TO G:GREATER THAN OR EQUAL TO 4:TRUNC 5:ROUND ? '+' 104.756 TYPE <ESCAPE> TO STOP
The compiler is named MTPLUS.COM and uses a root program, MTPLUS.000, and five overlays plus the debugger overlay. Input files may be located on any disk and the names are standard CP/M names. Input files must have a carriage return, line feed, and control Z at the end. The filename is one to eight characters long and may be preceeded by a drive letter ('A'..'P', '@' for the logged-in disk). The filename may have any extension but if specified with a blank extension, e.g., TEST1, and not found with a blank extension then the compiler will search for a file with a .SRC extension followed by searching for a file with a .PAS extension. If no match is made, then an error message will be issued: 'Unable to open input file.' MTPLUS creates a relocatable file <name>.ERL which must be linked with LINK/MT+ to the routines in the runtime package.
To execute the Pascal/MT+ compiler type:
MTPLUS <filename> {optional parameters preceeded by $ or #}
For example, 'MTPLUS CALC' puts CALC.ERL to the default drive and 'MTPLUS CALC $RB' puts CALC.ERL on drive B:. See Section 2.3 for details regarding linking.
The compiler accepts a number of "option switches" following the name of the input file on the command line. These options switches are in the form of a string preceeded by a '$' (dollar sign) character or a '#' character and are single letters followed by zero or more parameter characters. The parameter string extends from the $ to the end of the line and spaces are ignored, i.e., $PXRB is the same as $PX RB. Listed below are the switches and their default values. The 'd' parameter indicates where the output file is routed. When 'd' is 'X' it is routed to the console, when 'd' is 'P' output is routed to the printer, and for 'd' equal to '@' or 'A'..'O' it is sent to a standard CP/M disk drive.
SWITCH | MEANING | DEFAULT |
---|---|---|
Rd | Put the .ERL file on 'd:' d=@,A..O |
Put .ERL with source |
Od | MTPLUS.000, the root program. and MTPLUS.001 through MTPLUS.006
are on drive 'd:' d=@,A..O |
Root and overlays on default disk. |
Pd | Put the .PRN (listing file) on disk 'd'. d= X,P,@,A..O | no .PRN file |
X | Generate an eXtended REL file including disassembler records | nonextended REL file generated |
D | Generate debugger information in the object code and write the .PSY file to the drive specified by the R option | no debugger information and no .PSY file are generated |
Ed | The MTERRS.TXT file is on 'd:' d= @,A..O |
MTERRS.TXT on default disk |
Td | Put the PASTEMP.TOK file on 'd:' d= @,A..O |
PASTEMP on default disk |
Q | Quiet, suppress any unnecessary console messages | Compiler is verbose |
C | Continue on error, default is to pause and let operator interact on each error, one at a time. | Compiler stops and asks on each error. |
A | Automatically call the linker at the end of compilation. A .CMD CMD file with the same name as the input program is required. Linker must be named 'LINKMT.COM'. | Compiler does not automatically chain |
B | Use BCD rather than floating point for the real numbers | Floating point reals |
Z | Generate Z80 optimized code | Generate only 8080 code |
V | Print the name of each procedure and function when found in source code as an aid to determining error locations during PHASE 0. | Each procedure name not printed |
@ | The '@' character is made equivalent to the '^' character. | '@' not equivalent to '^' |
An example which executes the compiler, reads the source from the A: drive, places the .ERL file on B:, the .PRN file on the console, and automatically calls the linker is as follows:
MTPLUS A:TESTPROG $RB PX A
The Pascal/MT+ compiler will periodically output characters during the first two phases of the compilation (Phase 0 and Phase 1) to keep the user happy knowing that the compiler has not gone off to meet its maker. See 2.1, the compilation of CALC, for sample compiler output.
A '+' is printed to the console for every 16 source-code lines syntax scanned during Phase 0. At the beginning of PHASE 1 the available memory space is displayed. This is the number of bytes (in decimal) of memory before generation of the symbol table. Approximately 4K bytes of symbol table space is consumed by predefined identifiers. See Section 2.2.4.11 on reducing this space by eliminating unneeded declarations of built-in routines. At the end of this phase, the User table space is displayed in decimal. This is the amount of memory left for user symbols and the compiler recursion stack after the compiler symbols are loaded. When a procedure or function is found a '#' is output to the console. At the completion of PHASE 1, the number of bytes remaining in memory is displayed in decimal.
PHASE 2 generates object code. When the body of each procedure is encountered, the name of the procedure is output so that the user can see where the compiler is in the compilation of the program. Following the name is the offset from the beginning of the module in decimal. This is output when the procedure/function body is actually encountered, e.g., if A contains B which contains C, then the output would be C followed by B followed by A. The linker /M (Map) option will list the absolute addresses of the procedures in each module. Upon encountering an error, the line will be displayed and if MTERRS is on-line, a description of the error is written at the bottom of the screen. If MTERRS is not on-line, just the error number is written. This number may be looked up in the appendix to determine the meaning of the error. See Section 2.2.5 for further information. Upon completion the following lines are displayed:
Lines : lines of source code compiled (in decimal) Errors: number of errors detected Code : bytes of code generated (in decimal) Data : bytes of data reserved (in decimal).
The compiler toggle signals the compiler that the user wishes to enable or disable certain options. The format of this toggle is (*$____*) or {$_______} where the blanks are filled in with the toggle. One toggle per comment is allowed, e.g. (*$E+*) is legal but (*$E+ $S+*) is not legal. The compiler does not accept blanks before the key letter or trailing or imbedded blanks in names but will skip over leading blanks, e.g., {$E +} is the same as {$E+}, but {$ E +} will be ignored.
EXAMPLES:
(*$E+*) {$P} {$I D:USERFILE.LIB}
$E controls the generation of entry point records in the relocatable file. $E+ causes the global variables and all procedures and functions to be available as entry points, i.e., available to be referenced by EXTERNAL declarations in other modules. $E- supresses the generation of these records, thus causing the variables, procedures, and functions to be logically private. The default state is $E+ and the toggle may be turned on and off at will.
$S+ enables stack frame allocation of procedure / function parameters and local variables. It's default is non-recursion. It must be used in modules and programs which contain recursive procedures or functions. This toggle must be turned on before the word PROGRAM or MODULE and cannot be turned off within a separately compiled unit. Global variables in either programs or modules are always allocated statically. Modules which use $S+ may be linked with modules which do not use $S+ into a single program.
$I<filename> causes the compiler to include the named file in the sequence of Pascal source statements. Filename specification includes drive name and extension in CP/M standard format. If the extension is not given, the extension from the main file is assumed. The file must have a carriage return, line feed, and control Z at the end of the file to be included properly into the input stream. Nested include statements (one included source file includes another source file) are not legal.
The $Z $nnnn toggle is used to initialize the stack pointer to nnnnH in non-CP/M environments. In a CP/M environment the hardware stack is initialized by loading the value in absolute location 0006 into the stack pointer register. If the $Z toggle is used, then generation of the CP/M type initialization is supressed. This toggle must be placed before the BEGIN line in the main program. It is not needed in separate modules, but only once in the main program.
$T+, $T-, $W+ and $W- control the strict type checking / non- portable warning facility. These features are tightly coupled, i.e., strict type checking implies warning non-portable usage and visa versa. The default state is $T- ($W-) in which type checking is relaxed and warning messages are not generated. If these checks are on and a nonportable feature is encountered during the compilation of the source, error message 500 is generated. Note that because the STRING data type is NOT standard, string operations will cause this error when the W / T switch is on.
This switch is designed to check for compatibility with the ISO Pascal standard. It does not check for all features listed in the appendix on portability because many of them are implementation dependent or are software routines.
This togle may be turned on and off throughout the source code as desired.
$R+ and $R- control the compiler's generation of run-time code which will perform range checking on array subscripting and storing into subrange variables. The default state is $R- (off) and this toggle may be turned on and off throughout the source code as desired. See Chapter 4 for further information.
Exception checking is performed on integer and real zero divide, string overflow, real number overflow and underflow. $X+ and $X- control the compiler's generation of run-time code which will perform run-time error checking and error handling. This switch is default ON, and in the current release, turning it off is ignored. The user is directed to Chapter 4 for more discussion of run-time error handling and options.
The $P and $L+, $L- toggles control the listing generated by the first pass of the compiler. $P will cause a formfeed character (CHR(12)) to be inserted into the .PRN file. $L+ and $L- are used to switch the listing on and off throughout the source program and may be placed wherever desired.
The $Cn toggle can be used by the user to reduce run-time object code memory requirements when using REAL arithmetic. The user can, if available, specify a restart instruction number and the compiler will then change all calls to the @XOP routine,the real utility load and store routine, into a restart instruction. This will cause all three byte call instructions to shrink to one byte call instructions. The user specifies 'n' in the range 0.7 and the compiler generates RST n instructions. In a CP/M environment, the restarts which are not available because of CP/M usage are 0 and 7. MP/M users and others should consult their hardware documentation for more details.
The $C toggle requires that the toggle be present in both the modules which use this feature and in the main program. It must be in the main program so that the compiler may generate code to load the restart vector and generate restart instructions for calls to @XOP. It must be in modules which use real numbers so the restart instruction is generated.
In a similar manner to the $Cn toggle, the $Qn toggle has been added to perform the same operation (short calls) with recursive modules. The letter n is in the range of 0.7. Every call to the @DYN routine used for loads and stores will be converted to a restart. For example, restart 5 will be used if (*$Q 5*) is specified.
The $Q toggle requires that the toggle be present in both the modules which use this feature and in the main program. It must be in the main program so that the compiler may generate code to load the restart vector and generate restart instructions for calls to @DYN. It must be in modules which use recursion so the restart instruction is generated.
The $Kn toggles are used to remove unreferenced built-in routine definitions from the symbol table to make more room for user symbols. Any reference to the removed symbols generates an 'undefined identifier' error message. They have nothing to do with what the linker loads. The value n (0..15) is used to control various groups of routines. These may be used in any combination but these toggles MUST appear before the word PROGRAM or MODULE to be effective. Only one $K toggle per comment is allowed. The value n is selected as follows:
GROUP | ROUTINES REMOVED |
---|---|
0 | ROUND, TRUNC, EXP, LN, ARCTAN, SQRT, COS, SIN |
1 | COPY, INSERT, P0S, DELETE, LENGTH, CONCAT |
2 | GNB, WNB, CLOSEDEL, OPENX, BLOCKREAD, BLOCKWRITE |
3 | CLOSE, OPEN, PURGE, CHAIN, CREATE |
4 | WRD, HI, LO, SWAP, ADDR, SIZEOF, INLINE, EXIT, PACK, UNPACK |
5 | IORESULT, PAGE, NEW, DISPOSE |
6 | SUCC, PRED, EOF, EOLN |
7 | TSTBIT, CLRBIT, SETBIT, SHR, SHL |
8 | RESET, REWRITE, GET, PUT, ASSIGN, MOVELEFT, MOVERIGHT, FILLCHAR |
9 | READ, READLN |
10 | WRITE, WRITELN |
11 | < unused > |
12 | MEMAVAIL, MAXAVAIL |
13 | SEEKREAD, SEEKWRITE |
14 | RIM85, SIM85, WAIT |
15 | READHEX, WRITEHEX |
COMPILER TOGGLES | DEFAULT | |
---|---|---|
$E +/- | Controls entry point generation | $E+ |
$S +/- | Controls recursive/static variables | $S- |
$I <name> | Includes another source file into the input stream, e.g., {$I XXX.LIB} | |
$R +/- | Controls range checking code | $R- |
$T +/- $W +/- |
Controls strict type checking and generation of warning messages | $T- |
$X +/- | Controls eXception checking code | $X- |
$P | Enter a formfeed in the .PRN file | |
$L +/- | Controls the listing of source code | $L+ |
$Kn | Allows for Killing built-in routines to save space in symbol table (n=0..7) | |
$Z $nnnn | Initialize hardware stack to nnnnH (default is contents of location 0006 at the begining of execution) | |
$Cn | Use RST n instructions for REAL operations (default is to use CALL instructions) | |
$Qn | Use RST n instructions for loads and stores in recursive environments. (default is to use CALL instructions) |
Compilation errors are numbered in the same sequence and meaning as those in Jensen and Wirth's 'User Manual and Report'. The errors messages, brief explanations, and some causes of the error are found in the appendix.
The compiler asks whether you would like to abort or continue compiling after each error it finds (unless the command line C switch described in Section 2.2.2 is used).
If the compiler cannot find an overlay or a procedure within an overlay it will display a question mark followed by the name of the procedure or overlay which is missing.
EXAMPLES
?A:MTPLUS.003 {this form for missing file} ?"PH2TERM" {this form for corrupted file}
A missing overlay can be alleviated by making sure it is the correct name and is on-line. The Od switch (Section 2.2.2) may be necessary. If the routine cannot be found, you have a corrupted copy of the overlay.
Below are procedure names which would be displayed by the compiler if it could not locate the names in the entry point table for the overlay in which they are supposed to be located. The number in front of the name is the group number of the overlay which contains the procedure.
001 INITIALI 002 PHASE1 003 PH2INIT 004 BLK 005 PH2TERM 006 DBGWRITE
Error 407, Symbol Table Overflow : Occurs in Phase I when not enough symbol table space remains for the current symbol. This may be alleviated by 1) using $K toggles, 2) breaking the program into modules.
Recursion Stack Overflow: Occurs in Phase II when the compiler's expression evaluation stack 'collides' with the symbol table. This may be alleviated by following the suggestions given above as well as 1) simplifying expressions, 2) changing sparse CASE statements into IF-THEN-ELSE statements because the jump table generated by the CASE can become large.
LINK/MT+ is invoked by typing its name, followed by a space, followed by the main program and modules to be linked, separated by commas. Below is the syntax for the linker command line.
LINKMT {<main program>=}<main program>,<module(s)>,PASLIB{<switces>}
All files to be linked must have the .ERL extension (except the .CMD file described in the next section) but this extension is not specified in the linker 5 input file list. A maximum of 32 file names may be given to the linker as input. The output is directed to the same disk as the main program unless the user specifies an output file name followed by an equal sign before the main program name. Each file to be linked may also be preceeded by a drive letter. preceded by a drive letter. Examples are shown below:
LINKMT CALC,TRANCEND,FPREALS,PASLIB/S LINKMT B:CALC=CALC,B:TRANCEND,FPREALS,PASLIB/S {CALC.COM to B:}
The linker allows the user to place a number of "switches" following the file names in the list. Each switch is preceded by a slash (/) and is a single letter with a parameter on the P, D, V, X, and 0 switches. The only placement sensitive switch is /S.
The examples in the previous section show the use of the /S switch which commands the linker to search the previously named relocatable file, PASLIB in the above example, as a library and extract only the necessary modules. The /5 switch only extracts modules from libraries and does not extract procedures and functions from separately compiled modules. It is position dependent in that it must follow the name of the run-time library in the linker command line. PASLIB and FPREALS are specially constructed libraries so that they are searchable. Other .ERL files supplied with the system, unless explicitly specified, are not searchable. User created modules are not searchable unless they have been processed by LIB/MT, described in Section 2.6. The order of modules within a library is important. Each searchable library must contain routines in the correct order and be followed by /S for searching to occur (see 2.6.)
A /M following the last file named in the parameter list generates a map to the console.
A /L following the last module named causes the linker to display module code and data locations as they are being linked. A /E following the last module causes the linker to display all routines including those which begin with $, ?, or @, which are reserved for run-time library routine names.
In order to support relocation of object code and data areas, the linker supports the /P and /D switches. The /P switch controls the location of the object code (ROM) and the /D switch controls the location of the data area (RAM). The syntax is: /P:nnnn or /D:nnnn where "nnnn" is a hexadecimal number in the range 0..FFFF. These two switches are used in the linking of main programs and overlays.
Also, if /D is used, more space is gained in the linking process because the data is not intermixed with the code as it is being linked. Using this switch is one way to solve memory limitations. The user should note that local file operations are not guaranteed if this is used because the system depends upon the linker zeroing the data area to make this facility work properly.
Using the /P switch and /D switch does not cause the linker to leave empty space at the beginning of the .COM file. Other linkers (in particular L80) will generate a significant amount of disk space to force the program to load at the proper address in a CP/M environment. The philosophy of LINK/MT+ is that if the /P switch is used the user really wants to move the program to another system for execution. This means that if the user specifies /P:8000 the first byte of the .COM file will be the byte to be placed at location 8000H and not 32K of zeroes before the first byte.
These switches, /P and /D, are specified after the last relocatable file to be loaded and may be in any order.
The /H:nnnn switch is provided to allow the linker to generate a HEX file instead of a .COM file. The nnnn value is in HEX and is totally independent of the default relocation value of 100H (possibly overridden by the /P switch). This means that the user may relocate the program to execute at 1D00H, for example, but generate the HEX file to have addresses starting at 8000H. (The user would use /P:1DOO/H:8000).
The user in a CP/M environment must typically use the SUBMIT facility for typing repetitive sequences such as linking multiple files together over and over and over again. The LINK/MT+ linker allows the user to enter this data into a file and have the linker process the file names from the file. This process is considerably faster than submit. The user must specify a file with an extension of .CMD and follow this file name with a /F, e.g., CFILES/F. The linker will read input from this file and process the names. Names may be on one line separated by commas as you would type it on the terminal, or each name or group of names may be on a separate line. The input from the file is concatenated logically between the data on the left of the file name and the data on the right of the /F switch. The total input buffer to the linker may be 256 bytes. The example below uses a .CMD file to link the files CALC, TRANCEND, FPREALS, and PASLIB into a .COM file. The command to link the files would be LINKMT CALC/F/L. PASLIB is searched for only the necessary modules and a link map is gene rated.
CALC.CMD contains : A:CALC,D:TRANCEND,F:FPREALS,B:PASLIB/S
Three switches are used when the linker is processing a root program in an overlay scheme or is processing an overlay. Because overlays are treated in detail in Section 3.3, only a brief summary of overlay switches is presented here.
The first is /Vm:nnnn which gives the overlay area address. The second is /X:nnnn which tells the linker how much extra data space is required by the overlays. The value is added to SYSMEM, the heap pointer. The third is /O:n which numbers the overlay and indicates that the previous filename is the root program symbol table.
/S | Search preceding name as a library extracting only the required routines |
/L | List modules as they are being linked |
/M | List all entry points in tabular form |
/E | List entry points beginning with $, ? or @ in addition to other entry points |
/P:nnnn | Relocate object code to nnnnH |
/D:nnnn | Relocate data area to nnnnH |
/W | Write a SID compatible SYM file (written to the same disk as the .COM file) |
/H:nnnn | Write the output as a HEX file with nnnnH as the starting location for the hex format. This is totally independent of the /P switch (no .COM file produced if this switch is used) |
/F | Take preceding file name as a .CMD file containing input file names (one per line) |
/Vm:nnnn | Overlay area starting address |
/X:nnnn | Overlay static variable space added to SYSMEM |
/O:n | number the overlay and use the previous filename as the root program symbol table. By default, n is in 1.50 but may be extended to 1..256 by altering the overlay manager. |
The distribution disks contain many .ERL files which are linked into your program depending on what groups of routine the compiler must reference based on the contents of your program. Below is a list of each file and the routines that it contains. If you have any of these routines as an undefined reference then link the appropriate relocatable file to resolve the reference.
BCDREALS | BCD real numbers, @XOP,@RRL,@WRL |
- | |
FPREALS | Floating point real numbers @XOP,@RRL,@WRL (searchable) |
- | |
AMDIO | |
FPRTNS | |
REALIO | Hardware real numbers (SEE AMD9511.CMD) |
One of the above groups must be linked when any real number loads, stores, assignments, or input/output is performed.
TRANCEND | Support for SIN, COS, ARCTAN, SQRT, LN, EXP, SQR |
TRAN9511 | Transcendental routines for 9511 replaces TRANCEND. |
RANDOMIO | SEEKREAD and SEEKWRITE are resolved here. |
DEBUGGER | @NLN, @EXT, @ENT generated when debugger switch is requested. If @XOP and @WRL are undefined see Section 2.5. |
PASLIB | Comparisons, I/O, arithmetic support, etc. |
Errors encountered in the linking process include those such as 'unable to open input file: xxxxxxxx' (self explanatory) and 'Duplicate symbol - xxxxxxx.' 'Duplicate symbol' means that a run-time routine or variable and user routine or variable have the same name. The linker will also output 'duplicate symbol detected' because the above message may scroll off the screen.
If you run out of memory while linking, you may remove the data from the code space with the /D switch. You may need to run a test link with the D switch set very high to find out what the code size is, then relink with the D switch set just above the last code address (with some room for code expansion). Also, the $E toggle in the compiler can be turned off around identifiers which need not be public. This saves space in the linker's symbol table.
The error message 'initialization of DSEG not allowed' indicates that the linker found a DB or DW in the data segment. 'Incompatible relocatable file' means that the .ERL file is bad and cannot be linked or that the assembly language file is implementing something illegal. 'SYSMEM not found in .SYM file' is printed when linking an overlay and the root program symbol file is corrupted. When linking assembly language modules, 50 external plus offset addresses are allowed by the linker in its offset table. If this number is exceeded then the message 'External offset table overflow' is printed.
Link/MT+ will link Pascal/MT+ main programs, Pascal/MT+ modules, and assembly language modules created by M80 or RMAC. Link/MT+ supports those features of the Microsoft relocatable format required for Pascal/MT+. These do NOT include:
Also Link/MT+ demands that the data-size and program-size records preceed the first byte of data to be loaded. This is the case with the Pascal/MT+ compiler, M80 and RMAC but not with such compilers as FORTRAN.
If the user has not specified that the disassembler is to be used, then the .ERL file produced by the Pascal/MT+ compiler is almost Microsoft compatible. It is almost compatible due to undocumented and changing requirements for input files to other manufacturers linkers. However, processing the .ERL files produced by the compiler by the librarian program, LIB/MT+, can result in Microsoft compatible relocatable files. See Section 2.6 describing LIB/MT+ for information on this program. Other linkers, particularly the L80 linker from Microsoft, may not be able to link a program which Link/MT+ can handle due to memory limitations imposed by the design of these other linkers.
The disassembler component of the Pascal/MT+ package combines the .PRN file (created by using the P switch) produced by the first phase of the compiler with the .ERL file (created by using the X switch) produced by the last phase of the compiler into a human readable file which contains assembly language coding interspersed with the Pascal/MT+ statements. This allows investigation into the code produced by the compiler and provides the necessary information when it is required to debug the program at the machine code level.
Only a disassembler for 8080 mnemonics is provided with all CP/M-80 releases because the majority of the code produced by the compiler is 8080 code.
The disassembler is a stand-alone program which is invoked by specifying the name of the disassembler, the name of the .PRN file, the name of the .ERL file and the name of the output file:
DIS8080 <input name> {<destination name> {,L=nnn}}
The disassembler looks for a .ERL and a .PRN file with <input name> as a prefix. The .ERL file must be a specially compiled version in which the X switch has been enabled. Failing to do so causes the entire program to be disassembled into DB statements. The X switch generates opcode records for the disassembler's use. The .ERL and .PRN files may be on any disk but both must be on the same disk. The destination file name may be a CP/M file name or a Pascal/MT+ device name such as CON: or LST:. The default destination name is CON:. The L=nnn parameter allows the user to specify the number of lines per page on the output device. The default value is 66 for 11" paper with 6-lines-per-inch. This is useful when using printers such as the T.I. 810 which has a 6-lines-per-inch or 8-lines-per-inch switch. Using 8-lines-per-inch the user should specify (for 11" paper) that the paper has 88 lines. This can save considerable amounts of paper. To use the L= option the user MUST specify the <destination name>.
Error messages generated by the disassembler are due to the fact that it found something unexpected in the bit stream. Continuing on usually produces more errors as the sequence is off. A completed .ERL file should have no errors in it so the correction to be made is to re-compile the .ERL file and be sure you are just disassembling Pascal code.
The following Pascal/MT+ program, PPRIME, was compiled with the X and P switches and disassembled, producing the following output (for an 8080/Z80)
PROGRAM PPRIME; CONST SIZE=8190; VAR PRIME: ARRAY[0..SIZE] OF BOOLEAN; I,J,K,L: INTEGER; COUNT: INTEGER; CH : CHAR; MAX: 0..SIZE; (*$P*) PROCEDURE TEST1(A,B,C:INTEGER); BEGIN B:=SUCC(SUCC(SUCC(A+A))); C:=A+B; WHILE C<=MAX DO BEGIN PRIME[C]:=FALSE; C:=C+B; END; END; (* TEST1 *) (*$P*) BEGIN MAX := SIZE; WRITE('G'); READ(CH); FOR L := 1 TO 10 DO BEGIN COUNT:=0; FILLCHAR(PRIME,SIZEOF(PRIME),CHR(TRUE)); FOR I:=0 TO MAX DO IF PRIME[I] THEN BEGIN TEST1(I,J,K); COUNT:=SUCC(COUNT); END; END; WRITELN (COUNT); WRITE('E'); END.
Output from disassembler:
The user will note that references to program locations are followed by a single quote (1000') and references to data locations are followed by a double quote (0000"). The user will also note that the operand of instructions which reference external variables point to the previous reference and the final reference contains absolute 0000. The list of external chains is following the disassembly of the program.
Pascal/MT+ Release 5.00 Copyright (c) 1980 by MT MicroSYSTEMS Page # 1 Disassembly of: TESTIT Stmt Nest Source Statement / Symbolic Object Code PRIME EQU 0000 L EQU 2000 K EQU 2002 J EQU 2004 I EQU 2006 COUNT EQU 2008 CH EQU 200A MAX EQU 200C 1 0 PROGRAM PPRIME; 0000 DB 00,00,00,00,00,00,00,00 0008 DB 00,00,00,00,00,00,00,00 0010 JMP 0000 0013 JMP 0000 2 0 CONST 3 1 SIZE=8190; 4 1 VAR 5 1 PRIME: ARRAY[0..SIZE] OF BOOLEAN; 6 1 I,J,K,L: INTEGER; 7 1 COUNT: INTEGER; 8 1 CH : CHAR; 9 1 MAX: 0..SIZE; 10 1 11 1 12 1 13 1 14 1 15 1 (*$P*) 16 1 PROCEDURE TEST1(A,B,C:INTEGER); 17 1 BEGIN TEST1: 0016 CALL 0000 0019 POP H 001A SHLD 200E" 001D POP H 001E SHLD 2010" 0021 POP H 0022 SHLD 2012" 0025 CALL 0000 19 2 B:=SUCC(SUCC(SUCC(A+A))); 0028 LHLD 2012" 002B XCHG 002C LHLD 2012" 002F DAD D 0030 INX H 0031 INX H 0032 INX H 0033 SHLD 2010" 20 2 C:=A+B; 0036 LHLD 2012" 0039 XCHG 003A LHLD 2010" 003D DAD D 003E SHLD 200E" 21 2 WHILE C<=MAX DO 0041 LHLD 200E" 0044 PUSH H 0045 LHLD 200C" 0048 PUSH H 0049 CALL 0000 004C POP PSW 004D JNC 006D' 22 2 BEGIN 23 3 PRIME[C]:=FALSE; 0050 LXI H,0000" 0053 XCHG 0054 LHLD 200E" 0057 DAD D 0058 PUSH H 0059 LXI H,0000 005C XCHG 005D POP H 005E MOV M,E 24 3 C:=C+B; 005F LHLD 200E" 0062 XCHG 0063 LHLD 2010" 0066 DAD D 0067 SHLD 200E" 25 3 END; 006A JMP 0041' 26 2 END; (* TEST1 *) 006D RET 27 1 28 1 (*$P*) 29 1 30 1 BEGIN 006E LHLD 0006 0071 SPHL 0072 CALL 0000 31 1 MAX := SIZE; 0075 LXI H,1FFE 0078 SHLD 200C" 32 1 WRITE('G'); 007B LXI H,0000 007E PUSH H 007F CALL 0000 0082 LXI H,0047 0085 PUSH H 0086 CALL 0000 0089 CALL 0000 33 1 READ(CH); 008C LXI H,200A" 008F PUSH H 0090 LXI H,0000 0093 PUSH H 0094 CALL 0080' 0097 CALL 0000 34 1 FOR L := 1 TO 10 DO 009A LXI H,0001 009D PUSH H 009E LXI H,000A 00A1 PUSH H 00A2 POP D 00A3 POP H 00A4 DCX H 00A5 SHLD 2000" 00A8 INX H 00A9 PUSH H 00AA PUSH D 00AB CALL 0000 00AE SHLD 2014" 00B1 LHLD 2000" 00B4 INX H 00B5 SHLD 2000" 00B8 LHLD 2014" 00BB DCX H 00BC SHLD 2014" 00BF MOV A,H 00C0 ORA L 00C1 JZ 012C' 35 1 BEGIN 36 2 COUNT:=0; 00C4 LXI H,0000 00C7 SHLD 2008" 37 2 FILLCHAR(PRIME,SIZEOF(PRIME),CHR(TRUE)); 00CA LXI H,0000" 00CD PUSH H 00CE LXI H,1FFF 00D1 PUSH H 00D2 LXI H,0001 00D5 PUSH H 00D6 CALL 0000 38 2 39 2 FOR I:=0 TO MAX DO 00D9 LXI H,0000 00DC PUSH H 00DD LHLD 200C" 00E0 PUSH H 00E1 POP D 00E2 POP H 00E3 DCX H 00E4 SHLD 2006" 00E7 INX H 00E8 PUSH H 00E9 PUSH D 00EA CALL 00AC' 00ED SHLD 2016" 00F0 LHLD 2006" 00F3 INX H 00F4 SHLD 2006" 00F7 LHLD 2016" 00FA DCX H 00FB SHLD 2016" 00FE MOV A,H 00FF ORA L 0100 JZ 0129' 40 2 IF PRIME[I] THEN 0103 LXI H,0000" 0106 XCHG 0107 LHLD 2006" 010A DAD D 010B MOV A,M 010C RAR 010D JNC 0126' 41 2 BEGIN 42 3 TEST1(I,J,K); 0110 LHLD 2006" 0113 PUSH H 0114 LHLD 2004" 0117 PUSH H 0118 LHLD 2002" 011B PUSH H 011C CALL 0013' 43 3 COUNT:=SUCC(COUNT); 011F LHLD 2008" 0122 INX H 0123 SHLD 2008" 44 3 END; 0126 JMP 00F0' 45 2 END; 0129 JMP 00B1' 46 1 WRITELN (COUNT); 012C LHLD 2008" 012F PUSH H 0130 LXI H,007C' 0133 PUSH H 0134 CALL 0095' 0137 CALL 0087' 013A CALL 0000 013D CALL 0000 47 1 WRITE('E'); 0140 LXI H,0131' 0143 PUSH H 0144 CALL 0135' 0147 LXI H,0045 014A PUSH H 014B CALL 0138' 014E CALL 008A' 48 1 END. 0151 CALL 0000 External reference chain @WIN --> 013B External reference chain @CHW --> 014F External reference chain @RCH --> 0098 External reference chain @PST --> 0017 External reference chain @PLD --> 0026 External reference chain @CRL --> 013E External reference chain @LEI --> 004A External reference chain @FIN --> 00EB External reference chain @SFB --> 0145 External reference chain @DWD --> 014C External reference chain @INI --> 0073 External reference chain @HLT --> 0152 External reference chain OUTPUT --> 0141 External reference chain INPUT --> 0091 External reference chain FILLCH --> 00D7
The Pascal/MT+ debugger, a relocatable file named DEBUGGER.ERL, is a component of the Pascal/MT+ system which is linked into the object program along with the run-time support library. The debugger can display variables, set symbolic breakpoints, single step a statement at a time, display symbol tables, and display entry and exit from procedures and functions. Line numbers are displayed in trace mode although when debugging a program consisting of modules, line numbers are duplicated in each module. It can be used in a non-CP/M environment if the user responds with simply <return> to the debugger's request for the symbol table (.SYP) file name. This disables only the symbolic facilities but retains the display by address facilities.
The following two sections describe how to include the debugger code in an object program and how to operate the debugger.
To include debugger information into the object program the user must specify the D command line switch to MTPLUS.COM. The compiler will then produce a PSY file to the same disk as the .ERL file and generate extra code at the beginning and end of each procedure for the debugger breakpoint logic. The PSY files contain records for each procedure, function and variable declared in the program. The address fields for each of these items is module relative. Link/MT+ will process these PSY files and create a SYP file containing absolute addresses for the procedures, functions and variables. The debugger then uses this òSYP file for symbolic variable display, symbolic breakpoints, etc.
Link/MT+ (as described above) creates a .COM and a .SYP file from the .ERL and PSY files created by the compiler. The user must link the debugger as the first module of the program so that execution begins with the debugger when the program is run. Below is a sample command line for the linker when the debugger is is being linked.
LINKMT USERPROG=DEBUGGER,USERPROG,PASLIB/S
The 'USERPROG=' syntax causes the name of the .COM file generated by the linker to be USERPROG and not DEBUGGER.
Because the debugger is in charge of USERPROG, it will first ask for the name of the symbol table file when USERPROG is executed. The user should respond with the name of the SYP file or <return> for no symbols. The debugger will then respond with '+>'. After entering the BEgin command, the user may enter any of the debugger commands and proceed to debug the program under test.
When the debugger is used in a recursive environment local variables may not be displayed because they are not stored in static memory but are on the stack.
If you link the debugger as in the sample above, you will have two undefined symbols, '@XOP' and '@WRL', which are required to write real numbers. Because USERPROG does not use reals the real number run time package has not been linked causing the above routines to be undefined. This will not, of course, cause any problems in execution as there are no real numbers to display. An attempt to display a real will just cause the program to return to the operating system.
The debugger converts items whenever possible into the form expected by the user (i.e. decimal for integers, TRUE / FALSE for booleans, etc.). When this is not possible the debugger will display the data in HEX and ASCII. Described below are the syntax elements and the commands.
The term <name> is either a variable name, a procedure / function name, or a prefixed variable name. Names are 1 to 8 characters long and follow the syntax of the Pascal compiler. Underscores are allowed and ignored (e.g. A_B is exactly the same as AB). A prefixed variable name is a variable ientifier prefixed with a procedure / function name. This syntax is used to display local variables and parameters in non-recursive modules. If two procedures each have a local procedure of the same name only the first procedure linked will be available for symbolic display.
The term <num> is either a decimal number or, if prefixed by a '$' character, a hexadecimal number. Decimal numbers fall in the range 0.. 32767. Hexadecimal numbers in the range 0..FFFF.
<name> ::= <procedure identifier> : <variable identifier> | <variable identifier> | <num> <num> ::= $ <hex number> | <decimal number>
The variable display commands are followed by a parameter designated as <parm> which is defined in terms of <name>, <num>, offsets, and an indirection symbol.
<parm> ::= [<name> | <num>] {^} {[+ | -] <num>}
The offset syntax is the character '+' (which is assumed if not present) or '-' followed by <num>. The value of <num> is the number of bytes added to or subtracted from the address obtained thus far from the <parm>. The indirection symbol, '^', is used with variables which are pointers. When used, the debugger displays the data pointed to by the pointer, not the content of the pointer itself. Examples of <parm> are shown below:
(* Pascal declarations: *) TYPE PAOC = ARRAY [1..40] OF CHAR; VAR ABC : INTEGER; PTR : ^PAOC;
Example of <parm>:
ABC an integer PTR contents of PTR PTR^ entire array ABC+10 10 bytes past ABC location PTR^+10 PTRA [11] ABC-3 3 bytes before ABC PTR^-3 3 bytes before the array, PAOC $3FFD Absolute location $423B^ 32 bytes pointed to by $423B $3FFD+$5B 32 bytes at $4058 $423B^+49 32 bytes pointed to by contents of $423B + 49 PROC1:I local variable PROC2:J^+9 offset from local pointer
The command used to alter the contents of a memory address is 'SE<parm>'. This command displays the byte at that address in decimal. A decimal (or hex if the $ is used) value followed by a carriage return replaces the current byte with the new one. If a number is entered which is cannot be contained in one byte (greater than 255) then the last two digits are used. The address and contents of the next byte of memory is then displayed. Alteration may continue until a '.' followed by a carriage return is entered which returns you to the command mode. This works in the same way as the Set command in DDT or SID.
Command Syntax | Meaning |
---|---|
DV <name> {^} | Display Variable - variable display by <name>. If this is a pointer variable, the contents of the pointer is displayed unless followed by ^ which causes the data pointed to by the pointer to be displayed. |
The following commands are used when symbols are not available or when fields within records or array elements are to be displayed: | |
DI <parm> | Display Integer |
DC <parm> | Display Character |
DL <parm> | Display Logical (Boolean) |
DR <parm> | Display Real |
DB <parm> | Display Byte |
DW <parm> | Display Word |
DS <parm> | Display String |
DX <parm> {,num} | Display eXtended (structures) This is always displayed in HEX/ASCII format Num is the size, in bytes, for memory dump. The default value is 320 bytes. |
The following commands allow control of the user program: | |
TR or T | Trace - Execute one line and return |
T<num> | Trace <num> lines and return |
BE | BEgin execution (start program from beginning) |
GO | Continue execution from a breakpoint |
SB <name> | Set breakpoint at beginning of procedure <name> |
RB <name> | Remove breakpoint at procedure <name> |
E+ | Enable display entry and exit of each procedure or function during execution (default on) |
E- | Disable entry / exit display |
PN | Display procedure names from .SYP file |
VN <name> | Display variables associated with procedure <name> |
SE <parm> | Modify contents of memory at <parm>. A '.' terminates this command. |
?? | HELP! List of commands found in DBUGHELP.TXT. |
The Pascal/MT+ librarian is a dual purpose program. Its primary purpose is to logically concatenate .ERL files together to construct a searchable library such as PASLIB. Its secondary purpose is to convert Pascal/MT+ .ERL files into files which are compatible with Microsoft compatible linkers such as L80 and Link8O.
The librarian is invoked as shown below:
LIBMT <filename>
LIB/MT+ operates using a file of type '.BLD' as input. The filename given when invoking LIBMT must not use the extent, 'BLD'. This file contains an output file name followed by a list of input file names, each name on a separate line. Input files may be a single module or a library of modules. NOTE: A PASCAL MODULE COMPILED WITH THE 'X' (EXTENDED) OPTION (USED FOR THE DISASSEMBLER) MAY NOT BE PROCESSED.
An example '.BLD' file for creating a LINK/MT+ compatible library is shown below:
MYLIB. ERL MYMOD1. ERL MYMOD2. ERL MYMOD3. ERL
When processed by LIB/MT+ this fill will cause the deletion of any old copy of MYLIB.ERL and then read and concatenate MYMOD1.ERL, MYMOD2.ERL and MYMOD3.ERL and place the output into MYLIB.ERL. Pascal/MT+ modules, libraries, and appropriate assembly language modules are valid as input. The extension on the files must be supplied but need not be '.ERL'. The output file must be of type '.ERL' if it is to be processed by Link/MT+.
The Link/MT+ linker is a one pass linker. When the /S option is used to signify that a file is a library the linker loads only those modules which have been referenced by previous modules. Therefore the order of modules in your library is important. If the modules are concatenated as: A,B,C then modules B and C cannot contain references to module A unless they are guaranteed that module A is loaded. Module A, however, can contain references to B and/or C because this will cause the linker to load them.
Remember, only entire modules are extracted from a library by the linker and that single procedures from a module are not extracted. All entry points, both code and data, are used as a basis for searching when /S is used. Only one entry point in a module need be referenced to force loading that entire module.
PASLIB may not be altered using this librarian because of its special construction. Link the replacement modules before linking PASLIB to resolve references to those routines before PASLIB is searched. If the replacement routines are in a library, it is a good idea NOT to search it because the references to the replacement routines may not be made until PASLIB is processed.
If the first line of the .BLD file contains only 'L80' or '180' then the output file will be L80 compatible, otherwise it will be compatible with Link/MT+. An L80 compatible file will NOT work with Link/MT+. A sample .BLD file for converting a library and / or module to L80 format is given below.
L80 MYLIB. REL MYMOD1. ERL MYMOD2. ERL MYMOD3. ERL
LIB/MT+ creates a file called MYLIB.REL which contains the converted MYMOD1, MYMOD2, and MYMOD3. The conversion process truncates all public names to 6 characters in length which may cause duplicate symbol errors when using L80 which did not occur when using Link/MT+ because Link/MT+ allows public names to be up to 7 characters in length.
The features gained by using this program and L80 are:
The features of the Pascal/MT+ system lost when using this program and L80 are: