PCjs Machines

Home of the original IBM PC emulator for browsers.

Logo

PC-SIG Diskette Library (Disk #1080)

[PCjs Machine "ibm5170"]

Waiting for machine "ibm5170" to load....

Information about “MODULA-2 COMPILER 1 OF 2 (ALSO 1081)”

The MODULA-2 COMPILER (M2C) proves you don't have to buy a
commercial package to get a full-featured compiler!  M2C features the
compiler combined with an integrated editor and ``make'' facility, a
program linker, an execution profiler, and a makefile generator.

Code generated by the M2C suits either the Intel 8086 ``huge'' or
``large'' memory models.  More restrictive memory models are not
supported.  For the ``huge'' model, each module has its own data and
code segment.  Each of the segments can be up to 64K in size.  For the
``large'' memory model, static data from all the modules is combined
into a single data segment.  For either model, pointers are four bytes
long and all remaining memory is available for the ``heap''.

The package includes 37 pages of well-written and indexed
documentation.

FILE1080.TXT

Disk No: 1080
Program Title:  MODULA-2 COMPILER version 2.0a (Disk 1 of 2)
PC-SIG version:  2

The MODULA-2 COMPILER (M2C) proves that you don't have to buy a
commercial package to get a full-featured compiler!  M2C features the
compiler combined with an integrated editor and "make" facility, a
program linker, an execution profiler, and a makefile generator.

Code generated by the M2C suits either the Intel 8086 "huge" or "large"
memory model.  More restrictive memory models are not supported.  For
the "huge" model, each module has its own data and code segment.  Each
of the segments can be up to 64K in size.  For the "large" memory model,
static data from all the modules is combined into a single data segment.
For either model, pointers are four bytes long and all remaining memory
is available for the "heap."  The package includes 37 pages of indexed
documentation which are well-written and understandable.

Usage:  Modula Programming Utilities.

Special Requirements:  512K memory and the Modula Programming Language.

How to Start:  Type GO (press enter).

Suggested Registration: $25.00

File Descriptions:

FM2CMP20 ARC  Archived file of main program.
FM2DOC20 ARC  Archived documentation.
FM2UTL20 ARC  Archived utilities.

PC-SIG
1030-D East Duane Avenue
Sunnyvale, CA   94086
(408) 730-9291
(c) Copyright 1988,89 PC-SIG, Inc.


FMODULA2.DOC



                           Fitted Modula-2 Version 2.0

                 (C) Copyright 1987,1988 Fitted Software Tools.
                              All rights reserved.


                              Fitted Software Tools
                                 P.O.Box 867403
                                 Plano, TX 75086
                                BBS 214/517-4629




     










                             DISCLAIMER OF WARRANTY

     THIS SOFTWARE AND MANUAL ARE PROVIDED "AS IS" AND WITHOUT WARRANTIES
     AS TO PERFORMANCE OR MERCHANTABILITY.

     THIS SOFTWARE IS PROVIDED WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES
     WHATSOEVER. BECAUSE OF THE DIVERSITY OF CONDITIONS AND HARDWARE UNDER
     WHICH THIS SOFTWARE MAY BE USED, NO WARRANTY OF FITNESS FOR A
     PARTICULAR PURPOSE IS OFFERED. THE USER IS ADVISED TO TEST THIS
     SOFTWARE THOROUGHLY BEFORE RELYING ON IT. THE USER MUST ASSUME THE
     ENTIRE RISK OF USING THIS SOFTWARE.

     

     All the information in this document is believed to be correct at the
     time of publication.  We do, however, reserve the right to make any
     changes in product specifications and/or availability without notice. 

     





     IBM is a registered trademark of International Business Machines
     Corporation.

     





     Introduction                                                         2
     







                                    Chapter 1

                                  Introduction



     Thank you for your interest in our Modula-2 compiler. 

     This system features a Modula-2 compiler with an integrated editor and
     "make" facility, a program linker, a makefile generator, and an
     execution profiler. 

     The compiler generates code for the Intel 8086 "huge" or "large"
     memory model: In the "huge" memory model, each module has its own data
     and code segment, each of which can be up to 64k in size; In the
     "large" memory model, all the modules' static data is combined into a
     single data segment.  In either model, pointers are 4 bytes long and
     all the leftover memory is available for the "heap". More restrictive
     memory models are not currently supported. 

     All the library and runtime support source code is available to our
     registered users (see Shareware).

     We hope that our effort will prove itself worthy of your support. 



























     Introduction                                                         3
     





     1.1 Hardware requirements


     This system will run on IBM PC, PC/AT, or compatible systems with at
     least 512K of RAM, two double sided floppy disk drives and a
     monochrome display adapter, color graphics adapter or equivalent. 

     A hard disk and 640K of RAM are, however, recommended. 

     




     1.2 Software requirements


     This system requires DOS version 2.0 or later. 

     No other software is required to use this system, but you will need an
     assembler if you intend to modify one of the runtime support modules:
     M2Reals (floating point support), M2Longs (LONG arithmetic) or M2Procs
     (coroutine handling). 

     




     1.3 For users upgrading to release 2


     This is, in a nutshell, what is new in release 2.0.

     LONGREALs: You now have a choice of REAL size.  Release 1.x supported
     only the 4 byte real number format, which provided about seven digits
     of accuracy.  The LONGREAL format is 8 bytes and has about 15 digits
     of accuracy.  The tradeoff, of course, is time.  But, if you need
     accurate results in a short time, then... 

     8087 support: M2Reals, Mathlib0 and LMathLib0 (MathLib0 for LONGREALs)
     will use the 8087/80287 math coprocessor if one is present.  Inline
     generation of 8087 code is not available at this time.  The inline
     assembler supports all the 8087 mnemonics, but with some
     restrictions. 

     OBJ file generation: You may now instruct the compiler to generate DOS
     compatible OBJ files.  Please refer to the chapter on OBJ files for
     more details. 




     Introduction                                                         4
     


     Of special importance the international users, is the fact that the
     editor now accepts characters > 7FX. Indent and unindent commands were
     also added to the editor, as well as 43 or 50 line display support. 

     The module RealConversions was added to the system.  You can finaly
     convert floating point numbers to fixed decimal notation! 

     This is the most visible stuff.  There are, of course, many more minor
     enhancements in release 2.

     Of particular importance (it may affect your code!):

          The compiler now generates checks for NIL pointers, when the $T
          directive is in effect.  Also, Storage.DEALLOCATE now sets the
          pointer passed to it to NIL.

          In release 1 there were some problems with the implementation of
          type compatibility between CARDINAL and INTEGER: The compiler was
          more strict than the language definition called for.  Some of
          this was fixed along the way in release 1. We hope to have it
          cured now.  When the $R directive is in effect, the compiler
          generates "range check code" on assignments between INTEGERs and
          CARDINALs; basically, if the high order bit is on, the value is
          out of range, regardless of which way you are going.

     We owe an apology to many of the users that wrote in (or dialed up)
     with good suggestions.  Although some of these were implemented, many
     were not, not because they were discarded, but because of the
     unnavailability of resources (time, mostly!). 

     We hope that you will find this new release a worthy successor to what
     we introduced a little over a year ago. 

     






















     Software installation                                                5
     







                                    Chapter 2

                              Software installation



     Before starting, please print the file READ.ME, which provides a
     description of every file in the distribution disks. 

     




     2.1 Theory


     The library module TermIO (through which Terminal does its I/O)
     requires that the ANSI.SYS driver be installed. 

     The executable files (MC.EXE, M2LINK.EXE, ...) should, for ease of
     operation, be placed in a drive/directory named in the DOS PATH
     variable. 

     The editor configuration file M2ED.CFG must be accessible through the
     DOS PATH.

     Both the compiler and the linker will use the environment variable
     M2LIB to locate required library modules (the format for the M2LIB
     entry matches that of the DOS PATH).

     The environment variable M2MODEL may be set to 'HUGE' or 'LARGE',
     after which you no longer have to tell the compiler what memory model
     to compile for (unless you wish to override the environment
     selection).  IF M2MODEL is not set, the compiler, by default (and for
     compatibility with version 1.0), assumes that you want to compile for
     the HUGE model. 

     The compiler and utilities in this package do not keep many files open
     simultaneously.  If you set the FILES parameter in CONFIG.SYS to 10
     you should not encounter any problems.  For performance
     considerations, you should also allocate more than the default number
     of buffers for DOS: If you are running on a PC class machine, try
     allocating 20 buffers in your CONFIG.SYS. On an AT class machine, try
     64 buffers. 

     Example CONFIG.SYS:




     Software installation                                                6
     


          DEVICE=ANSI.SYS
          FILES=10
          BUFFERS=20

     This compiler is a memory hog -- you heard it here first!  This is
     neither good nor bad, simply an implementation decision.  Source
     modules being compiled, for example, are sucked into memory with a
     single read system call. 

     Source files (either being compiled or edited) are loaded at the top
     of available memory.  This, of course clobbers the resident portion of
     COMMAND.COM. Because this software was developed on a relatively slow
     system, with a very slow hard disk, we decided that it would be a good
     idea to, on request, preserve the resident portion of COMMAND.COM.

     To enable the "COMMAND save" feature of the compiler, which will stop
     it from clobbering the resident portion of COMMAND.COM, just add the
     following line to your AUTOEXEC.BAT file:

          SET CMDSIZE=NN

     where NN is the size of the resident portion of COMMAND.COM in K (18
     for DOS 3.0).

     MC clobbers the top of the memory space available for use during
     initialization.  Therefore, to find out the size of the resident
     portion of COMMAND.COM, try the following procedure: start by setting
     CMDSIZE to the size of COMMAND.COM. If now you execute MC, exit it,
     and press the F3 key, DOS will still remember your MC command. 
     Decrement CMDSIZE and retry the MC test until the system forgets your
     last command (COMMAND.COM had to be reloaded). 

     Because the compiler supports 2 different memory models, 2 different
     sets of library object files (.M2O) are provided, one for each of the
     memory models.  If you are going to be using both memory models, keep
     each of these sets of files in a different directory, and change the
     M2LIB path according to the model in use.  We use the following BAT
     files to take care of this:


     LARGE.BAT:
          set M2MODEL=LARGE
          set M2LIB=C:\M2\LIB;C:\M2\LIBL

     HUGE.BAT:
          set M2MODEL=HUGE
          set M2LIB=C:\M2\LIB;C:\M2\LIBH

     where \M2\LIB is the directory where all the DEF files reside,
     \M2\LIBL contains the LARGE memory model M2O files,... 

     In the following discussion we will, for simplicity sake, assume that




     Software installation                                                7
     

     you will be using only one of the memory models. 

     




     2.2 Recommended setup for a system with 2 floppy drives


     This whole system is too large to fit in a single 360k floppy. 
     Therefore, it is recommended that you build a "compiler" floppy and a
     "utilities" floppy (you may combine them both in a 720k or 1.2Mb
     floppy). 

     On the compiler floppy, place the compiler (MC.EXE), all the library
     definition modules (*.DEF), the file M2ED.CFG and DOS' COMMAND.COM.

     The utilities floppy will take the rest of the system: the linker
     (M2LINK.EXE), other .EXE files, and the library and runtime support
     object files (*.M2O and *.BIN).

     Assuming that you will use drive A for the compiler and utilities disk
     and drive B as your work drive, add the following to your AUTOEXEC.BAT
     file:

          SET PATH=A:
          SET M2LIB=A:

     If you follow these suggestions, you may use all the system's
     capabilities.  Just remember to swap the floppy in drive A before and
     after invoking the linker from the compiler's menu. 




     2.3 Recommended setup for a hard disk system


     Place the executable files (*.EXE) and M2ED.CFG in a directory
     currently in the DOS search path, or in a new directory (ex: \MODULA2)
     to be added to the PATH list.  Example:

          SET PATH=C:\BIN;C:\MODULA2

     Make a directory for the library files (ex: \M2LIB) and copy all the
     .DEF, .M2O and .BIN files to it.  To the AUTOEXEC.BAT file add the
     line:

          SET M2LIB=C:\M2LIB

     You will probably want to create a directory for your own reusable
     library modules.  This directory can be added to the M2LIB environment




     Software installation                                                8
     

     variable.  Example:

          SET M2LIB=C:\M2LIB;C:\MYLIB

     You may keep your projects in their own, individual, directories. 

     


















































     A little tour through the system                                     9
     







                                    Chapter 3

                        A little tour through the system



     After you finish the installation as described above, please copy the
     files identified as the "system tour files" in the READ.ME file to
     your work disk or directory. 

     Because we do not know your particular system configuration, in the
     following examples we will assume the worst possible scenario. 
     Therefore, some of the capabilities of this system will not be fully
     exploited.  Specifically, we will not invoke the linker or run the
     programs from the compiler menu, neither will we invoke a DOS shell to
     run DBG2MAP.

     




     3.1 The tour


     First, we will look at the unnatural case of compiling, linking and
     running a program that works the first time around.  Please execute
     the following commands:

          MC SIEVE /C
          M2LINK SIEVE /O

     Well, that's it!  Ready to run... 

          SIEVE

     Now for the more usual case:

          MC BADSIEVE

     From the compiler menu, select 'C' for compile. 

     Gee, that was quick!  Press RETURN to take a look at our errors... 

     The cursor is now positioned at the location of the first error. 
     Using the keys Ctrl-E (find next error) and Ctrl-P (find previous
     error) you may visit all the errors flagged by the compiler.  All the




     A little tour through the system                                    10
     

     while, the editor shows the error description on the top line of the
     screen.  But, going back to the first error... 

     We really confused the compiler when we mistakenly typed in '.'
     instead of '..' in the range declaration.  Move the cursor back (left
     arrow key) to where the '.' is, type in another '.', and that should
     fix that!  As you will see as you type Ctrl-E, that single error
     caused the compiler to dislike a few other things on that same line;
     we will just ignore those errors and go on. 

     Go on to the next error location (line 22). This time, we should have
     used a ']' but typed '}' instead.  The backspace key will delete the
     offending character; now, type the ']' in its place. 

     And that is that.  Shall we try to compile the program again? 

     Press Alt-S to save the file, Alt-Q to leave the editor and, back at
     the main menu, select 'C'.

     More errors?! 

          These errors should have been detected during pass2 of the
          compiler; If not, you may try to fix these errors and recompile,
          or you may opt for loading and compiling the new file
          BADSIEV1.MOD, which contains the earlier fixes.

     Going back to the editor... 

     We find that we used the identifier 'cnt' which is undefined; we
     really meant to use count.  So, moving the cursor around with the
     cursor keys and/or deleting characters with the backspace or delete
     key, please replace 'cnt' by 'count'.

     Searching for the next error... 

     The next error occured during the processing of the call to WriteCard.
     What happened here is that WriteCard requires 2 parameters, the second
     one being the size of the field to display.  So, to fix it, let's
     insert a comma after 'count' and some number (for example 'count,4').

     Any more erors?  No, that is it... 

     We now save the file (Alt-S), quit the editor (Alt-Q) and recompile
     (c).

     Now, the program should have compiled without errors.  If not, you may
     recompile BADSIEV2.MOD instead. 

     We may now quit the compiler (q).

     By now, we have some program that has compiled clean (BADSIEVE,
     BADSIEV1 or BADSIEV2). In what follows, we will assume all went well
     and we have BADSIEVE.




     A little tour through the system                                    11
     


     If you look at the directory, you will see the new object module
     created as a result of the previous exercise (BADSIEVE.M2O). The
     compiler always writes its output to a file with the extension 'M2O'.

     Let us link and test the program:

          M2LINK BADSIEVE /L

     We use the /L option so that the line number information written out
     by the compiler to the object file will be preserved by the linker. 
     We will need this information later. 

          BADSIEVE

     A runtime error?  And it gives us a PC location.  Very informative, is
     it not?  How in the world are we supposed to fix the program based on
     that?  Do not dispair! 

     Looking at your directory, you will notice that the linker created 2
     files: BADSIEVE.EXE and BADSIEVE.DBG.

     No, TYPEing BADSIEVE.DBG does not help, it just displays garbage.  But
     we have a utility called DBG2MAP that will convert the information in
     that file to a DOS LINK compatible MAP file.  Let's try it:

          DBG2MAP BADSIEVE

     Now, using your favorite editor (or the editor in MC: MC BADSIEVE.MAP
     and then E), look at the contents of BADSIEVE.MAP. In the last few
     lines of the file, we have the line number information for BADSIEVE.
     If you look up the line whose address is closest (but lower) to the PC
     in the error message, you get the number of the line where the error
     occured (line 22).

     Let's see what happened... 

          MC BADSIEVE

     Pick 'E' to go into the editor and, either move the cursor down to the
     line indicated by your research, or let the editor find it with Alt-G.

     So, what is the problem?  Well, we declared the 'flag' array to have a
     maximum index of 8190, but 'j' got bigger than that (the FOR loop will
     increment 'j' up to the value of 10000).

     You may fix the problem by deleting the '10000' and typing in its
     place 'SIZE'.

     Recompile the program, link it, and run it.  Did it work?  Good.

     It is time for you to experiment on your own.  But, before you do much
     more, you may want to check out the Editor chapter of the




     A little tour through the system                                    12
     

     documentation. 

     






















































     The Compiler                                                        13
     







                                    Chapter 4

                                  The Compiler



     In the Modula-2 language, as defined by Niklaus Wirth, identifiers may
     be used before they are declared, except when they are used in another
     declaration (this restriction does not apply to pointers).  This
     forces the compilation process to be done in at least two passes. 

     To avoid imposing unnecessary restrictions and, yet, provide
     reasonable performance, the two pass approach was selected: During the
     first pass, syntax analysis and declaration analysis are performed;
     The second pass performs the semantic analysis and code generation. 

     The compiler has an integrated text editor.  Should errors be
     encountered, the editor is invoked at the end of the current compiler
     pass (sooner, if an error is found during the processing of an import
     list or if 20 errors are identified). 

     The compiler also has a built in "make" processor.  A makefile must be
     created before this process is invoked.  Although you can create a
     makefile using the editor, we recommend that you use the utility
     provided for that purpose: GENMAKE (this utility may be invoked from
     the compiler menu -- G).

     The compiler can generate 2 different kinds of object files as
     output.  By default, M2O (stands for "Modula-2 Object") files are
     generated.  This file format is unique to this compiler, and it is
     optimized for our requirements and those of Modula-2. But the user
     can, through the use of an environment variable (M2OUTPUT), specify
     that standard OBJ files are to be generated instead. 

     
















     The Compiler                                                        14
     





     4.1 Running the integrated compiler: MC


     Compiler invocation:

          MC [workModule] [/p mainModule] [/s maxIds idSpace] [/c] [/e]
          [/m] [/d-]

     The '/p' option may be used to indicate the name of the main module of
     the program that you are working on (the name should not have an
     extension).  If this option is not used, but workModule is entered
     without an extension, the same name is also used for mainModule. 

     The '/s' option allows you to change the default sizes of the compiler
     identifier tables.  The two arguments specify the maximum number of
     different identifiers to be processed, and the total string space to
     be allocated to store these identifiers.  The default values are 2000
     and 12000, respectively. 

     If you use of the '/c' command line option, the compiler starts
     compiling "workModule" immediately and, if no errors are encountered,
     will bring you right back to the DOS prompt.  This is useful when
     running the compiler from a batch file:

          MC myprog /c

     The '/e' option will send you straight into the editor. 

     The '/m' option invokes the make processor, which will look for the
     file mainModule.MAK for the dependencies list. 

     The '/d-' option sets the default value of the compiler directives $R
     and $T to '-', disabling the default generation of most runtime error
     checking.  We do not recommend disabling the stack overflow checking,
     and the use of '/d-' will not do it. 

     The compiler always sets the DOS errorlevel to 0 if the last compile
     was successful (no errors); otherwise, the DOS errorlevel is set to 1.

     If the compiler is invoked without the '/c', '/e' or '/m' options, you
     will get a screen that looks something like this:












     The Compiler                                                        15
     




          Modula-2 compiler, Version 2.0
          (C) Copyright 1987,1988 Fitted Software Tools.
          All rights reserved.

          Memory model in use: LARGE
          Output file format:  M2O

          Heap in use:                   0K
          Available Heap:              249K

          Program:     sieve

          Work module: sieve.MOD

          Program  New   Options  DOS   Quit  dbg2map
          Compile  Edit  Genmake  Make  Link  eXecute >



     The options at this point are:

     Program           Specify the name of the main program module. 

     New               Specify another "Work module". 

     Options           To select the memory model to use. 

     DOS               Invoke a new DOS shell.  At the DOS prompt, you
                       should type EXIT to return to this system. 

     Quit              Return to DOS.

     dbg2map           (2) Execute DBG2MAP, passing as argument the name in
                       Program.

     Compile           Compile the "Work module". 

     Edit              Edit the "Work module". 

     Genmake           Invoke the GenMake program, passing as argument the
                       name in Program -- and '/OBJ', if appropriate. 

     Make              Recompile all the necessary modules as per the rules
                       of a makefile (The makefile is assumed to have the
                       name in Program and the extension of .MAK). Note: If
                       errors are encountered during the compilation of one
                       of the modules, the make process is aborted.  After
                       fixing the errors, select Make again. 

     Link              Invokes the linker (M2Link) passing along as




     The Compiler                                                        16
     

                       arguments the name in Program and '/L'.

     eXecute           Program is executed. 

     




     4.2 Running the freestanding compiler: M2COMP


     Compiler invocation:

          M2COMP filename [/m] [/s maxIds idSpace] [/d-]

     filename is the name of the module to compile or, if the /M option is
     used, the name of the makefile to process. 

     The DOS errorexit is set to 0 if the compilation (make) is successful
     and to 1 otherwise. 

     




     4.3 The compilation process


     


     4.3.0.1 The input file

     If the module to be compiled is already loaded into one of the editor
     buffers, that source is compiled.  Otherwise, the compiler tries to
     open the named file. 

     


     4.3.0.2 The imported modules

     The compiler and the linker cooperate in assuring that all the modules
     that refer to a particular definition module will have been compiled
     against the same version of that definition module. 

     To this end, the compiler places in the 'module header' and 'module
     import' records of the object file a "module key".  This module key is
     the date of the DEF file used during the compilation of the
     implementation module or during the processing of the IMPORT
     statement. 




     The Compiler                                                        17
     


     Due to this, the compiler will not look in the editor buffers for the
     DEF files needed to process an IMPORT list.  These are always read in
     from the disk. 

     


     4.3.0.3 The output file

     The output from the compilation of a main module or an implementation
     module is a single output file, with the same name of the source file
     but with the extension of 'M2O' (Modula-2 Object) -- OBJ files are
     created instead, if the environment variable M2OUTPUT so specifies. 

     The compilation of a definition module does not generate any new
     output files.  If the compilation is successful (no errors), the
     compiler simply 'touches' the source file, updating its modification
     time. 

     


     4.3.0.4 A warning

     Because of the fact that the compiler uses the date of the DEF file as
     that module's key, you may not modify a DEF file unless you intend to
     recompile all the modules that use it, nor can you copy the file in
     such a way that its date is not preserved. 

     In particular, if you are going to be transferring your modules
     between computers, you must use some procedure that will preserve all
     the DEF files' dates. 

     This is probably a good place to point out that, when you use OBJ
     files, you are not protected by this module version checking. 

     




     4.4 Compiler directives


     Certain compiler code generation options may be set through directives
     included in the program text.  These directives must appear
     immediately at the beginning of a comment; multiple directives may be
     entered in a single comment by separating them by commas.  Example

          (* $S-, $R+ *)

     A '+' sets the directive to TRUE, a '-' sets it to FALSE, and a '='




     The Compiler                                                        18
     

     pops the directive's value prior to the last '+' or '-'.

     The following compiler directives are defined:

     $A                Alignment. Default $A+. If enabled, all new variables
                       declared are aligned on a word boundary.  Record
                       fields are packed (not aligned) regardless of the
                       setting of this option. 

     $S                Stack overflow checking.  Default $S+. If enabled,
                       stack overflow checking is performed on entry to a
                       procedure and when copying open arrays to a
                       procedure's local stack frame. 

     $R                Range checking.  Default $R+. If enabled, before any
                       assignment is made to a variable of a subrange type,
                       the value to be assigned is tested against the limits
                       of the subrange type. 

     $T                Array subscript and NIL pointer checking.  Default
                       $T+. If enabled, any time a subscript operation is
                       performed on an array, the subscript value is checked
                       to confirm that the operation would not generate an
                       address outside the bounds of the array.  In
                       addition, before a pointer is dereferenced, its value
                       is checked for NIL.

     $L                Generate line number information.  Default $L-. If
                       this option is enabled, the compiler will include a
                       list of source code line numbers and their
                       corresponding object code offsets in the output
                       file.  This line number information is passed on to
                       the .DBG file when the program is linked with the /L
                       option. 

     


     4.4.0.1 Benchmarks

     If you are going to benchmark the code generated by this compiler,
     please disable the generation of runtime error checking on all the
     compilers involved in the comparison. 

     We feel compelled to spell this out because some other vendors'
     products do not generate runtime error checking by default. 

     




     4.5 Runtime errors




     The Compiler                                                        19
     



     When, during the execution of a program, a runtime error is detected,
     the runtime error handler will terminate the program and write out a
     message indicating the type of error encountered and its location (PC
     address). 

     To find the location of the error in the source code, run DBG2MAP
     against the .DBG file generated by M2LINK for this program.  Scanning
     the .MAP file created, you should be able to always determine the
     module and procedure where the error occured.  If the $L+ directive
     was used when compiling the module in question and the /L option was
     used when linking the program, the error location can be pinpointed to
     the offending line by scanning the line number information at the end
     of the .MAP file. 

     


     4.5.1 Trapping runtime errors in your program

     The Library module System provides you with a means of intercepting
     runtime errors.  The following are the currently defined runtime error
     numbers that may be passed to your error handler routine:

          0   stack overflow ($S option)
          1   range error ($R or $T option)
          2   integer/cardinal overflow (divide by zero)
          3   floating point error
          4   function did not execute a RETURN
          5   HALT was invoked




     4.6 Compiler size limits


     The following are the code and data size limits imposed by this
     compiler:

       -  A string constant cannot exceed 80 characters.  This is also the
          limit set for the size of any identifier. 

       -  When using the HUGE memory model, each compilation module is
          assigned its own data segment, which can be up to 64k in size. 
          In the data segment, the compiler allocates the space for all the
          module's global variables and some of the module's constants. 

       -  When using the LARGE memory model, all the modules' data are
          combined, at link time, into a single data segment (64k
          maximum). 





     The Compiler                                                        20
     

       -  The maximum size of a data structure is 65532 bytes. 

       -  The maximum amount of space allocated for variables local to a
          procedure is 32000 bytes. 

       -  The compiler will also refuse to generate the code to pass, in a
          procedure call, by value, a parameter greater than 65000 bytes in
          size. 

     The following are the compiler's internal limits:

       -  The maximum number of different (namewise) identifiers that can
          be processed in a single compilation is 2000. May be overwritten
          at compiler invocation. 

       -  The total number of characters in all the different (namewise)
          identifiers processed cannot exceed 12000 characters.  May be
          overwritten at compiler invocation. 

       -  No single procedure can be translated into more than 10k of
          object code. 

       -  An array of 8k bytes is used to keep track of all the initialized
          data for a module.  This imposes a limit on the total amount of
          string, real and long constants used in the compilation module. 




     4.7 The language supported


     This release of the compiler will translate a program written in the
     Modula-2 language as defined by Niklaus Wirth in the 3rd edition of
     his book "Programming in Modula-2", with the exceptions noted bellow:

     

       -  Integer and Cardinal arithmetic overflow is not detected. 

       -  ASM is a reserved word in this implementation. 

       -  For those programmers that "grew up" in the Hex world, a way to
          define CHAR literals in Hex is provided: 20X corresponds to the
          "space" character in ASCII.

     


     4.7.1 LONGINT and LONGCARD

     This compiler implements the standard types LONGINT and LONGCARD.





     The Compiler                                                        21
     

     Operands of the type LONGINT or LONGCARD may appear in any expression,
     just like INTEGER or CARDINAL. But that is about it! 

     Subranges of these types are not supported. 

     No standard procedure, except INC, DEC and the ones listed later in
     this document will accept operands of one of these types. 

     A variable of type LONGINT or LONGCARD cannot be used as the control
     variable in a FOR loop.  Neither can CASE labels be of a LONG type. 

     Constants of type LONGINT or LONGCARD can be coded in decimal only and
     must be terminated by an 'L' if the value is less than 65536. Example

          123L and 123567 are valid LONGCARD or LONGINT constant

          -1L and -348762 are valid LONGINT constants


     4.7.2 LONGREAL

     The standard type LONGREAL is implemented. 

     The rules for the use of LONGREALs are the same as for REALs.

     The types REAL and LONGREAL are not compatible, and no automatic
     conversion from one type to another is ever performed -- the standard
     procedures SHORT and LONG should be used to convert between these
     types. 

     Constants of type LONGREAL are no different from REAL constants.  The
     type of the constant is determined by context.  You may, however,
     "type" a constant by the use of the SHORT or LONG procedure.  Ex:

          CONST longreal1 = LONG(1.0);


     4.7.3 Additional or augmented standard procedures


     4.7.3.1 NEW and DISPOSE

     NEW and DISPOSE have been deleted from the language definition in the
     3rd edition of Wirth's book.  We implement them thus:

          NEW(p)

     Invokes the procedure ALLOCATE, which must conform to the type:

          PROCEDURE ( VAR ADDRESS, CARDINAL )

     passing along p and the size of the object p is defined as pointing
     to. 




     The Compiler                                                        22
     


          DISPOSE(p)

     Invokes the procedure DEALLOCATE, which must conform to the type:

          PROCEDURE ( VAR ADDRESS, CARDINAL )

     passing along p and the size of the object p is defined as pointing
     to. 

     The procedures ALLOCATE and DISPOSE must, therefore, be defined in the
     module using NEW and/or DISPOSE, or imported from some other module,
     like Storage.

     


     4.7.3.2 LONG and SHORT

          PROCEDURE LONG( INTEGER ) :LONGINT;

          PROCEDURE LONG( CARDINAL ) :LONGCARD;

          PROCEDURE LONG( REAL ) :LONGREAL;

          PROCEDURE SHORT( LONGINT ) :INTEGER;

          PROCEDURE SHORT( LONGCARD ) :CARDINAL;

          PROCEDURE SHORT( LONGREAL ) :REAL;

     LONG takes an INTEGER, CARDINAL or REAL and converts it into a LONGINT
     LONGCARD or LONGREAL, respectively. 

     SHORT takes a LONGINT, LONGCARD or LONGREAL and converts it into an
     INTEGER, CARDINAL or REAL, respectively. 

     


     4.7.3.3 FLOAT and TRUNC

     With our two integer/cardinal and real sizes, here is the behavior of
     the TRUNC and FLOAT procedures. 

          PROCEDURE FLOAT( CARDINAL ) :REAL;

          PROCEDURE FLOAT( LONGCARD ) :LONGREAL;

          PROCEDURE TRUNC( REAL ) :CARDINAL;

          PROCEDURE TRUNC( LONGREAL ) :LONGCARD;





     The Compiler                                                        23
     

     




     4.8 Objects exported by the pseudo module SYSTEM


     4.8.0.1 TYPE BYTE

     Takes 1 byte of storage.  Only assignment is defined for this type. 
     If the formal parameter of a procedure is of type BYTE, the
     corresponding actual parameter may be of any type that takes 1 byte of
     storage. 

     If the formal parameter of a procedure is of type ARRAY OF BYTE, the
     corresponding actual parameter may be of any type. 


     4.8.0.2 TYPE WORD

     Takes 1 word (2 bytes) of storage.  Only assignment is defined for
     this type.  If the formal parameter of a procedure is of type WORD,
     the corresponding actual parameter may be of any type that takes 1
     word of storage. 

     If the formal parameter of a procedure is of type ARRAY OF WORD, the
     corresponding actual parameter may be of any type.  Care should be
     taken in this case, as the size of the parameter passed is rounded up
     to an even size. 


     4.8.0.3 TYPE ADDRESS

     The type ADDRESS is compatible with all pointer types.  ADDRESS itself
     is defined as a POINTER TO WORD. In this implementation, the type
     ADDRESS is not compatible with any arithmetic type.  This is due to
     the fact that the Intel 8086 series processors use segmented
     addresses.  It would not be hard to implement automatic conversions
     between LONGCARD and ADDRESS but it is felt that this would be
     contrary to the spirit of the language, whereby the compiler is not
     expected to perform any "magic" tricks.  Instead, two functions are
     provided for that purpose: FLAT and PTR.

     In release 1.2 we relaxed the above a little.  ADDRESS + CARDINAL and
     ADDRESS - CARDINAL are legal expressions.  The CARDINAL is added or
     subtracted from the offset portion of the ADDRESS and the result is
     still an ADDRESS.

     Also, INC and DEC can take an ADDRESS as their first argument.  The
     operation is, however, performed on the offset portion of the ADDRESS
     only. 





     The Compiler                                                        24
     

     


     4.8.0.4 SEG and OFS

     These are field definitions for POINTER types.  If you import these,
     you may access the segment or offset portions of a pointer variable
     using regular field selection syntax.  Example

          pointer.SEG :segment portion of pointer


     4.8.0.5 PROCEDURE ADR

     ADR( designator ) Returns the address of designator (type ADDRESS).


     4.8.0.6 PROCEDURE FLAT

     FLAT( ADDRESS ) returns a LONGCARD "flat" address. 


     4.8.0.7 PROCEDURE PTR

     PTR( LONGCARD ) returns an ADDRESS corresponding to the "flat" address
     represented by the LONGCARD.


     4.8.0.8 PROCEDURE SEGMENT

     SEGMENT( designator ) returns the segment portion of the address of
     'designator'. Example:

          DX := SEGMENT( buffer ); would assign to DX the segment value of
          ADR(buffer).


     4.8.0.9 PROCEDURE OFFSET

     OFFSET( designator ) returns the offset portion of the address of
     'designator'.


     4.8.0.10 PROCEDURE NEWPROCESS

     NEWPROCESS(p:PROC; a:ADDRESS; n:CARDINAL; VAR p1:ADDRESS)

     creates a new process whose entry point is p and workspace is at a for
     n bytes.  p1 is the new process pointer.  This process is not
     activated until a TRANSFER to p1 is done. 

     The starting priority of the new process is the current processor
     priority at the time NEWPROCESS is invoked (please refer to the




     The Compiler                                                        25
     

     section on Module Priorities).


     4.8.0.11 PROCEDURE TRANSFER

     TRANSFER( VAR p1, p2 :ADDRESS)

     suspends the current process, assigning it to p1 and resumes p2.  The
     current process' value is assigned to p1 only after p2 has been
     identified; it is, therefore, okay for p1 and p2 to be the same. 

     The process is resumed at the same priority level that it was running
     at, at the time of suspension. 


     4.8.0.12 PROCEDURE IOTRANSFER

     IOTRANSFER( VAR p1, p2 :ADDRESS; intVector :CARDINAL )

     issues a TRANSFER from p1 to p2 (just the way TRANSFER does it) after
     installing the current process for reactivation when an interrupt
     comes in through interrupt vector intVector. 

     When the interrupt occurs, the interrupt vector is reloaded with its
     previous value.  A TRANSFER is done to the I/O process (the one that
     issued the IOTRANSFER) such that p2 now contains the value of the
     process that was running when the interrupt occured. 


     4.8.0.13 ASSEMBLER

     An 8086 inline assembler is provided.  Once ASSEMBLER is imported from
     SYSTEM, you can enter inline assembler code by bracketing it with the
     keywords ASM and END.

     Assembler input is free form.  Comments are entered as in regular
     Modula-2. Example

          loop:   CMP  BYTE [SI], 0   (*end of string?*)
                  MOV  BYTE [DI], [SI]
                  INC  SI  INC DI     (*increment pointers*)
                  JMP  loop

     The assembler accepts all the 8086/8088 opcode mnemonics.  Address
     operands can be coded in just about any form acceptable to other
     assemblers, except that the only operator supported if '+'. Operand
     type overrides are: WORD, BYTE, FAR, NEAR and are not to be followed
     by the keyword POINTER or PTR. Example

          label:  MOV  AX, ES:[BX,DI+5]
                  MOV  AX, ES:5[DI+BX]
                  MOV  WORD [5], 1
                  CALL NEAR [DI]




     The Compiler                                                        26
     

                  TEST BYTE i+2, 1

     All the mnemonics and register names must be entered in upper case. 
     In case you need to use a Modula-2 name that conflicts with one of the
     assembler reserved symbols, you may precede it with a '@'. Example

          MOV @AX, AX

     would generate a move from register AX to variable AX.

     All modula-2 variables can generaly be accessed in assembler.  Record
     field names are not accessible from assembler.  The assembler will not
     automatically do anything for you.  For example: if you specify a VAR
     parameter as an operand to an instruction, you are naming the address
     of the pointer to the actual parameter.  Example

          PROCEDURE p( VAR done :BOOLEAN );
          ...
          ASM
               LES  DI, done
               MOV  BYTE ES:[DI], TRUE
          END;

     is the correct way of storing TRUE in done. 

     The following types of constants may be accessed in assembler:
     INTEGER, CARDINAL, BOOLEAN, CHAR and enumeration constants. 

     All labels declared inside an ASM section are local to that section of
     code.  But labels names cannot match some name known in the scope of
     the current procedure.  Labels can only be referenced in jump
     instructions. 

     All jumps are optimized by the compiler.  There is, therefore, no need
     (or capability) to specify the size of a jump.  In particular, the
     compiler will turn a conditional jump out of range into a reverse
     conditional jump over a far jump to the original destination. 

     Remember, this is a Modula-2 compiler, not an assembler!  The inline
     assembler capability is provided for use in exceptional situations
     only. 

     


     4.8.0.14 ASSEMBLER - 8087 support

     All the 8087 math coprocessor instructions are supported by the inline
     assembler.  There are some restrictions, however. 

     Only the following operand types are supported by the load and store
     instructions: INTEGER, LONGINT, REAL and LONGREAL. You may not,
     therefore, load or store a value in temporary real or decimal format. 




     The Compiler                                                        27
     


     The meaning of the "no operand" form of the arithmetic instructions
     was retainned:

          FADD, FSUB, FMUL and FDIV all operate on the two top elements of
          the 8087 stack, using ST(1) as the destination and removing ST.

          FSUBR subtracts ST(1) from ST (FDIVR divides ST by ST(1)),
          leaving the result in ST(1) and removing ST.

     The 2 operand format of the arithmetic instructions was not
     implemented.  You may not, therefore, specify a destination register
     other than ST, except in the "and pop" versions of the instructions. 

     With a regular assembler, in register to register operations you can
     specify the register that gets the result of the operation (the
     destination register).  By definition, the destination register is
     also the first operand of the instruction. 

     With our inline assembler, ST is always the destination of the
     operation, except in the "and pop" form of the instructions, in which
     case the register specified in the instruction "gets the result". 

     For consistency, we decided that ST should always be the first operand
     of the instruction, even when the "and pop" form is used. 

     The meaning of FSUBP, FSUBRP, FDIVP and FDIVRP is, therefore:

          FSUBP ST(1) means FSUBRP ST(1),ST -> ST(1):=ST-ST(1)

          FSUBRP ST(1) means FSUBP ST(1),ST -> ST(1):=ST(1)-ST

          FDIVP ST(1) means FDIVRP ST(1),ST -> ST(1):=ST/ST(1)

          FDIVRP ST(1) means FDIVP ST(1),ST -> ST(1):=ST(1)/ST

     and ST is popped. 

     




     4.9 The generated object code


     


     4.9.1 Data type representation

     CHAR              1 byte





     The Compiler                                                        28
     

     INTEGER           2 bytes 2's complement

     CARDINAL          2 bytes

     LONGCARD          4 bytes

     LONGINT           4 bytes 2's complement

     BOOLEAN           1 byte (1=TRUE, 0=FALSE)

     REAL              4 bytes Intel 8087 format. 

     LONGREAL          8 bytes Intel 8087 format. 

     BITSET            1 word.  0 is low order bit, 15 is high order bit. 

     Enumerations      1 byte

     SETs              1 to 8 words (sets of up to 256 elements)

     POINTERs          4 bytes in Intel 8086/88 format

     PROCEDUREs        4 bytes POINTER to procedure entry point

     Addresses are represented in the default Intel 8086 format:

          1 word          byte offset

          1 word          segment

     Numeric values are likewise represented the way the Intel 8086
     processor family likes them: low order byte first, high order byte
     last. 

     


     4.9.2 The runtime memory map

     Currently, the compiler generates code using the "large" or "huge"
     memory model only. 

     In the "huge" memory model, each module has its own data and code
     segments. 

     In the "large" memory model, each module has its own code segment. 
     The entire program has one data segment. 

     The linker binds all the code segments first, and then all the data
     segments.  The stack is allocated above the data segments.  All the
     remainning memory is available for the heap. 

     When a program is loaded for execution, here is what the memory looks




     The Compiler                                                        29
     

     like:


          From low to high addresses:

          0         ----------------------------------------------
                    I  Interrupt vectors                         I
                    I  DOS                                       I
          PSP       I  Program segment prefix                    I
          PSP+100h  I  Program Code segments                     I
                    I  Program Data segment(s)                   I
          StackSeg  I  Stack                                     I
          HeapTop   I  Heap                                      I
                    I  ...                                       I
                    I  DOS Command (resident portion)            I
          MemTop    ----------------------------------------------

     Label names on the left are the ones exported by System.

     This system uses interrupt vector 192 (0C0H) at location 0000:0300.
     Interrupt 192 is issued by a program when a runtime error occurs, when
     HALT is invoked or when a coroutine other than the main one terminates
     via a return. 

     The first word (offset 0) in every code segment contains the data
     segment value for that particular module (for the program, in the case
     of the "large" memory model. 


     4.9.3 Procedure calling conventions

     Procedure parameters are pushed into the stack 1st argument first. 
     Control is then transferred to the procedure through a FAR call.  It
     is the called procedure's responsibility to remove its parameters from
     the stack before returning. 

     


     4.9.3.1 Parameter passing (all except open array parameters)

     If the formal parameter of a procedure is a value parameter, the
     actual parameter is copied into the stack. 

     If the formal parameter is a variable parameter (VAR), the address of
     the actual parameter is pushed into the stack (first the segment
     portion of the address and then the offset part). 

     


     4.9.3.2 Parameter passing (open array parameters)





     The Compiler                                                        30
     

     If the formal parameter is an open array, the address and HIGH value
     of the corresponding formal parameter are pushed into the stack (HIGH
     value first, and then the address, as above). 

     If the open array parameter is a value parameter, the value of the
     actual parameter is copied into the stack on procedure entry. 

     


     4.9.3.3 Returning values from a function procedure

     One byte results are returned in AL, two byte results are returned in
     AX, and four byte results are returned in DX:AX (DX has the high order
     part of the result). 

     LONGREALs are returned in the stack, at a location reserved for that
     purpose by the caller.  When invoking a function that returns a
     LONGREAL, an extra parameter is pushed onto the stack: the two byte
     offset, in the SS segment, of where to place the result.  This choice
     will make it easy to allow for the return of arbitrary structures from
     a function, should the language standard go that way, while at the
     same time allowing for full reentrancy of the code generated. 

     




     4.10 Module priorities


     Eight module priority levels are supported in this implementation,
     from 0 (highest priority) to 7 (lowest).

     Priorities are implemented by masking off, on the 8259 interrupt
     controller, all the interrupts at or below the current priority
     level. 

     Because the PC usually runs with several of the interrupt levels
     disabled, it is not easy to decide what the interrupt mask for the
     value for "no priority" should be for your particular application. 
     The implementation of NEWPROCESS, therefore, assumes that you have
     enabled all the interrupts that your program will be capable of
     processing before you create your processes.  The value in the
     interrupt mask register of the 8259 at the time of process creation
     will determine the initial priority level of this process, once it
     gets started.  Because of this, invoking NEWPROCESS from inside a
     priority module is usually not what you want to do! 

     Execution priorities are changed when entering/exitting procedures in
     modules that have a priority specification, and during the execution
     of some form of a TRANSFER.




     The Compiler                                                        31
     


     We highly recommend that you study the communications program
     provided, paying particular attention to the module Kernel, for an
     example of how to use priorities with this system. 

     NOTE: The compiler does not restrict the priority level specified (any
     number will do).  You must, therefore, exercise care in defining a
     module's priority level.  On the other hand, it is easy to add
     additional priority levels by simply modifying the runtime module
     M2Procs.

     




     4.11 Memory models


     In general, you may compile the same code under either the LARGE or
     the HUGE memory model. 

     The only factor to consider is when using inline assembler. 

     Under the HUGE memory model, the compiler generates code to reload DS
     after any invocation of an imported procedure or a VARiable
     procedure.  Under the LARGE memory model, this is not necessary as a
     single data segment is defined.  If you write some inline assembler
     code that modifies DS, please restore it, even if the next thing you
     do is a RETurn; this way, your routine will work regardless of whether
     you use the LARGE or the HUGE memory model. 

     Under the HUGE memory model, access to external variables is done
     through an indirect pointer, whereas in the LARGE memory model the
     external variable resides in the program's ONLY data segment and is,
     therefore directly accessible. 

     



















     Using OBJ files                                                     32
     







                                    Chapter 5

                                 Using OBJ files



     As long as you use this system to write Modula-2 programs for the DOS
     environment only, there is virtually no reason to use OBJ files.  But,
     in case you have to... 

     You condition the compiler to generate OBJ files by setting the
     environment variable M2OUPUT to OBJ.

          set M2OUTPUT=OBJ

     To link OBJ files you must exit the MC environment (or invoke the DOS
     shell) and use some OBJ file linker. 

     Also, with OBJ files, there is no module version checking done for
     you.  Of course, if you keep your ".MAK" files up to date, you should
     not encounter any problems. 

     




     5.1 GenLink


     To help you figure out which files need to be linked, we provide a
     utility (GenLink) that generates a LINK answer file.  The LINK answer
     file created by GenLink lists all the Modula-2 OBJ files that are
     required to link your program. 

     Since your program, most likely, requires modules written in another
     language (or you would not be using OBJ files, right?!), you will have
     to edit the file created by GenLink to make it suitable. 

     




     5.2 Foreign Modules






     Using OBJ files                                                     33
     

     To let the Modula-2 compiler know about modules written in other
     languages, you must write FOREIGN DEFINITION modules.  A foreign
     definition modules is a regular definition module, with the exception
     of the module's header, which goes like this:

          FOREIGN [C|PASCAL] DEFINITION MODULE modName;

     where the 'C' or 'PASCAL' qualifier is optional. 

     


     5.2.1 External names

     Names of public variables and procedures in foreign modules are
     encoded in one of 3 ways:

          In a regular FOREIGN (neither C nor PASCAL) module, the
          identifiers are encoded in the object files as you enter them.

          In a FOREIGN C module, identifiers are written out preceded by a
          '_' character.

          In a FOREIGN PASCAL module, identifiers are converted to all
          upper case.

     WARNING: As currently implemented, SET and STRING constants defined in
     a FOREIGN DEFINITION module, cause the compiler to generate external
     references to these.  These "constants" should, therefore, be
     allocated space and properly initialized in the foreign module. 

     


     5.2.2 Implementation

     FOREIGN modules are not expected to have an initialization procedure,
     and the compiler will not generate these initialization calls, as in
     the case of regular Modula-2 modules. 

     


     5.2.2.1 FOREIGN C modules

     When invoking a routine defined in a FOREIGN C module, the arguments
     are pushed onto the stack in reverse order, as per C's custom.  Also,
     the caller will remove the arguments off the stack upon return from
     the subroutine. 

     Since C, unlike Modula-2, supports (?) the passing of a variable
     number of arguments to a function, the symbol '...' may be used at the
     end of a PROCEDURE parameter list definition to indicate that an




     Using OBJ files                                                     34
     

     indeterminate number of arguments may be passed.  Example:

          PROCEDURE sum( n:INTEGER; ... ) :INTEGER;

     defines a function that takes n integers and returns their sum.  It
     could, actually, be implemented in Modula-2 thus:

          PROCEDURE sum( n:INTEGER; ... ) :INTEGER;
          VAR p   :POINTER TO INTEGER;
              res :INTEGER;
          BEGIN
              res := 0;
              p := ADR(n) + 2;
              WHILE n > 0 DO
                  res := res + p^;
                  INC( p, 2 );
                  DEC( n );
              END;
              RETURN res;
          END sum;

     Good luck! 

     In addition to being useful to define functions that take a variable
     number of parameters, the use of '...' is also a handy (?!) way of
     improving the odds that the arguments are passed in a form that C will
     like. 

     


     5.2.2.2 Parameter passing

     The form in which the individual parameters are passed is always the
     same, regardless of whether the procedure is in a foreign module or
     not.  The exception is when you use '...'.

     When passing parameters that correspond to the '...' in the procedure
     heading, the compiler follows the default C rules: Everything is
     passed by value, except for arrays, which are passed by reference
     (their address, instead of their value, is pushed onto the stack). 

     Modula-2 does not allow functions to return structured types.  Some C
     compilers return structured values by actually returning a pointer to
     those values in the DX:AX register pair, which is just the way that
     Fitted Modula-2 returns pointers!  With these, therefore, you could
     define

          struct someStruct cfunct()

     as

          TYPE someStructPtr = POINTER TO someStruct;




     Using OBJ files                                                     35
     

          PROCEDURE cfunct() :someStructPointer;

     


     5.2.3 In the real world...

     Knowing the parameter passing conventions used by the compiler you
     should have no trouble writing assembly language modules to be invoked
     by Modula-2.

     With the help provided (FOREIGN C and '...'), it should be easy enough
     to interface Modula-2 to C. But is it, really?  Not quite! 

     There are two main problems that you will have to overcome.  One, is
     the choice of a suitable memory model.  Our LARGE memory model is
     probably a better choice than HUGE, as some compilers require DS to
     always point to DGROUP.

     The other problem, is the set of requirements imposed by each
     language's runtime system.  Since we provide all the source code for
     our runtime, your best bet will probably be to modify our system to
     suit theirs.  Modules that are obvious candidates for "adaptation" are
     System and Storage; In their current state, they are virtually
     guarateed to not work with another vendor's runtime system, and they
     are a basis on which many other library modules depend. 

     





























     The Text Editor                                                     36
     







                                    Chapter 6

                                 The Text Editor



     The text editor included in this package has all the features that you
     have come to expect from a basic program editor: the ability to
     insert, delete, move, find and replace text; support for concurrent
     editing of multiple files (as many as will fit in memory) in separate
     windows (as many as will fit on the screen) with the ability to copy
     or move text from window to window. 

     Although you may load the same file in two different windows, the
     editor will not be aware of the fact and will treat the two copies as
     two different files. 

     The only preset limitation in the editor is that it cannot handle
     files bigger than 64k. This decision was justified by the fact that
     Modula-2 programs are supposed to be modular.  File load/save speed
     was the overriding factor here. 

     All the text editor keys are defined by the user through the use of
     the EDCONFIG program.  When the editor starts, it expects to find the
     file M2ED.CFG in the current PATH.

     M2ED.CFG will also tell the editor what display colors (attributes) to
     use for the Status line, for Normal text and for Marked text blocks. 

     Finally, M2ED.CFG also contains the default settings for the TAB size
     value, as well as whether or not the editor will expand the tabs
     inserted into the text spaces.  Note: Tabs present in a file will not
     be expanded to spaces by the editor. 

     To get you started, we provide a M2ED.CFG file with the following
     definitions:

          Cursor left                    : Left
          Cursor right                   : Right
          Cursor up                      : Up
          Cursor down                    : Down
          Previous word                  : ^Left
          Next word                      : ^Righ
          Page up                        : PgUp
          Page down                      : PgDn
          Cursor to beginning of line    : Home
          Cursor to end of line          : End




     The Text Editor                                                     37
     

          Cursor to top of window        : ^Home
          Cursor to bottom of window     : ^End
          To beginning of file           : ^PgUp
          To end of file                 : ^PgDn
          Current line to top of window  : AltT
          Toggle insert/overtype         : Ins
          Delete character under cursor  : Del
          Delete previous character      : ^H
          Delete Current Line            : ^Y
          Delete to EOL                  : AltY
          Delete Word                    : ^D
          Indent Line                    : F4
          Unindent Line                  : F3
          Indent Block                   : Alt=
          Unindent Block                 : Alt-
          New file                       : AltN
          Read file                      : AltR
          Write block                    : AltW
          Save file                      : AltS
          Open window                    : ^O
          Close Window                   : ^C
          Next window                    : F2
          Previous window                : aF2
          Split screen                   : ^S
          Mark beginning of block        : F7
          Mark end of block              : F8
          Goto beginning of block        : AltB
          Goto end of block              : AltE
          Clear block marks              : AltH
          Copy block                     : AltC
          Delete block                   : AltD
          Move block                     : AltM
          Search forward                 : F5
          Search backwards               : aF5
          Replace forward                : F6
          Replace backwards              : aF6
          Global replace                 : ^F6
          Repeat last search/replace     : F1
          Goto next error                : ^E
          Goto previous error            : ^P
          Goto line                      : AltG
          Set options                    : AltO
          Redraw the screen              : ^L
          Quit                           : AltQ













     The Linker                                                          38
     







                                    Chapter 7

                                   The Linker



     The linker is invoked by the command line

          M2LINK myprog [/s n] [/h n] [/o] [/l] [/swap [path]]

     where 'myprog' is the main module of the program you are creating. 
     The options are thus:

     /s n              n is the size of the stack to allocate (default is
                       8192).

     /h n              n is the amount of space to reserve for the heap (in
                       paragraphs).  The default is all the free memory. 

     /o                invokes the optimizer.  The optimizer prevents the
                       output, to the object file, of all the procedures
                       that are part of included modules but are not
                       referenced.  This will make your final EXE files
                       smaller. 

     /l                tells the linker to process the line number
                       information in the .M2O files and include it in the
                       .DBG file.  This option is disabled if the optimizer
                       is invoked. 

     /k                tells the linker to ignore module keys, i.e.  to not
                       check for module version compatibility.  This option
                       should be used with extreme care. 

     /swap [path]      tells the linker to use a swap file.  Code segments
                       will be kept in this swap file instead of in main
                       memory during the link process.  This allows you to
                       link larger programs. 

     The linker creates two files: the .EXE file is your executable
     program, the .DBG file is a file containning symbol information for
     use by other utilities (see Map file generator, Profiler).

     If the /swap directive is used, a swap file is created.  You may
     select the path (drive:directory) where the swap file is to be
     created.  Example:





     The Linker                                                          39
     

          M2LINK myprog /swap D:




     7.1 Module keys


     The module header record and the import records written out by the
     compiler to the object file are stamped with the date of the .DEF file
     that was processed - this becomes the module key.  The linker will
     assure that these module keys in the module header of the imported
     module and in the import record match; If they do not match, both
     modules were not compiled using the same definition module. 

     Because of the use of module keys, it is imperative that the date of
     the distributed .DEF files not be modified unless you intend to
     recompile the implementation modules. 

     When using OBJ files, you do not have the protection of Module keys. 

     



































     Other utilities                                                     40
     







                                    Chapter 8

                                 Other utilities



     




     8.1 Editor configurator


     This program lets you define the keystrokes to be used to invoke all
     the editor commands, the screen attributes (colors) to use, and the
     default editor options. 

     Invokation:

          EDCONFIG

     EdConfig presents you with a menu from which you may elect to modify
     the default editor options, the display attributes, or configure the
     editor commands. 

     If you are creating a new configuration file, you must configure the
     editor commands. 

     If you chose to configure the editor commands, you will be prompted
     for a log file (default M2ED.HLP), a text file in which all of your
     command choices will be saved.  You may print this file to create a
     quick reference card.  EDCONFIG will then prompt you for the key
     sequence to be used for each editor command.  For each command,
     EDCONFIG will also give you the option of defining an alternate key
     sequence. 

     When you select Quit, the program will prompt you for an output file,
     the default being 'M2ED.CFG'.

     




     8.2 Map file generator





     Other utilities                                                     41
     



     Invokation:

          DBG2MAP program_name

     Reads the .DBG file created by M2LINK and creates a DOS LINK
     compatible .MAP file. 

     




     8.3 Make and the Makefile generator


     These utilities eliminate the burden, on the user's part, of having to
     figure out which modules are affected and, therefore, need to be
     recompiled as a result of any changes to particular definition
     modules. 

     GENMAKE creates the .MAK file, the file with all the dependencies
     (this is the hard part) whereas MAKE (built into the compiler) will
     insure that these dependencies are observed when updating the object
     files. 

     GENMAKE Invokation:

          GENMAKE main_module_name [/l] [/obj]

     generates the .MAK file containning all the module dependencies for
     the named program.  It does this by reading all the IMPORT statements
     in the main module and, recursively, generating the dependency lists
     for all those modules.  GENMAKE will indeed read all the .MOD and .DEF
     files involved. 

     The /l option instructs GenMake to include the directories listed in
     the environment variable M2LIB in its search path.  Otherwise, only
     the modules in the current directory will be taken into consideration
     when creating the makefile. 

     The /obj option tells GenMake that you will be using the compiler to
     generate OBJ files instead of M2O files. 

     MAKE invocation: see "Running the Compiler".

     MAKE will invoke the compiler as needed to assure that all the
     dependencies in the make file are observed.  MAKE is dumb in that it
     will just run through the makefile sequentially.  It was GENMAKE's
     responsibility to see that the dependencies are listed in a proper
     sequence.  Please keep this in mind if you should edit a makefile! 





     Other utilities                                                     42
     

     




     8.4 The execution profiler


     Invokation:

          M2Prof program_name

     The profiler will ask you for the name of the .DBG file to use (if it
     cannot find it) and give you an option of profiling your entire
     program (generating an execution profile by module), a particular
     module (generating an execution profile by procedure in that module)
     or a particular procedure (generating an execution profile by line in
     the procedure). 

     Upon program termination, the profiler outputs the list of all the
     modules/procedures/lines profiled, ranked by execution time, to a file
     of your choice. 

     This profiler is not that versatile, but it is useful nevertheless. 
     It proved instrumental in pinpointing some obvious areas for
     improvement in the compiler (Oh, we did not tell you, did we?  This
     compiler was written in the language it compiles -- Modula-2 -- and
     this system was used as our primary development tool since very early
     in the development process). 

     


























     The Library Modules                                                 43
     







                                    Chapter 9

                               The Library Modules



     For complete information on what each library module provides, as well
     as its proper usage, please refer to the .DEF files. 

     In addition, the source code of all the library modules is available
     to all the registered users (see the order form in the back of this
     document for details). 

     




     9.1 Release 2.0 libraries


     In this release, several library modules were "extended". We have not
     created any source level incompatibility with previous library
     modules, that we are aware of.  But you will have to recompile all
     your programs, as they will not link with the new library modules. 

     If you customized any of the ASM modules, please note that their
     format was slightly changed and a module initialization routine is now
     included. 

     




















     The runtime support system                                          44
     







                                   Chapter 10

                           The runtime support system



     The library module System contains the runtime system's initialization
     code.  In particular, special interrupt vectors are loaded with the
     addresses of routines (also in System) that will handle runtime errors
     and other abnormal program terminations.  In addition, the module
     Storage depends on System doing its stuff -- setting the HeapBase,
     HeapTop and MemTop variables. 

     Three other special modules are included in this package.  M2Reals,
     M2Longs and M2Procs. These modules provide support for specific
     language features. 

     M2Reals handles all the REAL and LONGREAL arithmetic and conversions. 
     In release 2, M2Reals checks for the presence of an 8087 math
     co-processor and uses it, if found. 

     M2Longs handles LONGINT and LONGCARD arithmetic. 

     M2Procs provides the coroutine support. 



























     Shareware                                                           45
     







                                   Chapter 11

                                    Shareware



     This software package is distributed as Shareware.

     If you try this program and continue to use it, you are expected to
     register with us. 

     This software can be freely distributed, as long as no money is
     charged for it, all the files are included, unmodified, and with their
     modification dates preserved. 

     This software cannot be distributed as a part of, or in conjunction
     with, another product. 

     This software cannot be used in a commercial environment without the
     payment of a $29 (as of this writing) license fee per copy. 

     Our success will depend not only on the quality of this software but
     on the willingness of every individual user to "support" its
     developers.  If you use this product, please send in the registration
     form in the back of this document, along with your registration fee. 
     For $39 (as of this writing) we will send you the latest version of
     this software and all the library and runtime support source code
     (what a bargain!).  This source code is made available to registered
     users only! 

     Whether or not you use this product, please give complete copies of
     this software to others. 

     

















     License terms                                                       46
     







                                   Chapter 12

                                  License terms



     Before you register this product and become a licensed user, you are
     granted a limitted license to evaluate the product to determine
     whether or not it will fit your needs.  Use of this system for any
     other purpose, before registration and without our written consent, is
     expressly forbidden. 

     Registered users are given a non-exclusive license to use this
     software on any machine that they have access to, but not on more than
     one at a time (the "treat this software like a book" idea). 

     Registered users may modify the source code provided to suit their
     needs, but this source code (in original or modified form) may not be
     distributed without the prior written consent of Fitted Software
     Tools.

     Registered users may include compiled portions of the library and
     runtime support code in the programs by them developed, and use or
     distribute these programs without payment of any additional license
     fees to Fitted Software Tools.

     
























     Support                                                             47
     







                                   Chapter 13

                                     Support



     Our basic philosophy is very simple: Without happy users, we do not
     have a business -- or, at least, we will not have one for long! 

     We will do everything in our power to assure that our users get the
     kind of support that they deserve and we can afford to provide. 

     Above all, we do not want to create false expectations on the part of
     our users, the reason for this chapter. 

     We currently provide our registered users with support by mail,
     through BIX (conference 'fst'), or through our BBS, at 214/517-4629.

     We cannot, of course, promise to fix any bug that you may find within
     a certain period of time.  As a matter of fact, we do not even promise
     to fix any and all bugs that you may find, but we will try...  When a
     fix is not imminent, we will try to give you a workaround procedure,
     so that you may go on with your work. 

     As we fix bugs, we will make the new versions of the affected programs
     available for download from the BBS. Should this not be acceptable to
     you, you may elect to have the fixes mailed to you, for $5 to cover
     media and handling charges. 

     We also make new product updates available for download off the BBS.

     Registered users have the option of getting software updates by mail
     instead of downloading them.  The current price of such updates is
     $12.

     















     Your input matters to us                                            48
     







                                   Chapter 14

                            Your input matters to us



     You can bet that this is serious!  We know, and you know, that there
     are many ways in which this system can be improved.  It is in our
     common interest that we agree on just how (what needs changing, what
     additional capabilities are needed) and when (let's take care of the
     more important stuff first!). 

     Maybe you like this software so much that you would hate to see us
     improve it in the wrong direction (ha, ha, ha)... 

     Maybe you find some weaknesses in this product that make it awkward to
     use. 

     Maybe even (God forbid!)  that one or more of those weaknesses make
     this software unusable for your purposes. 

     Whichever the case may be, we need to know about it, our future is at
     stake!!! 

     So, please!, fill out the survey form and send it in. 

     


























                       Your comments would be appreciated


     How did you first learn about this product?

          ---------------------------------------------------------

     Where did you get this software from?

          ( ) us                   ( ) a bulletin board
          ( ) a friend                 phone # ___ ___ ____
          ( ) a computer club      ( ) a shareware software distributor
          ( ) other ________________________

     Systems you intend to use this software on

          ( ) PC (8088/8086)       ( ) AT (80286)      ( ) 80386

     Typical system's configuration

          ( ) hard disk
          ( ) 512k       ( ) 640k
          ( ) extended memory
          ( ) expanded memory (EMS, EEMS)
          ( ) EGA adapter
          ( ) VGA adapter

     What programming languages do you use regularly?

          ---------------------------------------------------------

     What do you like the most about this system?

          _____________________________________________________________
          _____________________________________________________________
          _____________________________________________________________
          _____________________________________________________________
          _____________________________________________________________

     What do you NOT like about this system?

          _____________________________________________________________
          _____________________________________________________________
          _____________________________________________________________
          _____________________________________________________________
          _____________________________________________________________

     Other comments / suggestions:












                                   BUG REPORT

     We would like to think that our software is bug free, but we have been
     around a while. 

     So, if you uncover one of those nasty critters, please provide us with
     the information below, and whatever else that may help us duplicate
     the problem. 


     Name_____________________________________________

     Company__________________________________________

     Address__________________________________________

     City, State, Zip_________________________________

     Telephone _____________


     Version of the software in use:  ___________________________

     Machine in use (make and model): ___________________________

     Memory / Disks / Display type:   ___________________________

     Operating system used:           ___________________________

     Other system information that may be pertinent (PATH settings,
     CONFIG.SYS contents,...) 





     Problem description:























                                REGISTRATION FORM


     Please mail this form to:

          Fitted Software Tools
          P.O.Box 867403
          Plano, TX 75086

     to register your copy/copies of the Modula-2 compiler, register/order
     additional copies, and/or order updates. 

     The unauthorized distribution of the library and runtime support
     source code included in the distribution disks that you receive when
     you order a registered copy or update is specifically prohibited. 
     This source code is made available to registered users only. 

     If you are ordering multiple copies for your organization (or for you
     and your friends), we suggest that you order 1 of the $39 packages and
     the rest as $29 registrations. 


     Name_____________________________________________

     Company__________________________________________

     Address__________________________________________

     City, State, Zip_________________________________


     QTY
     ___   X   Registration @ $29.00                      _________

     ___   X   Registration & latest version @ $39.00     _________

     ___   X   floppy updates @ $12.00                    _________

               Sales tax (TX residents)                   _________

               Shipping outside USA and Canada $5.00      _________

     Total enclosed:                                      _________


     Disk format preferred (360k 5-1/4" is the default) ___________

     If ordering the latest version, please specify how long you are
     willing to wait for a new, if imminent, update ________________

     Version of the software (the one displayed in the compiler screen)
     that you are currently using __________

     





































































                           Table of Contents


     Chapter 1 Introduction                                           2

        1.1 Hardware requirements                                     3
        1.2 Software requirements                                     3
        1.3 For users upgrading to release 2                          3

     Chapter 2 Software installation                                  5

        2.1 Theory                                                    5
        2.2 Recommended setup for a system with 2 floppy drives
                                                                      7
        2.3 Recommended setup for a hard disk system                  7

     Chapter 3 A little tour through the system                       9

        3.1 The tour                                                  9

     Chapter 4 The Compiler                                           13

        4.1 Running the integrated compiler: MC                       14
        4.2 Running the freestanding compiler: M2COMP                 16
        4.3 The compilation process                                   16

              4.3.0.1 The input file                                  16
              4.3.0.2 The imported modules                            16
              4.3.0.3 The output file                                 17
              4.3.0.4 A warning                                       17

        4.4 Compiler directives                                       17

              4.4.0.1 Benchmarks                                      18

        4.5 Runtime errors                                            18

           4.5.1 Trapping runtime errors in your program              19

        4.6 Compiler size limits                                      19
        4.7 The language supported                                    20

           4.7.1 LONGINT and LONGCARD                                 20
           4.7.2 LONGREAL                                             21
           4.7.3 Additional or augmented standard procedures          21

              4.7.3.1 NEW and DISPOSE                                 21
              4.7.3.2 LONG and SHORT                                  22
              4.7.3.3 FLOAT and TRUNC                                 22

        4.8 Objects exported by the pseudo module SYSTEM              23






              4.8.0.1 TYPE BYTE                                       23
              4.8.0.2 TYPE WORD                                       23
              4.8.0.3 TYPE ADDRESS                                    23
              4.8.0.4 SEG and OFS                                     24
              4.8.0.5 PROCEDURE ADR                                   24
              4.8.0.6 PROCEDURE FLAT                                  24
              4.8.0.7 PROCEDURE PTR                                   24
              4.8.0.8 PROCEDURE SEGMENT                               24
              4.8.0.9 PROCEDURE OFFSET                                24
              4.8.0.10 PROCEDURE NEWPROCESS                           24
              4.8.0.11 PROCEDURE TRANSFER                             25
              4.8.0.12 PROCEDURE IOTRANSFER                           25
              4.8.0.13 ASSEMBLER                                      25
              4.8.0.14 ASSEMBLER - 8087 support                       26

        4.9 The generated object code                                 27

           4.9.1 Data type representation                             27
           4.9.2 The runtime memory map                               28
           4.9.3 Procedure calling conventions                        29

              4.9.3.1 Parameter passing (all except open array
                    parameters)                                       29
              4.9.3.2 Parameter passing (open array parameters)
                                                                      29
              4.9.3.3 Returning values from a function procedure
                                                                      30

        4.10 Module priorities                                        30
        4.11 Memory models                                            31

     Chapter 5 Using OBJ files                                        32

        5.1 GenLink                                                   32
        5.2 Foreign Modules                                           32

           5.2.1 External names                                       33
           5.2.2 Implementation                                       33

              5.2.2.1 FOREIGN C modules                               33
              5.2.2.2 Parameter passing                               34

           5.2.3 In the real world...                                 35

     Chapter 6 The Text Editor                                        36

     Chapter 7 The Linker                                             38

        7.1 Module keys                                               39

     Chapter 8 Other utilities                                        40

        8.1 Editor configurator                                       40
        8.2 Map file generator                                        40





        8.3 Make and the Makefile generator                           41
        8.4 The execution profiler                                    42

     Chapter 9 The Library Modules                                    43

        9.1 Release 2.0 libraries                                     43

     Chapter 10 The runtime support system                            44

     Chapter 11 Shareware                                             45

     Chapter 12 License terms                                         46

     Chapter 13 Support                                               47

     Chapter 14 Your input matters to us                              48













































GO.TXT

╔═════════════════════════════════════════════════════════════════════════╗
║        <<<<  Disk No 1080 MODULA-2 COMPILER (Disk 1 of 2)  >>>>         ║
╠═════════════════════════════════════════════════════════════════════════╣
║ The program and documentation for this program are archived, you must   ║
║ first unarchive the files on both disks in order to run the program     ║
║                                                                         ║
║ The best way to unarchive the files on these disks is to create a       ║
║ subdirectory and copy the files from the two disks into it, then        ║
║ unarchive the files by typing, PKXARC *.ARC (press enter)               ║
╚═════════════════════════════════════════════════════════════════════════╝

Directory of PC-SIG Library Disk #1080

 Volume in drive A has no label
 Directory of A:\

FILE1080 TXT      1388   6-27-89   9:58a
FM2CMP20 ARC    182893  11-29-88  12:35a
FM2DOC20 ARC     47196  11-30-88   8:56p
FM2UTL20 ARC    108550  11-21-88  11:53p
GO       BAT        38   6-02-88  10:11a
GO       TXT       771   6-27-89   3:59p
PKXARC   COM     12242   3-01-87   1:25a
        7 file(s)     353078 bytes
                        5120 bytes free