home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft_Programmers_Library.7z / MPL / pas / pasusrg.txt < prev    next >
Encoding:
Text File  |  2013-11-08  |  361.0 KB  |  9,833 lines

  1.  Microsoft(R) Pascal Compiler User's Guide
  2.  
  3.  
  4.  
  5.  ───────────────────────────────────────────────────────────────────────────
  6.  
  7.  
  8.  
  9.  Microsoft(R) Pascal Compiler
  10.  
  11.  for the MS-DOS(R) Operating System
  12.  
  13.  User's Guide
  14.  
  15.  
  16.  
  17.  ───────────────────────────────────────────────────────────────────────────
  18.  
  19.  
  20.  
  21.  Information in this document is subject to change without notice and does
  22.  not represent a commitment on the part of Microsoft Corporation. The
  23.  software described in this document is furnished under a license agreement
  24.  or nondisclosure agreement. The software may be used or copied only in
  25.  accordance with the terms of that agreement. It is against the law to copy
  26.  Microsoft Pascal on magnetic tape, disk, or any other medium for any
  27.  purpose other than the purchaser's personal use.
  28.  
  29.  
  30.  
  31.  (C) Copyright Microsoft Corporation, 1981, 1982, 1983, 1984, l985
  32.  
  33.  
  34.  
  35.  If you have comments about the software or this manual, complete the
  36.  Software Problem Report at the back of the Microsoft Pascal Reference
  37.  Manual and return it to Microsoft Corporation.
  38.  
  39.  
  40.  
  41.  Microsoft, the Microsoft logo, and MS are registered trademarks of
  42.  Microsoft Corporation.
  43.  
  44.  MS-DOS is a trademark of Microsoft Corporation.
  45.  
  46.  CP/M and CP/M-86 are registered trademarks, and CP/M-80 is a trademark of
  47.  Digital Research, Inc.
  48.  
  49.  INTEL is a registered trademark of Intel Corporation.
  50.  
  51.  
  52.  
  53.  Contents
  54.  
  55.  ───────────────────────────────────────────────────────────────────────────
  56.  
  57.  1    Introduction to the Microsoft Pascal Compiler
  58.  
  59.        1.1  How to Use This Guide
  60.        1.2  System Software
  61.        1.3  Learning More About Pascal
  62.  
  63.  
  64.  2    Getting Started
  65.  
  66.        2.1  Preliminary Procedures
  67.        2.2  Program Development
  68.        2.3  Vocabulary
  69.  
  70.  
  71.  3    A Sample Session
  72.  
  73.        3.1  Creating a Microsoft Pascal Source File
  74.        3.2  Compiling Your Microsoft Pascal Program
  75.        3.3  Linking Your Microsoft Pascal Program
  76.        3.4  Executing Your Microsoft Pascal Program
  77.  
  78.  
  79.  4    Options for Compiling and Linking
  80.  
  81.        4.1  MS-DOS 2.0 File System Library
  82.        4.2  Alternative Linkers
  83.        4.3  Precision of Basic Numeric Types
  84.        4.4  Floating-Point Options
  85.        4.5  Changing the Default Math Library
  86.        4.6  End Cases for Compilation and Execution
  87.  
  88.  
  89.  5    More About Compiling
  90.  
  91.        5.1  Files Written by the Compiler
  92.        5.2  Filename Conventions
  93.        5.3  Starting the Compiler
  94.        5.4  Pass One Compiler Switches
  95.  
  96.  
  97.  6    More About Linking
  98.  
  99.        6.1  Files Read by the Linker
  100.        6.2  Files Written by the Linker
  101.        6.3  The Overlay Linker
  102.        6.4  Linker Switches
  103.  
  104.  
  105.  7    Using a Batch Command File
  106.  
  107.  
  108.  8    Compiling and Linking Large Programs
  109.  
  110.        8.1  Avoiding Limits on Code Size
  111.        8.2  Avoiding Limits on Data Size
  112.        8.3  Working With Limits on Compile Time Memory
  113.        8.4  Working With Limits on Disk Memory
  114.        8.5  Minimizing Load Module Size
  115.  
  116.  
  117.  9    Using Assembly Language Routines
  118.  
  119.        9.1  Calling Conventions
  120.        9.2  Internal Representations of Data Types
  121.        9.3  Interfacing to Assembly Language Routines
  122.  
  123.  
  124.  10   Advanced Topics
  125.  
  126.        10.1  The Structure of the Compiler
  127.        10.2  An Overview of the File System
  128.        10.3  Runtime Architecture
  129.        10.4  Floating-Point Operations
  130.        10.5  MS-Dos 2.0 Issues
  131.  
  132.  
  133.  Appendices
  134.  
  135.  A    Differences From Earlier Versions of Microsoft Pascal
  136.  
  137.  B    Version Specifics
  138.  
  139.  C    Customizing i8087 Interrupts
  140.  
  141.  D    Exception Handling for 8087 Math
  142.  
  143.  F    Microsoft LINK Error Messages
  144.  
  145.  
  146.  Index
  147.  
  148.  
  149.  Figures
  150.  
  151.  Figure 2.1    Program Development
  152.  
  153.  Figure 9.1    Contents of the Frame
  154.  
  155.  Figure 9.2    Stack Before Transfer to ADD
  156.  
  157.  Figure 9.3    One-Byte Return Value
  158.  
  159.  Figure 9.4    Two-Byte Return Value
  160.  
  161.  Figure 9.5    Four-Byte Return Value
  162.  
  163.  Figure 10.1   The Structure of the Microsoft Pascal Compiler
  164.  
  165.  Figure 10.2   The Unit U Interface
  166.  
  167.  Figure 10.3   Memory Organization
  168.  
  169.  Figure 10.4   Microsoft Pascal Program Structure
  170.  
  171.  
  172.  Tables
  173.  
  174.  Table 2.1     A Suggested Disk Setup
  175.  
  176.  Table 3.1     Files Used by the Microsoft Pascal Compiler
  177.  
  178.  Table 5.1     Filenames Assigned by the Compiler
  179.  
  180.  Table 5.2     Pass One Compiler Switches
  181.  
  182.  Table 6.1     Linker Defaults
  183.  
  184.  Table 6.2     Microsoft LINK Switches
  185.  
  186.  Table 10.1    Unit Identifier Suffixes
  187.  
  188.  Table 10.2    Error Code Classification
  189.  
  190.  Table 10.3    Runtime Values in BRTEQQ
  191.  
  192.  Table A.1     Share and Access Values
  193.  
  194.  Table F.1     How Errors are Numbered
  195.  
  196.  
  197.  
  198.  About the Microsoft Pascal Compiler
  199.  
  200.  The Microsoft Pascal Compiler generates object files in native code that
  201.  execute much faster than those compiled to p-code. With the MS-Pascal
  202.  Compiler, you get the programming advantages of a high-level language,
  203.  without sacrificing execution speed, because the compiler generates many
  204.  low-level escapes to the machine level. Programs written in MS-Pascal are
  205.  often comparable in speed to programs written in assembly language.
  206.  
  207.  MS-Pascal Compiler also generates code for fast numeric processing in the
  208.  8087 processing environment and provides 8087 emulation in the system
  209.  software package.
  210.  
  211.  Microsoft(R) Pascal, also called MS(TM)-Pascal, is a highly extended,
  212.  portable version of the Pascal language. Compatible with the International
  213.  Standards Organization (ISO) proposed standard, its extensions facilitate
  214.  systems programming as well as applications programming.
  215.  
  216.  You can use Microsoft Pascal at the ISO standard level for transporting
  217.  programs to and from other machines. Or, to make full use of the
  218.  capabilities of a specific computer, you can make your programs more
  219.  efficient by using the language at its extend or system levels.
  220.  
  221.  
  222.  System Requirements
  223.  
  224.  The Microsoft(R) Pascal Compiler can be used with any computer that has one
  225.  disk drive and a minimum of 130K random access memory available after the
  226.  operating system is loaded. (The MS(TM)-Disk Operating System utility
  227.  CHKDSK will tell you how much RAM is available.)
  228.  
  229.  We recommend at least two drives, however, for easier operation. The
  230.  compiler can successfully take advantage of at least 196K RAM. Your machine
  231.  should run MS-DOS.
  232.  
  233.  This implementation of the Microsoft Pascal Compiler can take advantage
  234.  of, but does not require, an INTEL(R) 8087 numeric coprocessor.
  235.  
  236.  Two versions of Microsoft LINK are available for your use. They are
  237.  LINK.EXE (the default linker) and LINK.V2 (the optional MS-DOS 2.0 linker
  238.  which supports pathnames and overlays). You must use either one or the
  239.  other to link your program modules (see Chapter 4, "Options for
  240.  Compiling and Linking"). Microsoft LINK is the standard MS-DOS linking
  241.  utility.
  242.  
  243.  
  244.  How to Use These Manuals
  245.  
  246.  Documentation for the Microsoft Pascal Compiler is provided in two binders
  247.  containing the two manuals described below:
  248.  
  249.  Microsoft Pascal User's Guide
  250.  
  251.  This manual provides an introduction to compilation and linking, a sample
  252.  session, and a technical reference for the Microsoft Pascal Compiler.
  253.  
  254.  Microsoft Pascal Reference Manual
  255.  
  256.  This manual describes the syntax and use of the Microsoft Pascal language.
  257.  With the exceptions noted in Appendix B, "Version Specifics," of the User's
  258.  Guide and any recent changes described in the README.DOC file (if present),
  259.  this is the language supported by the Microsoft Pascal Compiler.
  260.  
  261.  The following descriptive devices are used throughout these manuals to
  262.  emphasize elements of the text. Descriptions of Microsoft Pascal syntax
  263.  requirements can be found in Chapter 2 of the Microsoft Pascal Reference
  264.  Manual.
  265.  
  266.       CAPS         Capitalized text indicates statements, files, or
  267.                    commands. The text is capitalized only to emphasize
  268.                    procedures, files, and compilands, or objects that
  269.                    the user may encounter. Microsoft Pascal is not case
  270.                    sensitive. Capital letters also indicate that you
  271.                    must press a key named by the text; for example,
  272.                    "press the RETURN key."
  273.  
  274.       Italics      Italics indicate user-supplied data, for example,
  275.                    filenames, variable names, and array names.
  276.  
  277.       [ ]          Square brackets indicate that the enclosed entry is
  278.                    optional.
  279.  
  280.       ...          Ellipses indicate that an entry may be repeated as many
  281.                    times as needed or desired.
  282.  
  283.  All other punctuation, such as commas, colon, slash marks, parentheses, and
  284.  equal signs, must be entered exactly as shown.
  285.  
  286.  
  287.  
  288.  Chapter 1  Introduction to the Microsoft Pascal Compiler
  289.  
  290.  ───────────────────────────────────────────────────────────────────────────
  291.  
  292.  1.1     How to Use This Guide
  293.  
  294.  1.2     System Software
  295.  
  296.  1.3     Learning More About Pascal
  297.  
  298.  
  299.  
  300.  The Microsoft Pascal Compiler, version 3.20, implemented for the Microsoft
  301.  Disk Operating System, MS-DOS, version 1.25, accepts programs written
  302.  according to the ISO standard (Level 0) and the ANSI-IEEE Standard. It
  303.  also accepts those written in the full Microsoft Pascal language as
  304.  described in the May 1983 release of the Microsoft Pascal Reference
  305.  Manual.
  306.  
  307.  If you compile your programs with the default compiler options and link
  308.  them with the standard libraries, PASCAL.LIB and MATH.LIB, they will run
  309.  under both MS-DOS version 1.0 and version 2.0. If you have an 8087
  310.  installed in your machine, your programs will use it to improve the speed
  311.  of real arithmetic. If you don't have an 8087 installed, your programs
  312.  will run perfectly well and give the same results.
  313.  
  314.  Additional benefits of the Microsoft Pascal Compiler are:
  315.  
  316.        A double precision option for real number calculations in IEEE
  317.        floating-point format.
  318.  
  319.        Support for linking of 8086 assembly language, Microsoft Pascal,
  320.        and Microsoft FORTRAN programs.
  321.  
  322.        Extensive program development through support of SUPERARRAYS, flow
  323.        control, separately compiled UNITS, variable length strings, the
  324.        address types, constants and functions of ARRAY and RECORD types, and
  325.        other development features.
  326.  
  327.  
  328.  1.1  How to Use This Guide
  329.  
  330.  The Microsoft Pascal Compiler User's Guide describes the operation of the
  331.  Microsoft Pascal Compiler, from the most rudimentary procedures to more
  332.  advanced topics that may be of interest only to experienced programmers.
  333.  This document assumes that you have a working knowledge of both the
  334.  Microsoft Pascal language and MS-DOS.
  335.  
  336.  The Microsoft Pascal Compiler User's Guide also describes the compiling and
  337.  linking options that give you the flexibility of customizing your own
  338.  programs according to your requirements for portability and performance.
  339.  See Chapter 4, "Options for Compiling and Linking," for a summary of these
  340.  options. The Microsoft Pascal Compiler offers a wealth of options for
  341.  developing your programs.
  342.  
  343.  For a list of the differences between Microsoft Pascal 3.20 and previous
  344.  versions since 3.0, see Appendix A, "Differences Between Versions 3.2
  345.  and 3.3."
  346.  
  347.  The initial chapters (Chapters 1 through 6) should be read in their
  348.  entirety by the first-time user of the Microsoft Pascal Compiler. Included
  349.  in this material are the procedures you should perform before compiling and
  350.  linking your first program, a description of the process of program
  351.  development, and a step-by-step walk-through of each of the procedures that
  352.  follow the writing of a program: compiling, linking, and running.
  353.  
  354.  The remaining chapters (Chapters 7 through 10) provide information about
  355.  using a batch command file, compiling and linking large programs, and using
  356.  assembly language routines. They also provide additional technical
  357.  information on compiler structure, the Microsoft Pascal file system,
  358.  floating-point issues, and runtime architecture.
  359.  
  360.  Included in the appendix material are the version specifics of the
  361.  Microsoft Pascal Compiler for MS-DOS, some of the attributes of the 8087
  362.  numeric coprocessor, and the list of Microsoft LINK error messages.
  363.  
  364.  
  365.  1.2  System Software
  366.  
  367.  The Microsoft-Pascal Compiler software package includes two or more disks
  368.  which contain the following files:
  369.  
  370. ╓┌───────────────┌───────────────────────────────────────────────────────────╖
  371.  File            Contents
  372.  ───────────────────────────────────────────────────────────────────────────
  373.  PAS1.EXE        Pass one of the Microsoft Pascal Compiler
  374.  
  375.  PAS2.EXE        Pass two of the Microsoft Pascal Compiler
  376.  
  377.  PAS3.EXE        Pass three of the Microsoft Pascal Compiler
  378.  
  379.  PASCAL.LIB      The runtime library
  380.  File            Contents
  381. PASCAL.LIB      The runtime library
  382.  
  383.  PASCAL.MAP      Map of the runtime library
  384.  
  385.  MATH.LIB        The default floating-point package library contained in
  386.                  PASCAL.LIB
  387.  
  388.  MATH.MAP        The link map of MATH.LIB
  389.  
  390.  8087.LIB        An auxiliary library for use with programs that are to run
  391.                  only on machines with the 8087 coprocessor installed and
  392.                  whose size you wish to reduce
  393.  
  394.  8087.MAP        The link map of 8087.LIB
  395.  
  396.  DECMATH.LIB     An auxiliary library containing decimal floating-point
  397.                  support routines
  398.  
  399.  DECMATH.MAP     The map of DECMATH.LIB
  400.  
  401.  File            Contents
  402. 
  403.  DOS2PAS.LIB     An auxiliary library containing an MS-DOS version 2.0 file
  404.                  system interface
  405.  
  406.  DOS2PAS.MAP     A map of DOS2PAS.LIB
  407.  
  408.  ALTMATH.LIB     An auxiliary library containing high-speed floating-point
  409.                  support routines
  410.  
  411.  ALTMATH.MAP     A map of ALTMATH.LIB
  412.  
  413.  LINK.EXE        Default version of Microsoft LINK
  414.  
  415.  LINK.V2         Optional version of Microsoft LINK (MS-DOS 2.0)
  416.  
  417.  NULF.OBJ        The dummy file system
  418.  
  419.  NULE6.OBJ       The dummy error system
  420.  
  421.  FINU            Declarations of low-level file system routines (the Unit U
  422.  File            Contents
  423. FINU            Declarations of low-level file system routines (the Unit U
  424.                  interface)
  425.  
  426.  FINK            Declaration of the generic file control block type, FCBFQQ
  427.  
  428.  FINKXM          Declaration of the MS-DOS file control block
  429.  
  430.  ENTX6L.ASM      The assembler source of the execution control module that
  431.                  initializes and terminates every program
  432.  
  433.  SORT.PAS        Bubble sort demonstration program
  434.  
  435.  PRIMES.PAS      Prime number generator program
  436.  
  437.  README.DOC      If present, contains information that is more up to date
  438.                  than the documentation contained in these manuals
  439.  
  440.  
  441.  1.3  Learning More About Pascal
  442.  
  443.  The manuals in this package provide complete reference information for your
  444.  implementation of the Microsoft Pascal Compiler. They do not, however,
  445.  teach you how to write programs in Pascal. If you are new to Pascal or need
  446.  help in learning to program, we suggest you read any of the following
  447.  books:
  448.  
  449.  Findlay, W., and D. F. Watt. Pascal: An Introduction to Methodical
  450.  Programming. London: Pittman, 1978.
  451.  
  452.  Holt, Richard C., and J. N. P. Hume. Programming Standard Pascal. Reston,
  453.  Va.: Reston Publishing Company, 1980.
  454.  
  455.  Jensen, Kathleen, and Niklaus Wirth. Pascal User Manual and Report.
  456.  New York: Springer-Verlag, 1974, 1978.
  457.  
  458.  Koffman, E. B. Problem Solving and Structured Programming in Pascal.
  459.  Reading, Mass.: Addison-Wesley Publishing Company, 1981.
  460.  
  461.  Schneider, G. M., S. W. Weinhart, and D. M. Perlman. An Introduction to
  462.  Programming and Problem Solving With Pascal. New York: John Wiley & Sons,
  463.  second edition, 1982.
  464.  
  465.  
  466.  
  467.  Chapter 2  Getting Started
  468.  
  469.  ───────────────────────────────────────────────────────────────────────────
  470.  
  471.  2.1  Preliminary Procedures
  472.  
  473.        2.1.1  Backing Up Your System Files
  474.  
  475.        2.1.2  Setting Up Your System Disks
  476.  
  477.        2.1.3  If You Have an 8087 Coprocessor
  478.  
  479.  2.2  Program Development
  480.  
  481.  2.3  Vocabulary
  482.  
  483.  
  484.  
  485.  This chapter provides a brief review of the procedures, terms, and concepts
  486.  involved in developing Microsoft Pascal programs on your microcomputer.
  487.  
  488.  
  489.  2.1  Preliminary Procedures
  490.  
  491.  This section describes several preliminary procedures, some of which are
  492.  required and some of which are highly recommended before you begin the
  493.  sample session or compile any programs of your own. If you are unfamiliar
  494.  with any of the MS-DOS procedures mentioned, consult your MS-DOS User's
  495.  Guide for instructions.
  496.  
  497.  
  498.  2.1.1  Backing Up Your System Files
  499.  
  500.  This step is optional but highly recommended.
  501.  
  502.  The first thing you should do when you have unwrapped your system disks is
  503.  to make copies to work with, saving the original disks for future backup.
  504.  Make the copies using the COPY or DISKCOPY utilities supplied with MS-DOS.
  505.  
  506.  
  507.  2.1.2  Setting Up Your System Disks
  508.  
  509.  This step is recommended.
  510.  
  511.  Before you begin compiling and linking a program, we recommend that you
  512.  check the contents of each disk. You may wish to copy some files from one
  513.  system disk to another to set up a working arrangement that is convenient
  514.  for you.
  515.  
  516.  And, in order to avoid continual reprompting from the system to reload
  517.  certain MS-DOS files, you may also wish to set up your system disks as
  518.  shown in Table 2.1. This setup assumes you have two 160K disk drives
  519.  available.
  520.  
  521.  
  522.           Table 2.1
  523.           A Suggested Disk Setup
  524.  
  525.           Disk     Contents
  526.           ─────────────────────────────────────
  527.           1        COMMAND.COM
  528.                    text editor1
  529.                    miscellaneous utilities2
  530.                    PAS1.EXE
  531.  
  532.           2        COMMAND.COM
  533.                    PAS2.EXE
  534.                    PAS3.EXE
  535.  
  536.           3        COMMAND.COM
  537.                    PASCAL.LIB
  538.                    LINK.EXE
  539.  
  540.  
  541.  For most implementations, you can copy the necessary MS-DOS files by
  542.  formatting the blank disks with the /S switch and then copying the
  543.  appropriate files to each disk. If you do not format disks with the /S
  544.  switch, the compiler may prompt you to reinsert your MS-DOS disk after each
  545.  step.
  546.  
  547.  
  548.  2.1.3  If You Have an 8087 Coprocessor
  549.  
  550.  This step may be required if you have an 8087 coprocessor. The auxiliary
  551.  library, 8087.LIB, supports a particular arrangement of 8086/8087/8088
  552.  hardware. Specifically, it expects that i8087 interrupts will be directed
  553.  through to the 8086/8088 via the 8086/8088 interrupt vector 2 (NMI),
  554.  without the intervention of an 8259 interrupt controller or its
  555.  equivalent.
  556.  
  557.  Check to see if your hardware configuration meets any of the following
  558.  criteria:
  559.  
  560.     1.  It uses an 8087 interrupt vector number other than 2.
  561.  
  562.     2.  It uses an 8259 interrupt controller.
  563.  
  564.     3.  The 8087 shares interrupts with another device on the same vector.
  565.  
  566.  If any of these criteria is true for your computer system, you must read
  567.  Appendix C, "Customizing i8087 Interrupts," and customize the runtime
  568.  library as described there.
  569.  
  570.  
  571.  2.2  Program Development
  572.  
  573.  This section provides a short introduction to program development, a
  574.  multistep process which includes first writing the program, and then
  575.  compiling, linking, and executing it. For a brief explanation of terms that
  576.  may be unfamiliar, see Section 2.3, "Vocabulary."
  577.  
  578.  A microprocessor can execute only its own machine instructions; it cannot
  579.  execute source program statements directly. Therefore, before you run a
  580.  program, some type of translation of the statements in your program to the
  581.  machine language of your microprocessor must occur.
  582.  
  583.  Compilers and interpreters are two types of programs that perform this
  584.  translation. Depending on the language you are using, either or both types
  585.  of translation may be available to you. MS-Pascal is a compiled language.
  586.  
  587.  A compiler translates a source program and creates a new file called an
  588.  object file. The object file contains relocatable machine code that can be
  589.  placed and run at different absolute locations in memory.
  590.  
  591.  Compilation also associates memory addresses with variables and with the
  592.  targets of GOTO statements, so that lists of variables or of labels do not
  593.  have to be searched during execution of your program.
  594.  
  595.  Many compilers, including the MS-Pascal Compiler, are what are called
  596.  "optimizing" compilers. During optimization, the compiler reorders
  597.  expressions and eliminates common subexpressions, either to increase speed
  598.  of execution or to decrease program size. These factors combine to
  599.  measurably increase the execution speed of your program.
  600.  
  601.  The MS-Pascal Compiler has a three-part structure. The first two parts,
  602.  pass one and pass two, together carry out the optimization and create the
  603.  object code. Pass three is an optional step that creates an object code
  604.  listing. Compiling is described in greater detail in Section 3.2,
  605.  "Compiling Your Microsoft Pascal Program," and in Chapter 5, "More About
  606.  Compiling."
  607.  
  608.  Before a successfully compiled program can be executed, it must be linked.
  609.  Linking is the process in which MS-LINK computes absolute offset addresses
  610.  for routines and variables in relocatable object modules and then resolves
  611.  all external references by searching the runtime libraries. The linker
  612.  saves your program on disk as an executable file, ready to run.
  613.  
  614.  You may, at link time, link more than one object module, as well as
  615.  routines written in assembly language or other high-level languages and
  616.  routines in other libraries. Linking is described in greater detail in
  617.  Section 3.3, "Linking Your Microsoft Pascal Program," and in Chapter 6,
  618.  "More About Linking."
  619.  
  620.  Figure 2.1 illustrates the entire program development process. The
  621.  paragraphs following the figure describe the process in more detail.
  622.  
  623.  
  624.                    ┌────────────┐
  625.      ┌────────────│Text editor │────────────┐    1.
  626.      │             └─────┬──────┘             │
  627.      │        ┌──────────┴───────────┐        │
  628.      │                                      │
  629.      │ MS-Pascal Source       MS-Macro Source │
  630.      │        │                      │        │
  631.      │                                      │
  632.      │  ┌──────────┐            ┌──────────┐  │
  633.      │  │MS- Pascal│            │MS-Macro  │  │    2.
  634.      │  │Compiler  │            │Assembler │  │
  635.      │  └─────┬────┘            └────┬─────┘  │
  636.      │                                      │
  637.      ├──yes──errors?          errors?──yes──┘
  638.      │        │no                  no│
  639.      │                              
  640.      │     pas.OBJ    Runtime     asm.OBJ
  641.      │     file(s)    library      file(s)
  642.      │        │          │           │
  643.      │        └──────────┼───────────┘
  644.      │                   
  645.      │              ┌────────┐
  646.      │              │MS-LINK │                     3.
  647.      │              │Linker  │
  648.      │              └────┬───┘
  649.      │                   
  650.      │              pas.EXE file
  651.      │                   │
  652.      │                   
  653.      │            ┌─────────────┐
  654.      │            │ Run pas.EXE │                  4.
  655.      │            └──────┬──────┘
  656.      │                   
  657.      └──────yes───── errors? ───no───────────── 5.
  658.  
  659.               Figure 2.1.  Program Development
  660.  
  661.  
  662.     1.  Create and edit the MS-Pascal (and MS-Macro) source file.
  663.  
  664.         Program development begins when you write an MS-Pascal program; any
  665.         general purpose text editor will serve. Use a text editor also to
  666.         write any assembly language routines you may plan to include.
  667.  
  668.     2.  Compile the program with $debug+. Assemble the assembler source, if
  669.         any.
  670.  
  671.        ─────────────────────────────────────────────────────────────────────
  672.        Note
  673.            When your program has successfully compiled, remove the $debug+
  674.            metacommand and recompile to enhance your program's execution
  675.            time.
  676.        ─────────────────────────────────────────────────────────────────────
  677.  
  678.         Once you have written a program, compile it with the MS-Pascal
  679.         Compiler. The compiler flags all syntax and logic errors as it reads
  680.         your source file. Use the error-checking switches or their
  681.         corresponding metacommands (described in Section 5.4, "Pass One
  682.         Compiler Switches") to generate diagnostic calls for all runtime
  683.         errors. If compilation is successful, the compiler creates a
  684.         relocatable object file.
  685.  
  686.         If you have written your own assembly language routines (for
  687.         example, to increase the speed of execution of a particular
  688.         algorithm), assemble those routines with the Microsoft Macro
  689.         Assembler, MS-Macro. (You may have received MS-Macro as part of the
  690.         utility package that came with your computer system. If not, it is
  691.         available separately from your software dealer.)
  692.  
  693.     3.  Link compiled (and assembled) OBJ files with the runtime
  694.         libraries.
  695.  
  696.         A compiled (or assembled) object file is not executable and must be
  697.         linked with the runtime library, PASCAL.LIB, using either LINK.EXE
  698.         or LINK.V2. Separately compiled Microsoft FORTRAN subroutines can
  699.         also be linked to your program at this time.
  700.  
  701.        ─────────────────────────────────────────────────────────────────────
  702.        Note
  703.           Auxiliary math runtime libraries and the MS-DOS file system
  704.           library, DOS2PAS.LIB, may also be linked. For more details, see
  705.           Section 6.1.1.2, "Auxiliary Libraries."
  706.        ─────────────────────────────────────────────────────────────────────
  707.  
  708.     4.  Run EXE file.
  709.  
  710.         The linker links all modules needed by your program and produces as
  711.         output an executable object file with .EXE as the extension. This
  712.         file can be executed by simply typing its filename.
  713.  
  714.     5.  Recompile, relink, and rerun with $debug-.
  715.  
  716.         Repeat this process until your program has been successfully
  717.         compiled, linked, and run without errors. Then recompile, relink,
  718.         and rerun it without the runtime error-checking switches, to reduce
  719.         the amount of time and space required. Chapter 8, "Compiling and
  720.         Linking Large Programs," discusses how to work within various
  721.         physical limits you may encounter in compiling, linking, and
  722.         executing a program.
  723.  
  724.  
  725.  2.3  Vocabulary
  726.  
  727.  This section reviews some of the vocabulary that is commonly used in
  728.  discussing the steps in program development. The definitions given are
  729.  intended primarily for use with this manual. Thus, neither the individual
  730.  definition nor the list of terms is comprehensive.
  731.  
  732.  An MS-Pascal program is more commonly called a "source program" or "source
  733.  file." The source file is the input file to the compiler and must be in
  734.  ASCII format. The compiler translates this source and creates, as output, a
  735.  new file called a "relocatable object file." The source and object files
  736.  generally have the default extensions .PAS and .OBJ, respectively. After
  737.  the source code has been compiled, the object file(s) must be linked with
  738.  the runtime libraries to produce an executable program or run file. The run
  739.  file has the extension .EXE.
  740.  
  741.  Some other terms you should know are related to stages in the development
  742.  and execution of a compiled program. These stages are:
  743.  
  744.     1.  Compile time
  745.  
  746.         The time during which the compiler is executing and during which it
  747.         compiles an MS-Pascal source file and creates a relocatable object
  748.         file.
  749.  
  750.     2.  Linktime
  751.  
  752.         The time during which the linker is executing and during which it
  753.         links together relocatable object files and library files.
  754.  
  755.     3.  Runtime
  756.  
  757.         The time during which a compiled and linked program is executing. By
  758.         convention, runtime refers to the execution time of your program and
  759.         not to the execution time of the compiler or the linker.
  760.  
  761.  The following terms pertain to the linking process and the runtime
  762.  libraries:
  763.  
  764.     1.  Module
  765.  
  766.         A general term for a discrete unit of code. There are several types
  767.         of modules, including relocatable and executable modules.
  768.         (Furthermore, in the MS-Pascal language, "module" has a specific
  769.         meaning as one type of MS-Pascal compiland. See the Microsoft Pascal
  770.         Reference Manual for details. In this User's Guide, we use the term
  771.         "module" in its general sense, unless otherwise specified.)
  772.  
  773.         The object files created by the compiler are said to be
  774.         "relocatable," that is, they do not contain absolute addresses.
  775.         Linking produces an "executable" module, that is, one that contains
  776.         the necessary addresses to proceed with loading and running the
  777.         program.
  778.  
  779.     2.  Routine
  780.  
  781.         Code, residing in a module, that represents a particular procedure
  782.         or function. More than one routine may reside in a module.
  783.  
  784.     3.  External reference
  785.  
  786.         A variable or routine in one module that is referred to by a routine
  787.         in another module.
  788.  
  789.         The variable or routine is often said to be "defined" or "public" in
  790.         the module in which it resides.
  791.  
  792.         The linker tries to resolve external references by searching for the
  793.         declaration of each such reference in other modules. If such a
  794.         declaration is found, the module in which it resides is selected to
  795.         be part of the executable module (if it is not already selected) and
  796.         becomes part of your executable file. These other modules are
  797.         usually library modules in the runtime library.
  798.  
  799.         If the variable or routine is found, the address associated with it
  800.         is substituted for the reference in the first module, which is then
  801.         said to be "bound." When a variable is not found, it is said to be
  802.         "undefined" or "unresolved."
  803.  
  804.     4.  Relocatable module
  805.  
  806.         The module's code can be loaded and run at different locations in
  807.         memory. Relocatable modules contain routines and variables
  808.         represented as offsets relative to the start of the module. These
  809.         routines and variables are said to be at "relative" offset
  810.         addresses. When the module is processed by the linker, an address is
  811.         associated with the start of the module.
  812.  
  813.         The linker then computes an absolute offset address that is equal to
  814.         the associated address plus the relative offset for each routine or
  815.         variable. These new computed values become the absolute offset
  816.         addresses that are used in the executable file.
  817.  
  818.         These offset addresses are still relative to a "segment," which
  819.         corresponds to an 8086 segment register. Segment addresses are not
  820.         defined by the linker; rather, they are computed when your program
  821.         is actually loaded prior to execution.
  822.  
  823.     5.  Runtime libraries
  824.  
  825.         Contain the runtime routines needed to implement the Microsoft
  826.         Pascal language. A library module usually corresponds to a feature
  827.         or subfeature of the MS-Pascal language.
  828.  
  829.  
  830.  
  831.  Chapter 3  A Sample Session
  832.  
  833.  ───────────────────────────────────────────────────────────────────────────
  834.  
  835.  3.1  Creating a Microsoft Pascal Source File
  836.  
  837.  3.2  Compiling Your Microsoft Pascal Program
  838.  
  839.        3.2.1  Pass One
  840.  
  841.        3.2.2  Pass Two
  842.  
  843.        3.2.3  Pass Three
  844.  
  845.  3.3  Linking Your Microsoft Pascal Program
  846.  
  847.  3.4  Executing Your Microsoft Pascal Program
  848.  
  849.  
  850.  
  851.  This chapter provides step-by-step instructions for compiling and linking
  852.  an MS-Pascal program. We strongly recommend that you compile the sample
  853.  program before compiling any of your own MS-Pascal programs.
  854.  
  855.  If you enter commands exactly as described, you should have a successful
  856.  session. If a problem does arise, check to see that you have correctly
  857.  carried out all of the required procedures described in Section 2.1,
  858.  "Preliminary Procedures," and carefully redo each step in the sample
  859.  session up to the point where you had trouble.
  860.  
  861.  Creating an executable MS-Pascal program involves the following steps:
  862.  
  863.     1.  Write and save an MS-Pascal source file.
  864.  
  865.     2.  Compile your program with the MS-Pascal Compiler.
  866.  
  867.         a. Start pass one and enter your filenames in response to the
  868.            prompts.
  869.  
  870.         b. Run pass two of the compiler.
  871.  
  872.         c. Run pass three of the compiler. (This step is optional.)
  873.  
  874.     3.  Link your object file to the MS-Pascal runtime libraries.
  875.  
  876.     4.  Execute (i.e., run) your program.
  877.  
  878.  Compiler passes one and two are required. You need to run pass three only
  879.  if you need or want an object listing (as in this sample session).
  880.  
  881.  The sample session makes the following assumptions:
  882.  
  883.     1.  You have completed the necessary preliminary procedures.
  884.  
  885.     2.  You have two disk drives (A: and B:).
  886.  
  887.     3.  The sample program is already debugged, so that it will compile,
  888.         link, and execute successfully.
  889.  
  890.     4.  An object listing is required, therefore all three passes of the
  891.         compiler will be run.
  892.  
  893.     5.  No compiler or linker switches will be used.
  894.  
  895.     6.  There are no problems with data, code, or memory limits.
  896.  
  897.  These complexities are discussed in Chapter 5, "More About Compiling,"
  898.  Chapter 6, "More About Linking," and Chapter 8, "Compiling and Linking
  899.  Large Programs," and are referred to as appropriate in the following sample
  900.  session.
  901.  
  902.  If the files required for successive steps in the process are not on the
  903.  same disk as one another, you will have to exchange disks between steps.
  904.  For example, if PAS1.EXE and PAS2.EXE are not on the same disk, you will
  905.  have to remove the first disk after completing pass one and replace it with
  906.  the disk containing PAS2.EXE. Similarly, if the linker or the library file
  907.  is on a different disk than pass three, you will have to insert the proper
  908.  system disk before running MS-LINK.
  909.  
  910.  
  911.  3.1  Creating a Microsoft Pascal Source File
  912.  
  913.  Turn on your computer and load MS-DOS. Insert an empty work disk in drive
  914.  B:. Log onto drive B:; this makes B: the default drive.
  915.  
  916.  You can create MS-Pascal programs with any available text editor. The
  917.  source file should, in most cases, have the .PAS extension. For this sample
  918.  session, we will use the program named SORT.PAS, which came with the system
  919.  software.
  920.  
  921.  Copy SORT.PAS to drive B:, which is where it would be if it were your own
  922.  program.
  923.  
  924.  
  925.  3.2  Compiling Your Microsoft Pascal Program
  926.  
  927.  As mentioned previously, compiling a program is either a two or a three-
  928.  step process, depending on whether or not you choose to produce an object
  929.  code listing. For the sample session, we will run all three passes.
  930.  
  931.  
  932.  3.2.1  Pass One
  933.  
  934.  Insert the disk containing PAS1.EXE in drive A:. In response to the
  935.  operating system prompt, type:
  936.  
  937.       A:PAS1
  938.  
  939.  This command starts pass one of the MS-Pascal Compiler.
  940.  
  941.  The compiler prints a header that includes the date and version number,
  942.  then prompts you for four filenames:
  943.  
  944.     1.  your source filename
  945.  
  946.     2.  an object filename
  947.  
  948.     3.  a source listing filename
  949.  
  950.     4.  an object listing filename
  951.  
  952.  Respond to the prompts as described in the following paragraphs. For
  953.  additional information about the files themselves, see Chapter 5, "More
  954.  about Compiling."
  955.  
  956.  Pressing the RETURN (or ENTER) key is assumed at the end of every line you
  957.  enter in response to a prompt. Only if this is the only response required
  958.  is RETURN shown.
  959.  
  960.     1.  Source file
  961.  
  962.         The first prompt is for the name of the file that contains your
  963.         MS-Pascal source program:
  964.  
  965.             Source filename [.PAS]:
  966.  
  967.         The prompt reminds you that .PAS is the default extension for the
  968.         source filename. Unless the extension is something other than .PAS,
  969.         you may omit it when you type in the filename.
  970.  
  971.         For now, type SORT (to indicate that the source file is B:SORT.PAS).
  972.  
  973.     2.  Object file
  974.  
  975.         The second prompt is for the name of the relocatable object file,
  976.         which will be created during pass two:
  977.  
  978.             Object filename [SORT.OBJ]:
  979.  
  980.         The name in brackets is the name the compiler will give to the
  981.         object file if you simply press the RETURN key at this point. The
  982.         filename is taken from the source filename you gave in response to
  983.         the first prompt; the .OBJ extension is the standard extension for
  984.         object files.
  985.  
  986.         For now, either type SORT or press the RETURN key.
  987.  
  988.     3.  Source listing file
  989.  
  990.         The third prompt is for the name of the source listing file, created
  991.         during pass one:
  992.  
  993.             Source listing [NUL.LST]:
  994.  
  995.         As before, the prompt shows the default. Because the source listing
  996.         is not required for linking and executing a program, it defaults to
  997.         the null file; that is, if you press the RETURN key, the source
  998.         listing will be sent to the null file, NUL.
  999.  
  1000.         However, if you enter any part of a file specification, the default
  1001.         extension is .LST, the default device is the currently logged drive,
  1002.         and the filename defaults to the name given for the source file.
  1003.  
  1004.         For this session, assume that you want to send the source listing
  1005.         file to the terminal screen. Therefore, type USER in response to the
  1006.         source listing prompt. (Typing CON has essentially the same effect;
  1007.         see Section 5.2, "Filename Conventions," for further information.)
  1008.  
  1009.     4.  Object listing file
  1010.  
  1011.         The final prompt is for the object listing file, to be created
  1012.         during pass three:
  1013.  
  1014.             Object listing [NUL.COD]:
  1015.  
  1016.         The null file is the default for the object listing, as it is for
  1017.         the source listing. If you press the RETURN key, no intermediate
  1018.         files will be saved and you won't be able to run pass three.
  1019.         However, the same default naming rules apply here as elsewhere; if
  1020.         you enter any part of a file specification, the default extension is
  1021.         .COD, the default device is the currently logged drive, and the
  1022.         filename is the source filename.
  1023.  
  1024.         For now, type USER (or CON) to request that the object listing be
  1025.         displayed on your terminal screen when you run pass three.
  1026.  
  1027.  Compilation begins as soon as you have responded to all four prompts. The
  1028.  source listing is displayed on your screen, as requested. When pass one is
  1029.  complete, you should see the following message on your terminal screen:
  1030.  
  1031.       Pass One     No Errors Detected.
  1032.  
  1033.  If the compiler had detected errors during compilation, messages like the
  1034.  following would appear instead:
  1035.  
  1036.       Pass One     2 Warnings Detected.
  1037.       Pass One     3 Errors Detected.
  1038.  
  1039.  The error and warning messages would appear in the source listing as it
  1040.  comes on your screen.
  1041.  
  1042.     1.  Errors are mistakes that prevent a program from running correctly.
  1043.  
  1044.     2.  Warnings indicate a variety of conditions, none of which will
  1045.         prevent the program from running, but which may reflect poor
  1046.         programming practice or produce invalid results.
  1047.  
  1048.  See Appendix H, "Messages," in the Microsoft Pascal Reference Manual for a
  1049.  complete listing of messages and information about how to correct the
  1050.  errors in your program.
  1051.  
  1052.  Pass one creates two intermediate files, PASIBF.SYM and PASIBF.BIN. The
  1053.  compiler saves these two files on the default drive for use during pass
  1054.  two.
  1055.  
  1056.  If there are errors, the two intermediate files are deleted and the
  1057.  remaining passes cannot be run. If pass one generates only warning
  1058.  messages, you can still run passes two and three, but you should go back
  1059.  and correct the source file at some point.
  1060.  
  1061.  
  1062.  3.2.2  Pass Two
  1063.  
  1064.  Remove the disk containing PAS1.EXE from drive A: and insert the disk
  1065.  containing PAS2.EXE. You won't need to do this if PAS2.EXE is on the same
  1066.  disk as PAS1.EXE.
  1067.  
  1068.  Start pass two by typing:
  1069.  
  1070.      A:PAS2
  1071.  
  1072.  Pass two does not ordinarily prompt you for any input. However, it does
  1073.  perform the following actions:
  1074.  
  1075.     1.  It reads the intermediate files PASIBF.SYM and PASIBF.BIN created in
  1076.         pass one.
  1077.  
  1078.     2.  It writes the object file.
  1079.  
  1080.     3.  It deletes the intermediate files created in pass one.
  1081.  
  1082.     4.  It writes two new intermediate files, PASIBF.TMP and PASIBF.OID, for
  1083.         use in pass three. These files are written to the currently logged
  1084.         drive.
  1085.  
  1086.  When you are compiling your own programs, the last step described varies,
  1087.  depending on your response to the object listing prompt. If, as for this
  1088.  sample session, you plan to run pass three, pass two writes the two
  1089.  intermediate files. If in pass one you do not request an object listing,
  1090.  pass two writes and later deletes just one new intermediate file,
  1091.  PASIBF.TMP.
  1092.  
  1093.  When pass two is complete, a message like the following prints on your
  1094.  screen:
  1095.  
  1096.       Code Area Size = #05EC  (1516)
  1097.       Cons Area Size = #00E6   (230)
  1098.       Data Area Size = #0264   (612)
  1099.  
  1100.       Pass Two    No Errors Detected.
  1101.  
  1102.  The first three lines indicate, first in hexadecimal and then in decimal
  1103.  notation, the amount of space taken up by executable code (Code), constants
  1104.  (Cons), and variables (Data). The message concerning the number of errors
  1105.  refers to pass two only, not to the entire compilation.
  1106.  
  1107.  
  1108.  3.2.3  Pass Three
  1109.  
  1110.  Remove the disk containing PAS2.EXE from drive A: and insert the disk
  1111.  containing PAS3.EXE. You won't need to do this if PAS3.EXE is on the same
  1112.  disk as PAS2.EXE.
  1113.  
  1114.  Start pass three by typing:
  1115.  
  1116.       A:PAS3
  1117.  
  1118.  PAS3.EXE does not prompt you for any input. It reads PASIBF.TMP and
  1119.  PASIBF.OID, the intermediate files created during pass two, and, because of
  1120.  your earlier response to the object listing prompt, writes the object code
  1121.  listing to your screen.
  1122.  
  1123.  When pass three is complete, the two intermediate files are deleted. If,
  1124.  after requesting an object listing, you choose not to run pass three, you
  1125.  should delete these files yourself (to save space). Table 3.1 is a summary
  1126.  of the files read and written by each of the three passes of the compiler
  1127.  during this sample session.
  1128.  
  1129.  
  1130.  Table 3.1
  1131.  Files Used by the Microsoft Pascal Compiler
  1132.  
  1133.  Pass      Reads           Writes          Deletes
  1134.  ───────────────────────────────────────────────────────
  1135.  1         SORT.PAS        USER.LST
  1136.                            PASIBF.SYM
  1137.                            PASIBF.BIN
  1138.  
  1139.  2         PASIBF.SYM      SORT.OBJ        PASIBF.SYM
  1140.            PASIBF.BIN      PASIBF.OID      PASIBF.BIN
  1141.                            PASIBF.TMP
  1142.  
  1143.  3         PASIBF.OID      USER.COD        PASIBF.OID
  1144.            PASIBF.TMP                      PASIBF.TMP
  1145.  
  1146.  
  1147.  See Chapter 5, "More About Compiling," for details about compiler switches
  1148.  and other ways of responding to the compiler prompts.
  1149.  
  1150.  
  1151.  3.3  Linking Your Microsoft Pascal Program
  1152.  
  1153.  Now you are ready to link your program with one of the two versions of
  1154.  MS-LINK provided with the Microsoft Pascal Compiler version 3.20. Linking
  1155.  converts the relocatable object file into an executable program by
  1156.  assigning absolute addresses and setting up calls to the runtime libraries.
  1157.  
  1158.  Remove the disk containing PAS3.EXE from drive A: and insert the disk
  1159.  containing LINK.EXE. You won't need to do this if the linker is on the same
  1160.  disk as PAS3.EXE.
  1161.  
  1162.  Start the linker by typing:
  1163.  
  1164.       A:LINK
  1165.  
  1166.  The linker displays a header and then, like the front end of the compiler,
  1167.  gives a series of four prompts to which you must respond before linking
  1168.  begins. The linker prompts for the following information:
  1169.  
  1170.     1.  the name of your relocatable object file(s)
  1171.  
  1172.     2.  the name you wish to give to the executable program
  1173.  
  1174.     3.  the name you wish to give to the linker listing
  1175.  
  1176.     4.  the location of the runtime library
  1177.  
  1178.  Each of these prompts is discussed briefly in the following paragraphs and
  1179.  in somewhat more detail in Chapter 6, "More About Linking." For complete
  1180.  information on MS-LINK, see your MS-DOS manual.
  1181.  
  1182.  After the first of the four linker prompts appears on the screen, remove
  1183.  the disk containing LINK.EXE and insert the disk containing PASCAL.LIB.
  1184.  You won't need to do this if the linker and the runtime library are on the
  1185.  same disk.
  1186.  
  1187.  ───────────────────────────────────────────────────────────────────────────
  1188.  Note
  1189.     Prompting specific to LINK.V2, the optional linker, is discussed in
  1190.     detail in Section 6.1.2, "Linking Libraries." Included in that
  1191.     discussion are details concerning the overlay manager of the optional
  1192.     linker.
  1193.  ───────────────────────────────────────────────────────────────────────────
  1194.  
  1195.     1.  Object modules prompt
  1196.  
  1197.         The first prompt is for the name of your relocatable object file (or
  1198.         files):
  1199.  
  1200.             Object Modules [.OBJ]:
  1201.  
  1202.         Like the compiler prompts, the linker prompts always give certain
  1203.         defaults. Here, the prompt indicates that .OBJ is the default
  1204.         extension for any file(s) you name. Type SORT, and the file
  1205.         SORT.OBJ, created during compilation, will be linked with PASCAL.LIB
  1206.         during the linking process. If, for any reason, the object file does
  1207.         not have the extension .OBJ, you must give the file specification in
  1208.         full.
  1209.  
  1210.     2.  Run file prompt
  1211.  
  1212.         The second prompt is for the the name of the run file, the file
  1213.         created by the linker that will contain your executable program:
  1214.  
  1215.             Run File [SORT.EXE]:
  1216.  
  1217.         The default filename is taken from your response to the first linker
  1218.         prompt; the .EXE extension identifies an executable file. To accept
  1219.         the default filename, simply press the RETURN key.
  1220.  
  1221.     3.  Linker listing file prompt
  1222.  
  1223.         The third prompt is for the linker listing file, sometimes called
  1224.         the linker map:
  1225.  
  1226.             List File [NUL.MAP]:
  1227.  
  1228.         As the prompt indicates, the default for the list file is the NUL
  1229.         file, that is, no file at all. For now, simply press the RETURN key
  1230.         to accept this default.
  1231.  
  1232.         If, when linking your own programs, you wish to see the list file
  1233.         at your screen (console), without having it written to a disk file,
  1234.         type CON in response to the list file prompt. (The linker does
  1235.         not recognize USER as a name for your screen.)
  1236.  
  1237.         If you want the linker map written to a disk file, respond to this
  1238.         prompt with a name for the file.
  1239.  
  1240.     4.  Runtime libraries prompt
  1241.  
  1242.         The last linker prompt is for the location of the runtime libraries:
  1243.  
  1244.             Libraries [.LIB]:
  1245.  
  1246.         Here, to indicate that PASCAL.LIB is found on drive A:, you should
  1247.         simply type:
  1248.  
  1249.             A:
  1250.  
  1251.         If PASCAL.LIB is not already on the disk in drive A:, you will have
  1252.         to exchange disks before linking can proceed.
  1253.  
  1254.  After you have responded to the last of the four prompts, MS-LINK links
  1255.  your program, SORT.OBJ, with the necessary modules in the MS-Pascal runtime
  1256.  library, A:PASCAL.LIB. This linking process creates an executable file,
  1257.  named SORT.EXE, on the default drive.
  1258.  
  1259.  
  1260.  3.4  Executing Your Microsoft Pascal Program
  1261.  
  1262.  When linking is complete, the operating system prompt returns. To run the
  1263.  sample program, just type:
  1264.  
  1265.       SORT
  1266.  
  1267.  This command directs MS-DOS to load the executable file SORT.EXE, fix
  1268.  segment addresses to their absolute value (based on the address at which
  1269.  the file is loaded), and start execution.
  1270.  
  1271.  Assuming the program runs correctly, which it should, you will see
  1272.  displayed on the screen first an unsorted list of numbers and then the same
  1273.  list in sorted order.
  1274.  
  1275.  This concludes the sample session. Additional information on compiling and
  1276.  on linking is provided in Chapter 5, "More About Compiling," and Chapter
  1277.  6, "More About Linking," respectively. The following program shows a log
  1278.  of the entire sample session, including prompts, your responses (shown in
  1279.  italics and small capital letters), and files written to the terminal
  1280.  screen.
  1281.  
  1282.       A> B:
  1283.       B> A:PAS1
  1284.       Source filename [.PAS]:SORT
  1285.       Object filename [SORT.PAS]:<RETURN>
  1286.       Source listing [NUL.LST]:USER
  1287.       Object listing [NUL.COD]:USER
  1288.  
  1289.           [Source listing display]
  1290.  
  1291.            Pass One     No errors detected.
  1292.  
  1293.       B> A:PAS2
  1294.  
  1295.            Code Area Size =  #05EC  (1516)
  1296.            Cons Area Size =  #00E6   (230)
  1297.            Data Area Size =  #0264   (612)
  1298.  
  1299.            Pass Two    No Errors Detected.
  1300.  
  1301.       B> A:PAS3
  1302.  
  1303.           [Object listing display]
  1304.  
  1305.       B> A:LINK
  1306.       Object modules [.OBJ]:SORT
  1307.       Run file [SORT.EXE]:<RETURN>
  1308.       List map [NUL.MAP]:<RETURN>
  1309.       Libraries [.LIB]:A:
  1310.  
  1311.       B> SORT
  1312.  
  1313.           [Program display]
  1314.  
  1315.  
  1316.  
  1317.  Chapter 4  Options for Compiling and Linking
  1318.  
  1319.  ───────────────────────────────────────────────────────────────────────────
  1320.  
  1321.  4.1  MS-DOS 2.0 File System Library
  1322.  
  1323.  4.2  Alternative Linkers
  1324.  
  1325.  4.3  Precision of Basic Numeric Types
  1326.  
  1327.  4.4  Floating-Point Options
  1328.  
  1329.  4.5  Changing the Default Math Library
  1330.  
  1331.  4.6  End Cases for Compilation and Execution
  1332.  
  1333.  
  1334.  
  1335.  This chapter contains descriptions of optional libraries and compiler
  1336.  features that are available to the users of Microsoft Pascal for
  1337.  customizing the performance of executable programs. We recommend, however,
  1338.  that you start by using the compiler with its defaults, particularly if
  1339.  you are inexperienced with Pascal.
  1340.  
  1341.  
  1342.  4.1  MS-DOS 2.0 File System Library
  1343.  
  1344.  When you specify DOS2PAS.LIB at linktime, it will automatically replace the
  1345.  standard file system in the runtime library, PASCAL.LIB, with the MS-DOS
  1346.  2.0 file system. This will not be true if you are specifying PASCAL.LIB
  1347.  explicitly and have not specified DOS2PAS.LIB before PASCAL.LIB in the list
  1348.  of libraries to be searched by the linker.
  1349.  
  1350.  ───────────────────────────────────────────────────────────────────────────
  1351.  Note
  1352.     Programs linked with DOS2PAS.LIB will not run under MS-DOS 1.25. An
  1353.     error message, "Incorrect DOS version" will be returned by the operating
  1354.     system.
  1355.  ───────────────────────────────────────────────────────────────────────────
  1356.  
  1357.  
  1358.  4.2  Alternative Linkers
  1359.  
  1360.  Two versions of the Microsoft LINK utility are provided with this version
  1361.  of Microsoft Pascal. The first, named LINK.EXE is the most current linker
  1362.  for MS-DOS versions 1.25 and earlier. It will run under MS-DOS 2.0 but
  1363.  cannot accept pathnames or subdirectories. The other version is named
  1364.  LINK.V2. It accepts pathnames and will run only on MS-DOS 2.0.
  1365.  
  1366.  You must use either LINK.EXE or LINK.V2 to link your program because
  1367.  earlier versions of the MS-DOS linker lack some of the internal features
  1368.  necessary for support of this version of Microsoft Pascal.
  1369.  
  1370.  LINK.EXE and LINK.V2 search libraries based on the contents of a library
  1371.  list. This list is derived from your command line specifications and the
  1372.  search directives produced by the compiler. If, after all the libraries
  1373.  have been searched, at least one reference has been resolved, the linkers
  1374.  will repeat the search and attempt to resolve the other references.
  1375.  Previous versions of the linker searched each library only once.
  1376.  
  1377.  Rename LINK.V2 to be an EXE file, if you want to use it at linktime. See
  1378.  Section 6.1.2, "Linking Libraries," for command-line and prompting
  1379.  information.
  1380.  
  1381.  ───────────────────────────────────────────────────────────────────────────
  1382.  Note
  1383.     If you use the earlier versions of Microsoft LINK, an otherwise
  1384.     accurate program may produce linker error messages and not execute
  1385.     properly.
  1386.  ───────────────────────────────────────────────────────────────────────────
  1387.  
  1388.  For more information about LINK.V2, see Section 6.3, "The Overlay Linker."
  1389.  
  1390.  
  1391.  4.3  Precision of Basic Numeric Types
  1392.  
  1393.  In Microsoft Pascal, the basic INTEGER type is, by default, equivalent to
  1394.  the Microsoft Pascal type INTEGER2 which is a 16-bit, two's complement
  1395.  integer. The basic REAL type is similarly equivalent to a REAL4 which is a
  1396.  four-byte real number.
  1397.  
  1398.  You can use the $integer:n metacommand with (n=4) to change the default and
  1399.  make INTEGER equivalent to INTEGER4 (but note the restrictions on
  1400.  INTEGER4). You can use the $real:n metacommand with (n=8) to make the REAL
  1401.  type equivalent to REAL8. Note that the default, which is equivalent to
  1402.  {$real:4 $integer:2}, will result in the fastest and smallest code.
  1403.  
  1404.  
  1405.  4.4  Floating-Point Options
  1406.  
  1407.  You can use metacommands and alternative libraries to change the way
  1408.  floating-point operations are carried out. (For more details, see Section
  1409.  10.4, "Floating-Point Operations.") The options are:
  1410.  
  1411.  
  1412.  8087.LIB / $floatcalls-
  1413.  
  1414.  If you know that all machines on which you will be running your program
  1415.  will have an 8087 installed, you can use 8087.LIB to reduce its size. You
  1416.  can reduce its size still further and improve its performance by compiling
  1417.  with the $floatcalls- metacommand.
  1418.  
  1419.  
  1420.  Alternate Math Option
  1421.  
  1422.  If performance on machines without 8087s installed is an overriding
  1423.  concern, and you do not care if your program does not exploit an 8087 if it
  1424.  is installed, and if you do not require the full power of the proposed IEEE
  1425.  floating-point standard, you can use the fast math package by linking with
  1426.  ALTMATH.LIB.
  1427.  
  1428.  
  1429.  Decimal Math Option
  1430.  
  1431.  Microsoft Pascal supports an alternative floating-point format in which
  1432.  decimal floating-point numbers up to 14 digits and within a limited
  1433.  exponent range can be represented exactly. The results of the operations on
  1434.  the numbers in this format are also represented exactly if they are in the
  1435.  allowable range. This option is particularly useful in business and
  1436.  financial applications where exact results are important.
  1437.  
  1438.  You select the decimal format by using the $decmath metacommand in all of
  1439.  your program units that use floating-point. You must link with DECMATH.LIB
  1440.  to support this format.
  1441.  
  1442.  ───────────────────────────────────────────────────────────────────────────
  1443.  Note
  1444.     Decimal floating-point and IEEE floating-point are not compatible.
  1445.  ───────────────────────────────────────────────────────────────────────────
  1446.  
  1447.  
  1448.  4.5  Changing the Default Math Library
  1449.  
  1450.  The default math library is contained in MATH.LIB. You can make either
  1451.  DECMATH.LIB, 8087.LIB, or ALTMATH.LIB the default by naming the one you
  1452.  want to be MATH.LIB.
  1453.  
  1454.  
  1455.  4.6  End Cases for Compilation and Execution
  1456.  
  1457.  The Microsoft Pascal Compiler can create several versions of your
  1458.  executable program. Here are some "best case" combinations of Microsoft
  1459.  Pascal options for particular processor configurations.
  1460.  
  1461.   1.  Fastest: (with 8087)
  1462.  
  1463.       To get the best possible performance if you have an 8087,
  1464.       use the $floatcalls- metacommand and {$integer:2 $real:4}
  1465.       (the default) and link with 8087.LIB. This will also be the
  1466.       smallest version of your program.
  1467.  
  1468.   2.  Fastest: (without 8087)
  1469.  
  1470.       To get the best possible performance without an 8087, use
  1471.       {$integer:2 $real:4} metacommands and link with ALTMATH.LIB.
  1472.  
  1473.   3.  Most portable, most consistent:
  1474.  
  1475.       If you want your program to run on any environment and to
  1476.       give the most accurate results possible, use the default
  1477.       compiler and library options. You can also compile using the
  1478.       $floatcalls- metacommand and reduce the size of your
  1479.       program without affecting the results.
  1480.  
  1481.  
  1482.  
  1483.  Chapter 5  More About Compiling
  1484.  
  1485.  ───────────────────────────────────────────────────────────────────────────
  1486.  
  1487.  5.1  Files Written by the Compiler
  1488.  
  1489.        5.1.1  The Object File
  1490.  
  1491.        5.1.2  The Source Listing File
  1492.  
  1493.        5.1.3  The Object Listing File
  1494.  
  1495.        5.1.4  The Intermediate Files
  1496.  
  1497.  5.2  Filename Conventions
  1498.  
  1499.  5.3  Starting the Compiler
  1500.  
  1501.        5.3.1  Giving No Parameters on the Command Line
  1502.  
  1503.        5.3.2  Giving All Parameters on the Command Line
  1504.  
  1505.        5.3.3  Giving Some Parameters on the Command Line
  1506.  
  1507.  5.4  Pass One Compiler Switches
  1508.  
  1509.  
  1510.  
  1511.  This chapter provides additional procedural information on the compiler,
  1512.  supplementing the discussion in Section 3.2, "Compiling Your Microsoft
  1513.  Pascal Program." For a more technical discussion of the compiler, see
  1514.  Section 10.1, "The Structure of the Compiler."
  1515.  
  1516.  
  1517.  5.1  Files Written by the Compiler
  1518.  
  1519.  In addition to creating several intermediate files, which it later reads
  1520.  and deletes, the compiler writes one required file and two optional files
  1521.  that represent your program in various ways. The object file is the one
  1522.  permanent file that must be created. The source listing and object listing
  1523.  files are optional; you may request that either or both of these be
  1524.  displayed or printed instead of being written to a disk file.
  1525.  
  1526.  
  1527.  5.1.1  The Object File
  1528.  
  1529.  The object file is written to disk after the completion of pass two of the
  1530.  compiler. It is a relocatable module, which contains relative rather than
  1531.  absolute addresses. Normally created with the .OBJ extension, the object
  1532.  module must be linked with the MS-Pascal runtime libraries to create an
  1533.  executable module containing absolute addresses.
  1534.  
  1535.  
  1536.  5.1.2  The Source Listing File
  1537.  
  1538.  The source listing file is a line-by-line account of the source file(s),
  1539.  with page headings and messages. Each line is preceded by a number that is
  1540.  referred to by any error messages that pertain to that source line.
  1541.  
  1542.  Compiler error messages, shown in the source listing, are also displayed on
  1543.  your terminal screen. See Appendix H, "Messages," in the Microsoft Pascal
  1544.  Reference Manual for a list and explanation of all error messages.
  1545.  
  1546.  If you include files in the compilation with the $include metacommand,
  1547.  these files are also shown in the source listing.
  1548.  
  1549.  Both the $include metacommand and the source listing are discussed in the
  1550.  Microsoft Pascal Reference Manual. See Section 18.3, "Source File
  1551.  Control," for information on $include; see Section 18.4, "Listing File
  1552.  Control," for a description of metacommands that control listing file
  1553.  format; see Section 18.5, "Listing File Format," for a discussion of
  1554.  features of the listing file.
  1555.  
  1556.  The various flags, level numbers, error message indicators, and symbol
  1557.  tables make the source listing useful for error checking and debugging.
  1558.  Many programmers prefer a printout of the source listing file rather than
  1559.  of the source file itself as a working copy of the program.
  1560.  
  1561.  
  1562.  5.1.3  The Object Listing File
  1563.  
  1564.  The object listing file, a symbolic, assembler-like listing of the object
  1565.  code, lists addresses relative to the start of the program or module.
  1566.  Absolute addresses are not determined until the object file itself is
  1567.  linked with the runtime libraries.
  1568.  
  1569.  The object listing file is used less often than the source listing file,
  1570.  but may be a useful tool during program development:
  1571.  
  1572.     1.  You can look at it simply to see what code the compiler generates
  1573.         and to familiarize yourself with it.
  1574.  
  1575.     2.  You can check to see whether a different construct or assembly
  1576.         language would improve program efficiency.
  1577.  
  1578.     3.  You can use it as a guide when debugging your program with the
  1579.         MS-DOS DEBUG utility.
  1580.  
  1581.  
  1582.  5.1.4  The Intermediate Files
  1583.  
  1584.  Pass one creates two intermediate files, PASIBF.SYM and PASIBF.BIN. These
  1585.  two intermediate files are always written to the default drive.
  1586.  
  1587.  Pass two reads and then deletes PASIBF.SYM and PASIBF.BIN. Pass two itself
  1588.  creates one or two new intermediate files, depending on whether or not
  1589.  you've requested an object listing. If, as for the sample session, you plan
  1590.  to run pass three to produce the object listing, pass two writes the two
  1591.  intermediate files, PASIBF.TMP and PASIBF.OID.
  1592.  
  1593.  If in pass one you do not request an object listing, pass two writes and
  1594.  later deletes just one new intermediate file, PASIBF.TMP.
  1595.  
  1596.  PAS2.EXE assumes that the intermediate files created in pass one are on the
  1597.  default drive. If you have switched disks so that they are on another
  1598.  drive, you must indicate their location on the command that starts pass
  1599.  two. For example:
  1600.  
  1601.       A:PAS2 A/PAUSE
  1602.  
  1603.  The "A" immediately following the command tells the compiler that
  1604.  PASIBF.BIN and PASIBF.SYM are on drive A:, instead of the default drive B:.
  1605.  The "/PAUSE" tells the compiler to pause before continuing so that you can
  1606.  insert the disk that contains them into drive A:.
  1607.  
  1608.  After pausing, pass two prompts as follows:
  1609.  
  1610.       Press the ENTER key to begin pass two.
  1611.  
  1612.  When you have inserted the new disk in drive A:, press the RETURN key and
  1613.  the compiler proceeds with pass two.
  1614.  
  1615.  PASIBF.TMP and PASIBF.OID are deleted from the default drive during pass
  1616.  three. If you change your mind after requesting an object listing file and
  1617.  decide not to run pass three, be sure to delete these files to recover the
  1618.  space on your disk.
  1619.  
  1620.  If you have a disk "drive" that is implemented with random access memory
  1621.  (or other faster file device), instead of an actual disk, this is a good
  1622.  location for intermediate files. Since they are processed twice each,
  1623.  first written and then read, compilation is faster if these files are
  1624.  written to such a fast access device.
  1625.  
  1626.  
  1627.  5.2  Filename Conventions
  1628.  
  1629.  When you start up the compiler, it prompts you for the names of four files:
  1630.  your source file, the object file, the source listing file, and the object
  1631.  listing file. The only one of these names you must supply is the source
  1632.  filename.
  1633.  
  1634.  This section describes how the compiler constructs the remaining filenames
  1635.  from the source filename and how you can override these defaults.
  1636.  
  1637.  A complete filename specification under MS-DOS has three parts:
  1638.  
  1639.     1.  Device name
  1640.  
  1641.         The name of the disk drive where the file is or will be. On a
  1642.         single-drive machine, all device names default to A:. On multidrive
  1643.         machines, if you do not specify a device, the compiler assumes the
  1644.         currently logged drive.
  1645.  
  1646.     2.  Filename
  1647.  
  1648.         The name you give to a file. Consult your operating system manual
  1649.         for any limitations on assigning filenames.
  1650.  
  1651.     3.  Filename extension
  1652.  
  1653.         Added to the filename for further identification of the file. The
  1654.         extension consists of up to three alphanumeric characters and must
  1655.         be preceded by a period. Although you may give any extension to a
  1656.         filename, the MS-Pascal Compiler and MS-LINK recognize and assign
  1657.         certain conventional filename extensions by default, as shown in the
  1658.         following list:
  1659.  
  1660.               Filename Extension     Function of File
  1661.               ──────────────────────────────────────────────────────────────
  1662.               .PAS                   MS-Pascal source file
  1663.               .FOR                   MS-FORTRAN source file
  1664.               .OBJ                   Relocatable object file
  1665.               .LST                   Source listing file
  1666.               .COD                   Object listing file
  1667.               .ASM                   Assembler source file
  1668.               .MAP                   Linker map file
  1669.               .LIB                   Library files
  1670.               .EXE                   Run file
  1671.  
  1672.  If you give unique extensions to your filenames, you must include the
  1673.  extension as part of the filename in response to a prompt. If you do not
  1674.  specify an extension, the MS-Pascal Compiler supplies one of those shown in
  1675.  Table 5.1.
  1676.  
  1677.  
  1678.  Table 5.1
  1679.  Filenames Assigned by the Compiler
  1680.  
  1681.  File              Device   Extension   Full Filename
  1682.  ───────────────────────────────────────────────────────
  1683.  Source file       dev:     .PAS        dev:filename.PAS
  1684.  
  1685.  Object file       dev:     .OBJ        dev:filename.OBJ
  1686.  
  1687.  Source listing    dev:     .LST        dev:NUL.LST
  1688.  
  1689.  Object listing    dev:     .COD        dev:NUL.COD
  1690.  
  1691.  
  1692.  Table 5.1 also shows the default filenames supplied by the compiler if you
  1693.  give a name for the source file and then press the RETURN key in response
  1694.  to each of the remaining compiler prompts.
  1695.  
  1696.  The device "dev:" is the currently logged drive. Even if you specify a
  1697.  device in the source filename, the remaining file specifications will
  1698.  default to the currently logged drive. You must explicitly specify the
  1699.  name of another drive if that is where you want a particular file to
  1700.  go.
  1701.  
  1702.  The NUL file is equivalent to creating no file at all; thus, by default,
  1703.  the compiler creates neither a source listing file nor an object listing
  1704.  file. If, in response to either of the last two prompts, you enter any part
  1705.  of a file specification, the remaining parts default as follows:
  1706.  
  1707.       Source listing     dev:filename.LST
  1708.       Object listing     dev:filename.COD
  1709.  
  1710.  Neither listing file is created unless you explicitly request it. If you
  1711.  specify any non-null file for the object listing, pass two leaves
  1712.  PASIBF.TMP and PASIBF.OID, the input files for pass three, on your work
  1713.  disk until you delete them, either explicitly or by running pass
  1714.  three.
  1715.  
  1716.  If you want to send either listing file to your screen or console, use one
  1717.  of the special filenames USER or CON. USER is recognized only by MS-Pascal
  1718.  (and MS-FORTRAN) and writes to the screen immediately as the listing is
  1719.  created. CON is recognized by all MS-DOS programs, but saves the screen
  1720.  output and writes it in blocks of 512 bytes.
  1721.  
  1722.  The general rules for filenames may be summarized as follows:
  1723.  
  1724.     1.  All lowercase letters in filenames are changed into uppercase
  1725.         letters. For example, the following three names are all considered
  1726.         equivalent to ABCDE.FGH:
  1727.  
  1728.             abcde.fgh     AbCdE.FgH     ABCDE.fgh
  1729.  
  1730.     2.  To enter a filename that has no extension in response to a prompt,
  1731.         type the name followed by a period.
  1732.  
  1733.         For example, typing ABC. in response to the source filename prompt
  1734.         gives a filename of ABC.PAS; typing ABC. instructs the compiler to
  1735.         accept ABC, with no extension, as the name.
  1736.  
  1737.     3.  Leading and trailing spaces are permitted. Therefore, the following
  1738.         is an acceptable response to the prompt for the source filename:
  1739.  
  1740.             ABC     &;
  1741.  
  1742.         The filename itself must not contain spaces.
  1743.  
  1744.     4.  You may override any defaults by typing all or part of the name
  1745.         instead of pressing the RETURN key. For example, if the currently
  1746.         logged drive is B: and you want the object file to be written to the
  1747.         disk in drive A:, type A: in response to the following prompt:
  1748.  
  1749.             Object Filename [ABC.OBJ]:
  1750.  
  1751.         This results in a full filename of A:ABC.OBJ for the object file.
  1752.  
  1753.     5.  Listing files default to null. However, if you specify any part of a
  1754.         legal filename, the default changes so that the compiler creates a
  1755.         filename with the same default rules that apply to the source and
  1756.         object files. Specifically, if you give a drive or extension, the
  1757.         base name is the base name of the source file. For example, typing
  1758.         B: in response to the object listing prompt gives a filename
  1759.         of B:ABC.COD.
  1760.  
  1761.     6.  Typing a semicolon after the source filename or in response to any
  1762.         of the later prompts tells the compiler to assign the default
  1763.         filenames to all remaining files. This is the quickest way to start
  1764.         the compiler (if you don't need either of the listing files). For
  1765.         example, typing ABC; in response to the source file prompt
  1766.         eliminates the remaining prompts and  results in the following
  1767.         filenames:
  1768.  
  1769.             Source file      B:ABC.PAS
  1770.             Object file      B:ABC.OBJ
  1771.             Source listing   B:NUL.LST
  1772.             Object listing   B:NUL.COD
  1773.  
  1774.         You may not enter a semicolon to specify a source file, since the
  1775.         source file has no default filename.
  1776.  
  1777.  
  1778.  5.3  Starting the Compiler
  1779.  
  1780.  You can start the MS-Pascal Compiler in one of three ways:
  1781.  
  1782.     1.  You can let the compiler prompt you for each of the three filenames
  1783.         (as in the sample session).
  1784.  
  1785.     2.  You can give all four filenames on the command line.
  1786.  
  1787.     3.  You can give some of the filenames on the command line and let the
  1788.         compiler prompt you for the rest.
  1789.  
  1790.  Each of these methods is discussed in the following sections. The second
  1791.  method, giving all four filenames on the command line, is particularly
  1792.  useful when you plan to use a batch command file. See Chapter 7, "Using a
  1793.  Batch Command File," for information.
  1794.  
  1795.  
  1796.  5.3.1  Giving No Parameters on the Command Line
  1797.  
  1798.  To start the compiler without giving any of the necessary parameters
  1799.  (filenames) on the command line, simply type the following:
  1800.  
  1801.       A:PAS1
  1802.  
  1803.  As in the sample session, the compiler prompts you for each of the four
  1804.  filenames that it needs. A typical session might look like this (your
  1805.  responses are shown in italics and small capital letters):
  1806.  
  1807.       Source filename [.PAS]:MYFILE
  1808.       Object filename [MYFILE.OBJ]:<RETURN>
  1809.       Source listing  [NUL.LST]:MYFILE
  1810.       Object listing  [NUL.COD]:<RETURN>
  1811.  
  1812.  This sequence of responses would give you an object file called
  1813.  B:MYFILE.OBJ, a source listing file called B:MYFILE.LST, and no object
  1814.  listing file.
  1815.  
  1816.  ───────────────────────────────────────────────────────────────────────────
  1817.  Note
  1818.     Pressing the RETURN key means that you accept the default filename
  1819.     shown in brackets; giving any part of a file specification creates a
  1820.     file with the same default rules that apply to other files.
  1821.  ───────────────────────────────────────────────────────────────────────────
  1822.  
  1823.  
  1824.  5.3.2  Giving All Parameters on the Command Line
  1825.  
  1826.  Instead of letting the compiler prompt you for each of the four filenames
  1827.  in turn, you may implicitly or explicitly give all four names on the same
  1828.  command line with which you start the compiler. This eliminates prompting
  1829.  for the filenames and is particularly useful when you are using the MS-DOS
  1830.  batch file facility. See Chapter 7, "Using a Batch Command File," for
  1831.  information on creating a batch command file for use with the compiler.
  1832.  
  1833.  The general form of the command line that includes all of the compiler
  1834.  parameters is as follows:
  1835.  
  1836.       A:PAS1 source, object, sourcelist, objectlist;
  1837.  
  1838.  The same default naming conventions apply here as when you are prompted for
  1839.  the filenames.
  1840.  
  1841.  You must separate each filename with a comma; spaces are optional. Put a
  1842.  semicolon at the end of the line to indicate that you do not want
  1843.  additional prompting.
  1844.  
  1845.  If you omit a filename after a comma, the file by default is given the same
  1846.  filename as the source, the default device designation, and the default
  1847.  extension. Thus, these two command lines are equivalent:
  1848.  
  1849.       A:PAS1 DATABASE,DATABASE,DATABASE,DATABASE;
  1850.       A:PAS1 DATABASE,,,;
  1851.  
  1852.  Both result in the following four filenames being assigned:
  1853.  
  1854.       Source file         B:DATABASE.PAS
  1855.       Object file         B:DATABASE.OBJ
  1856.       Source listing      B:DATABASE.LST
  1857.       Object listing      B:DATABASE.COD
  1858.  
  1859.  If you want the normal defaults, with NUL listing files, use the semicolon
  1860.  (;) following the source filename. Thus, these command lines are
  1861.  equivalent:
  1862.  
  1863.       A:PAS1 YOYO,YOYO,NUL,NUL;
  1864.       A:PAS1 YOYO;
  1865.  
  1866.  You may include spaces before or after filenames, but not within them. The
  1867.  command line may also include switches, described in Section 5.4, "Pass
  1868.  One Compiler Switches," anywhere that spaces can go.
  1869.  
  1870.  
  1871.  5.3.3  Giving Some Parameters on the Command Line
  1872.  
  1873.  You may also start the compiler by giving one or more of the required
  1874.  filenames on the command line and letting the compiler prompt you for the
  1875.  rest. This feature of the compiler makes it relatively failsafe to use.
  1876.  
  1877.  For example, if you give only the names of the source file and the object
  1878.  file on the command line, the compiler will prompt you for the names of the
  1879.  source listing and the object listing (your responses are shown in italics
  1880.  and small capital letters):
  1881.  
  1882.       B> A:PAS1 TEST,TEST
  1883.       Source listing [NUL.COD]: TEST
  1884.       Object listing [NUL.COD]: <RETURN>
  1885.  
  1886.  This sequence of responses results in the following filenames:
  1887.  
  1888.       Source file         B:TEST.PAS
  1889.       Object file         B:TEST.OBJ
  1890.       Source listing      B:TEST.LST
  1891.       Object listing      B:NUL.COD
  1892.  
  1893.  
  1894.  5.4  Pass One Compiler Switches
  1895.  
  1896.  By adding switches to the command line when you start pass one of the
  1897.  compiler, or to your response to any of the pass one prompts, you can
  1898.  direct the MS-Pascal Compiler to perform additional or alternate functions.
  1899.  The switch tells the compiler to "switch on" a special function or to alter
  1900.  a normal compiler function. More than one switch may be used, but each must
  1901.  begin with a slash (/). Do not confuse these switches with the linker
  1902.  switches, which are discussed in Section 6.4, "Linker Switches."
  1903.  
  1904.  Switches affect the entire compilation and may be placed anywhere that
  1905.  spaces may go. You may enter them either on the command line or in response
  1906.  to compiler prompts. Table 5.2 shows the compiler switches that are
  1907.  currently available to you, the default position of the switch, and the
  1908.  corresponding metacommand.
  1909.  
  1910.  
  1911.  Table 5.2
  1912.  Pass One Compiler Switches
  1913. ╓┌────────┌─────────┌─────────────┌──────────────────────────────────────────╖
  1914.  Switch   Default   Metacommand   Action
  1915.  ───────────────────────────────────────────────────────
  1916.  /A       off       $indexck      Checks for array index
  1917.                                   values in range,
  1918.                                   including super array
  1919.                                   indices
  1920.  
  1921.  /D       off       $debug        Switches on all
  1922.                                   debugging switches
  1923.  
  1924.  /E       off       $entry        Generates procedure
  1925.                                   entry and exit calls
  1926.                                   for debugger
  1927.  
  1928.  /I       off       $initck       Checks for use of
  1929.                                   uninitialized values
  1930.  
  1931.  /L       off       $line         Generates line number
  1932.                                   calls for debugger
  1933.  
  1934.  Switch   Default   Metacommand   Action
  1935. 
  1936.  /M       off       $mathck       Checks for mathe-
  1937.                                   matical errors such as
  1938.                                   overflow and division
  1939.                                   by zero
  1940.  
  1941.  /N       off       $nilck        Checks for
  1942.                                   dereferencing of any
  1943.                                   pointers that are NIL
  1944.  
  1945.  /Q       off       $debug        Switches off all
  1946.                                   debugging switches
  1947.  
  1948.  /R       off       $rangeck      Checks for subrange
  1949.                                   validity including
  1950.                                   assignments
  1951.  
  1952.  /S       off       $stackck      Checks for stack
  1953.                                   overflow at
  1954.                                   procedure or
  1955.  Switch   Default   Metacommand   Action
  1956.                                  procedure or
  1957.                                   function entry
  1958.  
  1959.  Since all of the pass one switches correspond to MS-Pascal metacommands,
  1960.  you can achieve the same effect either by using the metacommand in the
  1961.  source file or by giving the command as a switch to the compiler. However,
  1962.  any instruction given as a metacommand in the source file overrides the
  1963.  corresponding switch given at compile time.
  1964.  
  1965.  The MS-Pascal metalanguage is discussed in detail in Chapter 18, "Microsoft
  1966.  Pascal Metacommands," of the Microsoft Pascal Reference Manual. The two
  1967.  switches, /D and /Q, are equivalent to the  $debug+ and $debug-
  1968.  metacommands, respectively, except that they also turn on and off $entry
  1969.  and $line.
  1970.  
  1971.  Several of the switches correspond to runtime error checking metacommands
  1972.  that end with the letters "CK". Because of the way these switches are
  1973.  implemented, turning one off does not guarantee that the check will never
  1974.  be performed; it only means that no extra effort will be spent to perform
  1975.  the check.
  1976.  
  1977.  ───────────────────────────────────────────────────────────────────────────
  1978.  Important
  1979.     One strong caution should be observed. Error-checking switches and
  1980.     their corresponding metacommands cause a significant increase in the
  1981.     volume of code generated. You may wish to use them in the early
  1982.     stages of program development, then recompile your program without
  1983.     them to reduce your program's code size and decrease its execution
  1984.     time.
  1985.  ───────────────────────────────────────────────────────────────────────────
  1986.  
  1987.  The following sample command lines and responses illustrate the use of
  1988.  compiler switches (your responses are shown in italics):
  1989.  
  1990.  This turns on $indexck:
  1991.  
  1992.       B> A:PAS1 /A DEMO,,,NUL
  1993.       B> A:PAS1 DEMO,,,/D
  1994.  
  1995.  and then turns on $mathck and $indexck, and later $initck:
  1996.  
  1997.       B> A:PAS1 DEMO/Q
  1998.       Object filename [DEMO.OBJ]: /M/A
  1999.       Source listing  [NUL.LST]: DEMO
  2000.       Object listing  [NUL.COD]: /I
  2001.  
  2002.  
  2003.  
  2004.  Chapter 6  More About Linking
  2005.  
  2006.  ───────────────────────────────────────────────────────────────────────────
  2007.  
  2008.  6.1  Files Read by the Linker
  2009.  
  2010.        6.1.1  Object Modules
  2011.  
  2012.                6.1.1.1  Standard Runtime Libraries
  2013.  
  2014.                6.1.1.2  Auxiliary Libraries
  2015.  
  2016.        6.1.2  Linking Libraries
  2017.  
  2018.  6.2  Files Written by the Linker
  2019.  
  2020.        6.2.1  The Run File
  2021.  
  2022.        6.2.2  The Linker Listing File
  2023.  
  2024.        6.2.3  VM.TMP
  2025.  
  2026.  6.3     The Overlay Linker
  2027.  
  2028.        6.3.1  Restrictions
  2029.  
  2030.        6.3.2  Overlay Manager Prompts
  2031.  
  2032.  6.4  Linker Switches
  2033.  
  2034.  
  2035.  
  2036.  This chapter provides an overview of what you will see on your screen when
  2037.  you start LINK.EXE, the default version of Microsoft LINK. Included in
  2038.  this overview is a description of the standard runtime libraries and the
  2039.  auxiliary libraries provided with this version of the Microsoft Pascal
  2040.  Compiler. Also included is a discussion of the optional version of
  2041.  Microsoft LINK, LINK.V2, which accepts pathnames and overlays.
  2042.  
  2043.  
  2044.  6.1  Files Read by the Linker
  2045.  
  2046.  A successful Microsoft Pascal compilation produces a relocatable object
  2047.  file. Linking, the next step in program development, is the process of
  2048.  converting one or more relocatable object files into an executable
  2049.  program.
  2050.  
  2051.  
  2052.  6.1.1  Object Modules
  2053.  
  2054.  Object files can come from any of the following sources:
  2055.  
  2056.     1.  Microsoft Pascal compilands (programs, modules, or units)
  2057.  
  2058.     2.  Microsoft FORTRAN compilands (programs, subroutines, or functions)
  2059.  
  2060.     3.  user code in other high-level languages
  2061.  
  2062.     4.  assembly language routines
  2063.  
  2064.     5.  routines in standard runtime library modules that support facilities
  2065.         such as error handling, heap variable allocation, or input/output
  2066.  
  2067.  Interfacing to Microsoft FORTRAN routines is quite straightforward. The
  2068.  Microsoft FORTRAN procedure or function must be external in the Microsoft
  2069.  Pascal source code, and all parameters must be VARS or CONSTS. For other
  2070.  languages, see the appropriate reference and user manuals.
  2071.  
  2072.  You may need to write assembly language interface routines to translate
  2073.  from the Microsoft Pascal or Microsoft FORTRAN calling convention or
  2074.  function return to the one used by that language. Whatever the language,
  2075.  it must be able to produce linkable object modules. For information on
  2076.  linking assembly language routines, see Chapter 9, "Using Assembly
  2077.  Language Routines." For further information on Microsoft LINK, see the
  2078.  appropriate chapter in your MS-DOS manual.
  2079.  
  2080.  The ability to link together programs, units, and modules of Microsoft
  2081.  Pascal source code, as well as assembly language and library routines,
  2082.  allows you to develop a program incrementally. Separate compilation and
  2083.  later linking of separate parts of a program not only reduces the need for
  2084.  continual recompilation, it also allows you to create programs larger than
  2085.  64K bytes of code. See Chapter 8, "Compiling and Linking Large Programs,"
  2086.  for more information.
  2087.  
  2088.  For now, assume that you have created a program that uses one Microsoft
  2089.  Pascal unit and one Microsoft Pascal module and also contains two assembly
  2090.  language external procedures. Assume further that these files have already
  2091.  been compiled or, in the case of the assembly language routines, already
  2092.  assembled and that the files thus created are the following:
  2093.  
  2094.       PROG.OBJ
  2095.       UNIT.OBJ
  2096.       MODU.OBJ
  2097.       ASM1.OBJ
  2098.       ASM2.OBJ
  2099.  
  2100.  To link these all together, first start the linker by typing the
  2101.  following:
  2102.  
  2103.       A:LINK
  2104.  
  2105.  Like the compiler, the linker gives a sequence of four prompts. Before
  2106.  linking can proceed, you must explicitly or implicitly supply the following
  2107.  pieces of information:
  2108.  
  2109.     1.  the name(s) of the object modules to be linked
  2110.  
  2111.     2.  the name to be given to the executable run file
  2112.  
  2113.     3.  the linker listing file
  2114.  
  2115.     4.  the names of any libraries to be searched (other than PASCAL.LIB)
  2116.  
  2117.  As with the compiler, responses to all except the first prompt may be
  2118.  supplied by defaults.
  2119.  
  2120.  In response to the first linker prompt, enter the names of the object
  2121.  files, separated by plus signs as shown:
  2122.  
  2123.       PROG+UNIT+MODU+ASM1+ASM2
  2124.  
  2125.  The first object file listed must be a Microsoft Pascal program, module, or
  2126.  unit, although it need not be the main program. Do not put any assembly
  2127.  language module first; doing so may result in segments being ordered
  2128.  incorrectly. After the initial Microsoft Pascal object file, you may list
  2129.  the other modules, units, or assembly language routines in any order.
  2130.  
  2131.  ───────────────────────────────────────────────────────────────────────────
  2132.  Note
  2133.     Typing a semicolon at any point in the prompting session after you
  2134.     have specified the object files that you wish to link, tells the
  2135.     linker to omit the remaining prompts and to supply defaults for all
  2136.     remaining parameters (see Table 6.1 that follows).
  2137.  ───────────────────────────────────────────────────────────────────────────
  2138.  
  2139.  
  2140.           Table 6.1
  2141.           Linker Defaults
  2142.  
  2143.           Prompt              Default Response
  2144.           ─────────────────────────────────────
  2145.           Object modules      None
  2146.           Run file            prog.EXE
  2147.           List map            NUL.MAP, (i.e., no map)
  2148.           Libraries           PASCAL.LIB
  2149.  
  2150.  
  2151.  6.1.1.1  Standard Runtime Libraries
  2152.  
  2153.  A runtime library contains runtime routines that are required during
  2154.  linking to resolve references made during compilation. (See Section
  2155.  10.3.1, "Runtime Routines," for a complete list.) It also may contain
  2156.  fixups used in floating-point instructions. (See Section 10.4.1,
  2157.  "The $floatcalls- Option," for details.)
  2158.  
  2159.  Microsoft Pascal causes the linker to search for the runtime libraries
  2160.  PASCAL.LIB and MATH.LIB which are supplied with the compiler and contain
  2161.  the standard runtime modules for Pascal. MATH.LIB contains the default
  2162.  floating-point math package. See Chapter 10, "Advanced Topics," for more
  2163.  details about these elements of MATH.LIB.
  2164.  
  2165.  If you don't use any real numbers in your programs, MATH.LIB is not
  2166.  required at linktime. But if you have unresolved references when you link,
  2167.  the linker will request MATH.LIB to satisfy them. You can also change the
  2168.  default math package by renaming MATH.LIB and naming the library of your
  2169.  choice to be 'MATH.LIB.'
  2170.  
  2171.  
  2172.  6.1.1.2  Auxiliary Libraries
  2173.  
  2174.  You may wish the linker to search additional libraries at runtime. The
  2175.  auxiliary libraries supplied with Microsoft Pascal are:
  2176.  
  2177.     1.  ALTMATH.LIB which contains a high speed floating-point package
  2178.  
  2179.     2.  8087.LIB which contains 'stubs' for the floating-point package
  2180.  
  2181.     3.  DECMATH.LIB which contains decimal floating-point support routines
  2182.  
  2183.     4.  DOS2PAS.LIB which contains the MS-DOS 2.0 input/output system
  2184.  
  2185.  ───────────────────────────────────────────────────────────────────────────
  2186.  Note
  2187.     The auxiliary math libraries completely replace MATH.LIB and can be
  2188.     specified before or after an explicit reference to PASCAL.LIB. If you
  2189.     specify them first, the automatic search for MATH.LIB will be
  2190.     suppressed. You must not specify more than one math library explicitly.
  2191.  
  2192.     DOS2PAS.LIB replaces the equivalent part of PASCAL.LIB and must be
  2193.     searched before PASCAL.LIB. This will occur automatically unless
  2194.     you are specifying PASCAL.LIB explicitly. In this case, DOS2PAS.LIB must
  2195.     come before PASCAL.LIB in the list of libraries supplied to the linker.
  2196.  ───────────────────────────────────────────────────────────────────────────
  2197.  
  2198.  
  2199.  6.1.2  Linking Libraries
  2200.  
  2201.  To produce a library search using the LINK.EXE prompts, you specify the
  2202.  desired library at the "Libraries" prompt. For example, if you wanted
  2203.  PASCAL.LIB to be searched, you would enter pascal.lib in the sequence of
  2204.  prompts;
  2205.  
  2206.       Object Modules [.OBJ]:your modules
  2207.       Run File [SORT.EXE]:<RETURN>
  2208.       List File [NUL.MAP]:<RETURN>
  2209.       Libraries [.LIB]:pascal.lib
  2210.  
  2211.  On the command line, it would look as shown here:
  2212.  
  2213.       A>LINK your modules ,,, pascal.lib
  2214.  
  2215.  If PASCAL.LIB or any library that you have specified cannot be found, the
  2216.  following message will appear on your screen:
  2217.  
  2218.       Cannot find library filename.lib
  2219.       Enter new library spec:
  2220.  
  2221.  Switch disks if necessary, and then type the name of the library that you
  2222.  wish to be searched. If instead you want linking to proceed without a
  2223.  library search, respond by pressing the RETURN key.
  2224.  
  2225.  You can achieve the same effect by using the linker option switch,
  2226.  /NODEFAULTLIBRARYSEARCH, to override the automatic search for PASCAL.LIB.
  2227.  However, this will produce unresolved reference error messages unless you
  2228.  replace every required runtime routine with a routine of your own.
  2229.  
  2230.  To instruct the linker to search other libraries (for example, FORTRAN.LIB)
  2231.  as well as PASCAL.LIB, give the library names, separated by plus signs, in
  2232.  response to the final linker prompt,
  2233.  
  2234.     Libraries [.LIB]:pascal.lib+fortran.lib+stat.lib
  2235.  
  2236.  See your MS-DOS User's Guide for complete information on using different
  2237.  libraries with Microsoft LINK. Because a library is read twice by the
  2238.  linker, this file is also a good candidate for a file to put on a RAM-based
  2239.  disk drive or other fast file device.
  2240.  
  2241.  If you are using LINK.EXE, you may specify just the drive, or just the
  2242.  library filename, or both the drive and the filename. If you are using
  2243.  LINK.V2, you may specify the library filename in a path
  2244.  (drive:\pathname\filename and extension). For example, if you want the
  2245.  standard runtime library, PASCAL.LIB, you respond,
  2246.  
  2247.          A>LINK your modules ,,, \pascal\
  2248.  
  2249.  The linker will look for PASCAL.LIB in the PASCAL directory on drive A:.
  2250.  If you respond,
  2251.  
  2252.          A>LINK your modules ,,, \pascal\foo\
  2253.  
  2254.  the linker will look for FOO.LIB.
  2255.  
  2256.  ───────────────────────────────────────────────────────────────────────────
  2257.  Note
  2258.     You cannot specify a pathname with the default linker, LINK.EXE.
  2259.  ───────────────────────────────────────────────────────────────────────────
  2260.  
  2261.  
  2262.  6.2  Files Written by the Linker
  2263.  
  2264.  The primary output of the linking process is an executable run file. You
  2265.  may also request a linker map or listing file, which serves much the same
  2266.  purpose as the compiler listing files. The linker, if need be, also writes
  2267.  and later deletes one temporary file.
  2268.  
  2269.  
  2270.  6.2.1  The Run File
  2271.  
  2272.  The run file produced by the linker is your executable program.
  2273.  
  2274.  The default filename, given in brackets as part of the prompt, is taken
  2275.  from the name of the first module listed in response to the first prompt.
  2276.  To accept this prompt, press the RETURN key. To specify another run
  2277.  filename, type in the name you want. All run files receive the extension
  2278.  .EXE.
  2279.  
  2280.  The linker ordinarily saves the run file, with the extension .EXE, on the
  2281.  disk in the default drive. To specify another drive, which may be
  2282.  necessary if your program is large, type a drive name or drive name and
  2283.  pathname for LINK.V2 in response to the run file prompt.
  2284.  
  2285.  
  2286.  6.2.2  The Linker Listing File
  2287.  
  2288.  The link map, also called the linker listing file, shows the addresses,
  2289.  relative to the start of the run module, for every code or data segment in
  2290.  your program. If you request it with the /MAP switch, the linker map can
  2291.  also include all PUBLIC variables. See Section 6.4, "Linker Switches," for
  2292.  information on the /MAP switch.
  2293.  
  2294.  The link map defaults to the NUL file, unless you specifically request that
  2295.  it be printed, displayed on the screen, or saved on disk. In the early
  2296.  stages of program development, you may find it useful to inspect the linker
  2297.  map in these two instances:
  2298.  
  2299.     1.  when using the debugger to set breakpoints and locate routines and
  2300.         variables
  2301.  
  2302.     2.  to find out why a load module is so large (for example, what
  2303.         routines are loaded, how big they are, and what's in them)
  2304.  
  2305.  As the prompt indicates, the default for the linker map is the NUL file,
  2306.  that is, no file at all. Press the RETURN key to accept this default. If
  2307.  you wish to see the linker map but not have it written to a disk file, type
  2308.  CON in response to the list file prompt. (The special filename USER is not
  2309.  recognized by the linker.) If you want the file written to disk, give a
  2310.  device or filename.
  2311.  
  2312.  
  2313.  6.2.3  VM.TMP
  2314.  
  2315.  Linking begins after you have responded to all of the linker prompts. If
  2316.  the linker needs more memory space to link your program than is available,
  2317.  it will create a file called VM.TMP on the disk in the default drive and
  2318.  will display a message like the following:
  2319.  
  2320.       VM.TMP has been created.
  2321.       Do not change disk in drive B:.
  2322.  
  2323.  If the additional space is used up or if you remove the disk that contains
  2324.  VM.TMP before linking is complete, the linker will terminate.
  2325.  
  2326.  If the linker is terminated with a CTRL-C, use the MS-DOS command DIR to
  2327.  check the contents of your disk to make sure that VM.TMP has been deleted.
  2328.  Then, to make sure the space has been released, use the CHKDSK program
  2329.  (supplied with MS-DOS). CHKDSK will reclaim any available space from
  2330.  unclosed files and tell you the total amount of available space on the
  2331.  disk.
  2332.  
  2333.  
  2334.  6.3  The Overlay Linker
  2335.  
  2336.  You can direct the MS-DOS 2.0 version of the linker (named LINK.V2) to
  2337.  create an overlayed version of your program. This means that parts of your
  2338.  program will only be loaded if and when they are needed, and will share the
  2339.  same space in memory. Your program will be smaller as a result, but will
  2340.  usually run more slowly because of the time needed to read and reread the
  2341.  code into memory.
  2342.  
  2343.  Provided your modules obey the restrictions described below, all you have
  2344.  to do is specify the overlay structure to the linker. Loading of the
  2345.  overlays is automatic. You specify overlays in the list of modules that you
  2346.  submit to the linker by enclosing them in parentheses. Each parenthetical
  2347.  list represents one overlay. For example, in the following response to the
  2348.  OBJECT MODULES prompt,
  2349.  
  2350.      OBJECT MODULES [.OBJ]:a + (b+c) + (e+f) + g + (i+j)
  2351.  
  2352.  elements (b+c), (e+f) and (i+j) are overlays. The remaining modules and
  2353.  any drawn from the runtime libraries, make up the resident part of your
  2354.  program, or "root." Overlays are loaded into the same region of memory, so
  2355.  only one can be resident at a time. Duplicate names in different overlays
  2356.  are not supported, so each module can occur only once in a program.
  2357.  
  2358.  The linker will replace calls from the "root" to an overlay and calls from
  2359.  an overlay to another overlay with an interrupt (followed by module
  2360.  identification and offset). The interrupt is, by default, number #CD. If
  2361.  this conflicts with another use of this interrupt number in your program,
  2362.  you can specify another using the /OVERLAYINTERRUPT switch. This switch
  2363.  takes a numeric parameter.
  2364.  
  2365.  
  2366.  6.3.1   Restrictions
  2367.  
  2368.  The name for the overlays is appended to the EXE file, and the name of this
  2369.  file is encoded into the program so the overlay manager can access it. If,
  2370.  when the program is initiated, the overlay manager cannot find the EXE file
  2371.  (perhaps you have renamed it or it is not in a directory specified by the
  2372.  path environment variable), then the linker will prompt you for a new name.
  2373.  
  2374.  You can only overlay modules to which control is transferred and returned
  2375.  by a standard 8086 long (segmented) call/return instruction. This will
  2376.  always be true for Pascal and FORTRAN modules (although you should not
  2377.  attempt to overlay any of the modules in the standard runtime libraries).
  2378.  An exception is a function or a procedure parameter. In this case, the
  2379.  actual parameter (the function or procedure that you specify as the
  2380.  parameter) must either be in the same overlay in which the parameter is
  2381.  used to call it, or in the "root."  You cannot use long jumps or indirect
  2382.  calls to pass control to an overlay.
  2383.  
  2384.  
  2385.  6.3.2  Overlay Manager Prompts
  2386.  
  2387.  Suppose that B: is the default drive; then in the following example,
  2388.  
  2389.          Cannot find PAYROLL.EXE
  2390.          Please enter new program spec:\employee\data\
  2391.  
  2392.  the response "\employee\data\" causes the overlay manager to look for
  2393.  \employee\data\payroll.exe on drive B:.
  2394.  
  2395.  Now, suppose that it becomes necessary to change the disk in drive B:. If
  2396.  the overlay manager needs to swap overlays, it will find that PAYROLL.EXE
  2397.  is no longer on drive B:, and will give the following message,
  2398.  
  2399.          Please put diskette containing
  2400.          B:\employee\data\payroll.exe
  2401.          in drive B: and strike any key when ready.
  2402.  
  2403.  After the overlay has been read from the disk, the overlay manager will
  2404.  give the following message,
  2405.  
  2406.          Please restore the original diskette.
  2407.          Strike any key when ready.
  2408.  
  2409.  
  2410.  6.4  Linker Switches
  2411.  
  2412.  After any of the linker prompts, you may give one or more linker switches.
  2413.  Table 6.2 summarizes the linker switches you may use with Microsoft Pascal.
  2414.  See your MS-DOS manual for more information on linker switches and when and
  2415.  how to use them.
  2416.  
  2417.  
  2418.  Table 6.2
  2419.  Microsoft LINK Switches
  2420. ╓┌────────────────────────┌──────────────────────────────────────────────────╖
  2421.  Switch                   Action
  2422.  ───────────────────────────────────────────────────────────────────────────
  2423.  /CPARMAXALLOC:NNNN       By default, the cparMaxAlloc field (at offset
  2424.                           0C) in the EXE header (see Chapter 5 in the
  2425.                           MS-DOS 2.0 Programmer's Reference) is set
  2426.                           to 65535. This switch allows you to set the
  2427.                           value to any number between 1 and 65535; if the
  2428.                           value you specify is less than the computed
  2429.                           value of cparMinAlloc, the linker will use
  2430.                           the value of cparMinAlloc (at offset  0A)
  2431.                           instead. If you are running programs under
  2432.                           MS-DOS 1.25, you should not use this switch.
  2433.  
  2434.  /DSALLOCATE              Loads data at the high end of the data segment.
  2435.                           For Microsoft Pascal and Microsoft FORTRAN
  2436.                           programs, this switch is required and supplied
  2437.                           automatically by the compiler.
  2438.  Switch                   Action
  2439.                          automatically by the compiler.
  2440.  
  2441.  /LINENUMBERS             Includes source listing line numbers and
  2442.                           associated addresses in the linker listing,
  2443.                           which allows you to correlate machine
  2444.                           addresses with source lines when debugging.
  2445.                           This correlation is also available on the
  2446.                           object listing.
  2447.  
  2448.  /MAP                     Includes all EXTERN and PUBLIC variables
  2449.                           in the linker list file.
  2450.  
  2451.  /NODEFAULTLIBRARYSEARCH  Tells the linker not to automatically
  2452.                           search PASCAL.LIB.
  2453.  
  2454.  /NOGROUPASSOCIATION      If you are using LINK.V2 and find that you
  2455.                           must link in an old Microsoft Pascal/FORTRAN
  2456.                           library, you must use this switch. This option
  2457.                           causes LINK.V2 to initiate the addressing
  2458.                           scheme of linkers delivered with MS-Pascal
  2459.  Switch                   Action
  2460.                          scheme of linkers delivered with MS-Pascal
  2461.                           versions 3.14 and earlier.
  2462.  
  2463.  /NOIGNORECASE            By default, "FOO", "foo", and "Foo" are treated
  2464.                           by the linker as being equivalent. If
  2465.                           /NOIGNORECASE is specified, then they are all
  2466.                           different symbols.
  2467.  
  2468.  /OVERLAYINTERRUPT:NNNN   By default, the interrupt number used for
  2469.                           passing control to overlays is CD hexadecimal.
  2470.                           The overlay interrupt switch allows the user to
  2471.                           select a different interrupt number. NNNN can
  2472.                           be any of the following:
  2473.  
  2474.                           ■ A decimal number from 0 to 255 (numbers
  2475.                             that conflict with MS-DOS interrupts are
  2476.                             not prevented, but their use is inadvisable).
  2477.  
  2478.                           ■ An octal number from 0 to 377. A number
  2479.                             is interpreted as octal if it starts with
  2480.  Switch                   Action
  2481.                            is interpreted as octal if it starts with
  2482.                             a zero, e.g., 10 is 10 decimal but 010 is
  2483.                             8 decimal.
  2484.  
  2485.                           ■ A hexadecimal number from 0 to FF. A
  2486.                             number is interpreted as hexadecimal if
  2487.                             it starts with "0x". Thus, 10 is ten
  2488.                             decimal, 010 is 8 decimal, and 0x10 is 16
  2489.                             decimal.
  2490.  
  2491.  /PAUSE                   Tells Microsoft LINK to display the following
  2492.                           message:
  2493.  
  2494.                             About to generate .EXE file
  2495.                             Change disks <press RETURN>
  2496.  
  2497.                           You may then change disks before the
  2498.                           linker continues.
  2499.  
  2500.  As with all linker switches, a unique abbreviation of the switch name is
  2501.  acceptable in place of the whole name.
  2502.  
  2503.  The /PAUSE switch is particularly useful for linking large programs, since
  2504.  it allows you to switch disks before writing the run file. However, if a
  2505.  VM.TMP file is created, you must not switch the disk in the default drive.
  2506.  
  2507.  ───────────────────────────────────────────────────────────────────────────
  2508.  Note
  2509.     For Microsoft Pascal and Microsoft FORTRAN programs, do not use either
  2510.     of the additional linkerswitches /HIGH or /STACK.
  2511.  ───────────────────────────────────────────────────────────────────────────
  2512.  
  2513.  
  2514.  
  2515.  Chapter 7  Using a Batch Command File
  2516.  
  2517.  ───────────────────────────────────────────────────────────────────────────
  2518.  
  2519.  
  2520.  
  2521.  MS-DOS allows you to create a batch file for executing a series of
  2522.  commands. Creating and using batch command files is described fully in
  2523.  your MS-DOS manual. This chapter provides a brief description of command
  2524.  files in the context of compiling, linking, and running an MS-Pascal
  2525.  program.
  2526.  
  2527.  A batch command file is a text file of lines that are MS-DOS commands. If a
  2528.  batch file is open when MS-DOS is ready to process a command, the next line
  2529.  in the file becomes the command line. After processing all batch command
  2530.  lines (or if batch processing is otherwise terminated), MS-DOS goes back to
  2531.  reading command lines from the screen.
  2532.  
  2533.  Batch file lines cannot be read by the compiler, the linker, or a user
  2534.  program. Thus, you cannot put responses to filename prompts, $inconst
  2535.  values, or the like in a batch file. All compiler parameters must be given
  2536.  on the command line, as described in Section 5.3.2, "Giving All Parameters
  2537.  on the Command Line."
  2538.  
  2539.  The batch file may contain dummy parameters that you replace with actual
  2540.  parameters when you invoke it. The symbol %1 refers to the first parameter
  2541.  on the line, %2 to the second parameter, and so on. The limit is %9. A
  2542.  batch command file must have the extension .BAT and should be kept on
  2543.  either the program disk or the utility disk.
  2544.  
  2545.  The PAUSE command, followed by the text of the prompt, tells the operating
  2546.  system to pause, display a prompt (which you have defined), and wait for
  2547.  some further input before continuing.
  2548.  
  2549.  If your program is already debugged and you are making only minor changes
  2550.  to it, you can speed up the compilation process by creating a batch file
  2551.  that issues the compile, link, and run commands.
  2552.  
  2553.  For example, use the line editor in MS-DOS to create the following batch
  2554.  file, COLIGO.BAT:
  2555.  
  2556.       A:PAS1 %1,,;
  2557.       PAUSE ...If no errors, insert PAS2 disk in drive A:
  2558.       A:PAS2
  2559.       PAUSE ...Insert runtime libraries disk in drive A:
  2560.       A:LINK %1;
  2561.       %1
  2562.  
  2563.  To execute this file, type:
  2564.  
  2565.       COLIGO SORT
  2566.  
  2567.  SORT is the name of the source program you want to compile, link, and run.
  2568.  
  2569.     1.  The first line of the batch file runs pass one of the compiler.
  2570.  
  2571.     2.  The second line generates a pause and prompts you to insert the pass
  2572.         two disk.
  2573.  
  2574.     3.  The third line runs pass two.
  2575.  
  2576.     4.  The fourth line generates a pause and prompts you to insert the
  2577.         runtime library.
  2578.  
  2579.     5.  The fifth line links the object file.
  2580.  
  2581.     6.  The sixth line runs the executable file.
  2582.  
  2583.  A BAT file is only executed if there is neither a COM file or EXE file with
  2584.  the same name. Thus, if you keep your source file and BAT file on the same
  2585.  disk, they should have different filenames.
  2586.  
  2587.  For more information about batch command files, see your MS-DOS
  2588.  manual.
  2589.  
  2590.  
  2591.  
  2592.  Chapter 8  Compiling and Linking Large Programs
  2593.  
  2594.  ───────────────────────────────────────────────────────────────────────────
  2595.  
  2596.  8.1  Avoiding Limits on Code Size
  2597.  
  2598.  8.2  Avoiding Limits on Data Size
  2599.  
  2600.        8.2.1  Long Heap Allocation
  2601.  
  2602.        8.2.2  Allocating Dynamic Arrays on the Long Heap
  2603.  
  2604.  8.3     Working With Limits on Compile Time Memory
  2605.  
  2606.        8.3.1  Identifiers
  2607.  
  2608.        8.3.2  Complex Expressions
  2609.  
  2610.  8.4     Working With Limits on Disk Memory
  2611.  
  2612.        8.4.1  Pass One
  2613.  
  2614.        8.4.2  Pass Two
  2615.  
  2616.        8.4.3  Linking
  2617.  
  2618.        8.4.4  A Complex Example
  2619.  
  2620.  8.5     Minimizing Load Module Size
  2621.  
  2622.        8.5.1  I/O
  2623.  
  2624.        8.5.2  Runtime Error Handling
  2625.  
  2626.        8.5.3  Error Checking
  2627.  
  2628.  
  2629.  
  2630.  Occasionally, you may find that a large program exceeds one or more
  2631.  physical limits on the size of program the compiler, the linker, or your
  2632.  machine can handle. This chapter describes some ways to avoid or work
  2633.  within such limits.
  2634.  
  2635.  
  2636.  8.1  Avoiding Limits on Code Size
  2637.  
  2638.  The upper limit on the size of code that can be generated at once by the
  2639.  MS-Pascal Compiler is 64K bytes. However, since you can compile any number
  2640.  of compilands separately and link them together later, the real program
  2641.  size limit is not 64K but the amount of memory available.
  2642.  
  2643.  For example, you can separately compile six different compilands of 50K
  2644.  bytes each. Linking them together produces a program with a total of 300K
  2645.  bytes of code.
  2646.  
  2647.  In practice, a source file large enough to generate 64K bytes of code would
  2648.  be thousands of lines long, and unwieldy both to edit and to maintain. A
  2649.  better practice is to break a large program into MS-Pascal modules and
  2650.  units to better structure the development and maintenance process. As
  2651.  always, there is a tradeoff between size and speed. Procedure and function
  2652.  calls within a module to routines without the PUBLIC attribute are somewhat
  2653.  faster, since intrasegment calls, which run faster, are generated rather
  2654.  than intersegment calls.
  2655.  
  2656.  Finally, if your program is still too big, you should consider devising an
  2657.  overlaying scheme. See Section 6.3, "The Overlay Linker," for details.
  2658.  
  2659.  
  2660.  8.2  Avoiding Limits on Data Size
  2661.  
  2662.  Data includes your main variables, the stack, and the heap. MS-Pascal
  2663.  operates with data in two regions of memory:
  2664.  
  2665.     1.  the default data segment
  2666.  
  2667.     2.  the segmented data space
  2668.  
  2669.  The upper limit on the amount of data that can reside in the default data
  2670.  segment is also 64K bytes. You can go beyond this limit by taking
  2671.  advantage of the ability to place certain kinds of data outside the default
  2672.  data segment, using ADS variables, the long heap allocator (HESM), VARS and
  2673.  CONSTS parameters, and segmented ORIGIN variables.
  2674.  
  2675.  The default data segment normally holds the following:
  2676.  
  2677.     1.  all statically allocated variables
  2678.  
  2679.     2.  constants that reside in memory
  2680.  
  2681.     3.  heap variables
  2682.  
  2683.     4.  the stack, which holds parameters, return addresses, stack
  2684.         variables, etc.
  2685.  
  2686.  The segmented data space includes the entire 8086 address space, including
  2687.  the default data segment. See the appropriate chapters in the Microsoft
  2688.  Pascal Reference Manual for a discussion of these MS-Pascal features.
  2689.  
  2690.  Although operations with data in the default data segment are more
  2691.  efficient (i.e., generate less code and run faster) than those with data
  2692.  that may be in any other segment, almost all MS-Pascal operations work
  2693.  equally well on data outside the default data segment. Only in the
  2694.  following cases must data reside in the default data segment:
  2695.  
  2696.     1.  file variables
  2697.  
  2698.     2.  the LSTRING parameters to ENCODE and DECODE
  2699.  
  2700.     3.  all parameters to READSET
  2701.  
  2702.  To allocate data outside the default data segment, you can use the long
  2703.  heap allocator which works in a similar way to NEW and DISPOSE. If you wish
  2704.  to make static allocation of data outside of the default data segment, you
  2705.  must go outside the MS-Pascal system itself. If you already know the
  2706.  address of free blocks of memory on your computer, you can use these
  2707.  addresses in a segmented ORIGIN attribute or assign them to an ADS
  2708.  variable. Otherwise, you can get the addresses of free memory from MS-DOS,
  2709.  using a process (described in item 4 in Section B.1, "Implementation
  2710.  Additions") to get a pair of ADS variables to the lower and upper bounds of
  2711.  available memory.
  2712.  
  2713.  Many applications use a large block of memory for primary data, as well as
  2714.  various other variables to control access and processing of this data. For
  2715.  example, a text editor will have a work area; a data base system will have
  2716.  a data area (or index area); and so on. This large block can be managed
  2717.  outside the default data segment with ADS variables.
  2718.  
  2719.  In the default data segment, the heap and the stack grow toward each other.
  2720.  Heap allocation will attempt to use existing disposed blocks in the heap
  2721.  itself, before growing into memory shared with the stack. As a part of
  2722.  this process, adjacent disposed blocks are merged, and free blocks at the
  2723.  end of the heap become available to the stack.
  2724.  
  2725.  However, only heap allocation (i.e., NEW or GETHQQ) releases free heap
  2726.  blocks to the stack. Therefore, if you are running out of stack after a
  2727.  number of DISPOSE operations, make the following call:
  2728.  
  2729.  EVAL (GETHQQ (65534));
  2730.  
  2731.  ALLHQQ should be declared as an external function, like this:
  2732.  
  2733.  FUNCTION ALLHQQ (SIZE:WORD); WORD; EXTERN
  2734.  
  2735.  
  2736.  8.2.1  Long Heap Allocation
  2737.  
  2738.  A "long" heap module, HESM (segmented addresses), has been provided with
  2739.  this release of Pascal. The module assumes that all memory from the top of
  2740.  DGROUP to the bottom of MS-DOS is available to the long heap allocator.
  2741.  
  2742.  Four library procedures (system extensions) have been provided that allow
  2743.  the user to access segmented memory beyond the default DGROUP data segment
  2744.  ASSUMED by the MS-Pascal runtime. The routines assume that all memory
  2745.  beyond DGROUP has been allocated to the user by the MS-DOS loader.
  2746.  Requests to the ALLMQQ and GETMQQ routines may be up to 64K.
  2747.  
  2748.  You can use one of the following four routines to allocate and free up to
  2749.  64K bytes of memory at a time. The amount of memory actually reserved is
  2750.  always a unit number of 16-byte paragraphs. These routines are at the
  2751.  system level of extension.
  2752.  
  2753.         {Allocate block of "wants" bytes.}
  2754.         FUNCTION  ALLMQQ (wants: word): adsmem;
  2755.  
  2756.         {Free a block. No error handling.}
  2757.         FUNCTION  FREMQQ (block: adsmem): word;
  2758.  
  2759.         {Call ALLMQQ, check for error returns.}
  2760.         FUNCTION GETMQQ (wants: word): adsmem;
  2761.  
  2762.         {Call FREMQQ, check for error returns.}
  2763.         PROCEDURE DISMQQ (block: adsmem);
  2764.  
  2765.  Procedure ALLMQQ allocates segmented memory blocks. (No single block may
  2766.  be greater than 64K bytes.) Function FREMQQ frees a segmented block of
  2767.  memory; returns 0 if no errors encountered, nonzero otherwise. Function
  2768.  GETMQQ performs an ALLMQQ with error checking. Procedure DISMQQ performs a
  2769.  FREMQQ with error checking.
  2770.  
  2771.  If the space above DGROUP is exhausted using ALLMQQ, blocks of memory are
  2772.  allocated by ALLMQQ from the "small" unsegmented heap between the end of
  2773.  program space and the user stack. Thus, ALLMQQ can utilize all of the
  2774.  available user memory on 8086 based machines.
  2775.  
  2776.  In the above routines, the parameter "wants" is the size in bytes of the
  2777.  desired memory request and the parameter "block" is a segmented address.
  2778.  ALLMQQ(w).r will be (0) if a block of the correct size cannot be found and
  2779.  (1) if the segmented address space has been corrupted.
  2780.  
  2781.  Unlike allocating with NEW, the compiler cannot check that sufficient bytes
  2782.  are allocated to contain the variable you are going to reference. This is
  2783.  the responsibility of your program.
  2784.  
  2785.  For variables of fixed size including variant records, you can use the
  2786.  SIZEOF function. You must use ADS variables to reference the allocated
  2787.  variable, so be careful when you assign one ADS variable to another, since
  2788.  there is no type checking on such assignments.
  2789.  
  2790.  This means that you could accidently retype the variable to one that is
  2791.  longer than the space allocated. If you reference parts of the variable for
  2792.  which no memory is assigned, you will get unpredictable results. If you
  2793.  assign to those same parts, you may get serious and, occasionally,
  2794.  catastrophic errors.
  2795.  
  2796.  
  2797.  8.2.2  Allocating Dynamic Arrays on the Long Heap
  2798.  
  2799.  While you can use SIZEOF and appropriately typed variables (with care) to
  2800.  reference fixed size variables correctly, SIZEOF is less effective if you
  2801.  want to allocate arrays whose bounds are to be fixed at runtime. (Unlike
  2802.  NEW, you cannot use a pointer to supertype, since pointers cannot reference
  2803.  the long heap.)
  2804.  
  2805.  However, you can achieve the effect of "dynamic" bounds by declaring your
  2806.  address type as if it referenced an array with fixed bounds greater than
  2807.  the maximum you would have allocated if you were using NEW.
  2808.  
  2809.  In any particular instance, you allocate memory only for the array elements
  2810.  you require for that instance. To be safe (at least when you are developing
  2811.  your program), you should explicitly check index values against the value
  2812.  you used to allocate the array before using them to reference the array.
  2813.  
  2814.  The following example illustrates how to use the long heap allocator and
  2815.  includes an appropriate test on the index.
  2816.  
  2817.         PROGRAM LONGALLOCATION;
  2818.  
  2819.         CONST
  2820.           MAXINDEX = 4000;
  2821.  
  2822.         TYPE
  2823.           MAXARRAY = ARRAY [1 .. MAXINDEX] OF RECORD
  2824.                                i: integer;
  2825.                                j: real;
  2826.                              END;
  2827.           ADSARRAY = ADS OF MAXARRAY;
  2828.           REKORD = RECORD
  2829.               CASE INTEGER OF
  2830.               0: ();
  2831.               1: (b: byte);
  2832.               2: (i4: integer4)
  2833.               END;
  2834.           ADSREKORD = ADS OF REKORD;
  2835.  
  2836.         VAR
  2837.           w: word;
  2838.           r: rekord;
  2839.           rp: adsrekord;
  2840.           ap: adsarray;
  2841.  
  2842.         {Allocate a block of "wants" bytes}
  2843.         FUNCTION ALLMQQ (wants: word): adsmem; extern;
  2844.  
  2845.         {Free a previously allocated block (no error handling)}
  2846.         FUNCTION FREMQQ (block: adsmem): word; extern;
  2847.  
  2848.         {Call ALLMQQ, and check for error returns}
  2849.         FUNCTION GETMQQ (wants: word): adsmem; extern;
  2850.  
  2851.         {Call FREMQQ, and check for error returns}
  2852.         PROCEDURE DISMQQ (block: adsmem); extern;
  2853.  
  2854.         PROCEDURE P (U: INTEGER);
  2855.         BEGIN
  2856.           W := 20;
  2857.           AP := ALLMQQ (SIZEOF (AP^ [1]) * W);
  2858.           {You must not use an index greater than w}
  2859.           RP := ALLMQQ (SIZEOF (R, 2));
  2860.           IF U > ORD(W) THEN ABORT
  2861.                ('ARRAY BOUND EXCEEDED',WRD(U),W);
  2862.           AP^ [U].I := 5;
  2863.           {...}
  2864.           {...}
  2865.           DISMQQ (AP);
  2866.           DISMQQ (RP)
  2867.         END;
  2868.         BEGIN
  2869.         p(9);
  2870.         END.
  2871.  
  2872.  
  2873.  8.3  Working With Limits on Compile Time Memory
  2874.  
  2875.  During compilation, large programs are most often limited in the number of
  2876.  identifiers in any one source file. They are occasionally limited by the
  2877.  complexity of the program itself. If one of these limits is reached, you
  2878.  will see the following error message:
  2879.  
  2880.       Compiler Out Of Memory
  2881.  
  2882.  There is no particular limit on number of bytes in a source file. The
  2883.  number of lines is limited to 32767, but in practice, any source file this
  2884.  big will run into other limits first.
  2885.  
  2886.  
  2887.  8.3.1  Identifiers
  2888.  
  2889.  Pass one of the compiler can handle a maximum of about a thousand
  2890.  identifiers visible at any one time. This assumes a 64K default data
  2891.  segment (i.e., about 160K of memory total); it also assumes that most of
  2892.  your identifiers are seven characters or shorter and are not PUBLIC or
  2893.  EXTERN.
  2894.  
  2895.  Once a procedure or function is compiled, its local identifiers can be
  2896.  released to provide room for new ones. Several methods of reducing the
  2897.  number of identifiers in a program are described in the following
  2898.  paragraphs.
  2899.  
  2900.     1.  Break your program into modules or units.
  2901.  
  2902.         The best way to reduce the number of identifiers is to break up your
  2903.         program into modules or units. When dividing your application into
  2904.         pieces, one guiding principle is to minimize the number of shared
  2905.         (i.e., PUBLIC and EXTERN) identifiers. This not only is good
  2906.         programming practice, it makes compilation easier.
  2907.  
  2908.         Breaking up a program may force you to choose between a shared
  2909.         variable and a shared procedure or function. Usually a shared
  2910.         procedure or function is "cleaner;" it is easier to trace the use of
  2911.         a procedure than the use of a variable, for example. However, a
  2912.         shared variable is usually more efficient in terms of memory
  2913.         required and number of identifiers used.
  2914.  
  2915.     2.  Simplify your identifiers.
  2916.  
  2917.         Although it reduces the readability of a program (since naming
  2918.         something is a more readable way of referring to it than giving an
  2919.         arbitrary number), you may simplify your identifiers by replacing
  2920.         names with numbers. If necessary, any of the following may help:
  2921.  
  2922.         a. Change enumerated types into WORD types and use numbers instead
  2923.            of identifiers.
  2924.  
  2925.         b. Use constant literals instead of constant identifiers.
  2926.  
  2927.         c. Combine related procedures and functions into single ones, with a
  2928.            parameter indicating the type of call.
  2929.  
  2930.         d. Combine variables into an array and refer to the variables using
  2931.            constant array indices.
  2932.  
  2933.  A special caution is required regarding interfaces. When an interface USES
  2934.  another interface, it must import all identifiers in the other interface.
  2935.  To do this, the other interface must have been declared, so now its
  2936.  identifiers occur twice. If a third interface USES both of the first two,
  2937.  the first interface's identifiers occur three times and the second
  2938.  interface's identifiers occur twice, and so on. This is an easy way to run
  2939.  out of identifiers!
  2940.  
  2941.  The only reason an interface needs to USE another interface is to import
  2942.  identifiers for types; an interface has no use for variables, procedures,
  2943.  and functions. You can declare a single interface with global types; this
  2944.  is the only interface used by other interfaces. Once compilation gets past
  2945.  the USES clause in the PROGRAM, MODULE, or IMPLEMENTATION, many of these
  2946.  "extra" identifiers are removed.
  2947.  
  2948.  
  2949.  8.3.2  Complex Expressions
  2950.  
  2951.  It is also possible to run out of memory in pass one with any of the
  2952.  following:
  2953.  
  2954.     1.  a very complex statement or expression (i.e., one that is very
  2955.         deeply nested)
  2956.  
  2957.     2.  a large number of error messages
  2958.  
  2959.     3.  a large number of structured constants, including string constants
  2960.  
  2961.  You may be able to change literal strings and other structured constants
  2962.  into EXTERN READONLY variables which get initialized (as PUBLIC variables)
  2963.  in another module.
  2964.  
  2965.  Usually, if a program gets through pass one without running out of memory,
  2966.  it will get through pass two. The major exception occurs with complex
  2967.  basic blocks, as in either of the following:
  2968.  
  2969.     1.  sequences of statements with no labels or other breaks
  2970.  
  2971.     2.  sequences of statements containing very long expressions or
  2972.         parameter lists (especially a WRITE or WRITELN procedure call with
  2973.         many expressions)
  2974.  
  2975.  If pass two runs out of memory, it displays the following message:
  2976.  
  2977.       Compiler Out Of Memory
  2978.  
  2979.  The error message will give a line number reference. If there is a
  2980.  particularly long expression or parameter list near this line, break it up
  2981.  by assigning parts of the expression to local variables (or using multiple
  2982.  WRITE calls). If this does not work, add labels to statements to break the
  2983.  basic block.
  2984.  
  2985.  
  2986.  8.4  Working with Limits on Disk Memory
  2987.  
  2988.  Another type of limit you may encounter is in the number of disk drives on
  2989.  your computer or the maximum file size on one disk. As with other limits,
  2990.  there are several possible solutions.
  2991.  
  2992.  The simplest method of avoiding these limits is to first load a compiler
  2993.  pass, then switch disks and run the pass.
  2994.  
  2995.  
  2996.  8.4.1  Pass One
  2997.  
  2998.  For PAS1.EXE, just type PAS1 (or dev:PAS1, if necessary) to load pass one.
  2999.  When the "Source File" prompt appears, you can remove the disk containing
  3000.  PAS1.EXE. If you have a single-drive system, replace the system disk with
  3001.  the disk containing your source file. PAS1 will write its intermediate
  3002.  files on the same disk.
  3003.  
  3004.  If you have a two-drive system, insert your source file in the nondefault
  3005.  drive. Since the intermediate files are always written to the default
  3006.  drive, you will need to give an explicit device (i.e., drive) letter for
  3007.  your source file. Typically, a source listing file would go on the same
  3008.  drive as the source.
  3009.  
  3010.  If your source file will not fit on one disk, you can break it into pieces
  3011.  and use the $include metacommand to compile the pieces as a group. One way
  3012.  to do this is to create a master file with lines such as:
  3013.  
  3014.       {$message:`insert B:P1.PAS'
  3015.           $inconst:P1 $include:`B:P1.PAS'}
  3016.       {$message:`insert B:P2.PAS'
  3017.           $inconst:P2 $include:`B:P2.PAS'}
  3018.       {$message:`insert B:P3.PAS'
  3019.           $inconst:P3 $include:'B:P3.PAS'}
  3020.  
  3021.  The $inconst metacommand makes the compiler pause while you switch disks.
  3022.  These $include metacommands can also be simply typed at your screen. Just
  3023.  give USER as the name of your source file, and type your $include
  3024.  metacommands directly, one per line. You will need to type CONTROL-Z (end-
  3025.  of-file) to end the compilation.
  3026.  
  3027.  If your source file doesn't fit on one disk, your source listing file will
  3028.  not fit either, so you will need to send it directly to the printer. If
  3029.  you think you could get a listing file on the disk, except that the source
  3030.  and intermediate (PASIBF) files take up too much room, include a line like
  3031.  the following near the start of your source file:
  3032.  
  3033.        {$inconst:ZERROR}  CONST ERROR = 1 DIV ZERROR;
  3034.  
  3035.  If you respond with 0 to the "Inconst ZERROR" prompt, you will get a
  3036.  compiler error. The compiler error stops the writing of the intermediate
  3037.  files, which will leave room on the disk for your listing. However, then
  3038.  you will have to run the front end twice, once to generate intermediate
  3039.  files for pass two and once for the listing.
  3040.  
  3041.  Another way to control a large listing file is use of the $list
  3042.  metacommand. Turn off generation of listing code with the $list-
  3043.  metacommand, and then use the pair of metacommands, $list+ and $list-, to
  3044.  bracket only those portions of the program for which you want a source
  3045.  listing.
  3046.  
  3047.  
  3048.  8.4.2  Pass Two
  3049.  
  3050.  Two command line parameters available with pass two can help you with disk
  3051.  limitations.
  3052.  
  3053.     1.  You can indicate a drive letter on which your input intermediate
  3054.         files, PASIBF.SYM and PASIBF.BIN, can be found.
  3055.  
  3056.     2.  The /PAUSE switch tells pass two to pause while you remove the disk
  3057.         containing PAS2.EXE and insert some other disk.
  3058.  
  3059.  For example, if you have a single-drive system, insert your PAS2.EXE disk
  3060.  and type PAS2 /PAUSE. After PAS2.EXE is loaded, you will see the message:
  3061.  
  3062.       Press <ENTER> or <RETURN> to begin pass two.
  3063.  
  3064.  Take out the PAS2.EXE disk and insert the disk with the intermediate file
  3065.  from pass one. Now press ENTER or RETURN and pass two will run.
  3066.  
  3067.  If you have two drives, but you run out of disk memory when executing pass
  3068.  two, you need to have the input intermediate files PASIBF.SYM and
  3069.  PASIBF.BIN on one drive and PASIBF.TMP on the other drive (also PASIBF.OID
  3070.  if you are making an object listing file).
  3071.  
  3072.  The PASIBF.TMP file (and the PASIBF.OID file used in pass three) are always
  3073.  written to the default drive.
  3074.  
  3075.  Give pass two a drive letter to specify the drive containing the PASIBF.SYM
  3076.  and PASIBF.BIN files; for example, PAS2 B. Normally you will also need the
  3077.  pause command; for example, PAS2 B/PAUSE. Pass two will respond with a
  3078.  message like the following:
  3079.  
  3080.       PASIBF.SYM and PASIBF.BIN are on B:
  3081.  
  3082.  This message is followed by the pause prompt:
  3083.  
  3084.       Press <ENTER> key to begin pass two
  3085.  
  3086.  When you run pass two with the PASIBF files on two disks, the object file
  3087.  should usually go on the same disk as PASIBF.TMP (and PASIBF.OID); that is,
  3088.  in the default drive. If it doesn't quite fit, and you are making an
  3089.  object listing file, you could compile your program twice, once without the
  3090.  object listing but with the object file itself, and once with an object
  3091.  listing but with NUL used for the object file.
  3092.  
  3093.  
  3094.  8.4.3  Linking
  3095.  
  3096.  If you are making a large program with small disks (or only one disk
  3097.  drive), you may run into similar problems when you link your program.
  3098.  Since you can split your program into pieces and compile them separately,
  3099.  but you must link the entire program at one time, you may run into disk
  3100.  limitations in the linker but not the compiler.
  3101.  
  3102.  The linker will prompt you for any object files and/or libraries it cannot
  3103.  find, so you can swap in the correct disk and continue linking. Also, the
  3104.  /PAUSE switch makes the linker wait after linking but before writing the
  3105.  run (EXE) file, so you can create a run file that fills an entire disk.
  3106.  However, creation of the virtual file VM.TMP and the link map limit the
  3107.  amount of disk swapping you can do.
  3108.  
  3109.  On a single-drive system:
  3110.  
  3111.     1.  Load the linker by typing LINK.
  3112.  
  3113.     2.  Remove the disk containing LINK.EXE and insert the disk containing
  3114.         your object file(s) and, if there is room, any libraries.
  3115.  
  3116.     3.  Respond normally to the linker prompts, except to include the /PAUSE
  3117.         switch with the run file if you want the run file on another disk.
  3118.  
  3119.  Unless all object files, libraries, and the run file will fit on one disk,
  3120.  you must not write the linker listing to a disk file. Instead, send the
  3121.  linker map to NUL, CON, or directly to your printer. Since the map is
  3122.  written at various points in the linking process, you cannot swap the disk
  3123.  on which the map is written.
  3124.  
  3125.  The linker will prompt you when it needs an object file, a library file, or
  3126.  is about to write the run file; exchange disks as necessary when this
  3127.  happens. If the linker gives a message that it is creating VM.TMP, its
  3128.  virtual memory file, you cannot switch disks anymore, so you may not be
  3129.  able to link without more memory or a second disk drive.
  3130.  
  3131.  With two disk drives, you can devote one drive (the default) to the VM.TMP
  3132.  file (and to the linker map, if you want one). Use the other drive for
  3133.  your object files, libraries, and run file (using the /PAUSE switch). With
  3134.  this method, you can link very large programs.
  3135.  
  3136.  The linker makes two passes through the object files and libraries: one to
  3137.  build a symbol table and allocate memory, and one to actually build the run
  3138.  file. This means you will insert a disk containing object files or
  3139.  libraries twice, and finally insert the disk that will receive your run
  3140.  file.
  3141.  
  3142.  
  3143.  8.4.4  A Complex Example
  3144.  
  3145.  The following example illustrates compiling and linking a very large
  3146.  program. The example assumes that the machine has two drives and that the
  3147.  programmer doesn't want any of the listing files.
  3148.  
  3149.  Pass one
  3150.  
  3151.     1.  Log onto drive B:.
  3152.  
  3153.     2.  Insert the disk containing PAS1.EXE in drive A:, type A:PAS1, and
  3154.         wait for the "Source File" prompt.
  3155.  
  3156.     3.  Remove the disk containing PAS1.EXE from drive A: and insert the
  3157.         disk containing the source file, LARGE.PAS.
  3158.  
  3159.     4.  Respond to the "Source File" prompt with A:LARGE,A:LARGE, and
  3160.         wait for pass one to run.
  3161.  
  3162.  Pass two
  3163.  
  3164.     1.  Log onto drive A:. Remove the source disk from A:.
  3165.  
  3166.     2.  Insert the disk containing PAS2.EXE in A:, type PAS2 B/PAUSE and
  3167.         wait for the pass two prompt.
  3168.  
  3169.     3.  Remove the disk containing PAS2.EXE from A:. Insert an empty disk
  3170.         (to which the object file will be written).
  3171.  
  3172.     4.  Respond to the pass two prompt by pressing the RETURN key and wait
  3173.         for pass two to run.
  3174.  
  3175.     5.  Remove the disk containing the object file from A:.
  3176.  
  3177.  Linking
  3178.  
  3179.     1.  Log onto drive B: (which contains a now-empty disk).
  3180.  
  3181.     2.  Insert LINK.EXE in A:; type A:LINK and wait for the "Object Modules"
  3182.         prompt.
  3183.  
  3184.     3.  Remove the disk containing LINK.EXE from A: and insert the disk
  3185.         containing the object file(s).
  3186.  
  3187.     4.  Respond to the "Object Modules" prompt by typing A:LARGE (plus any
  3188.         other object files).
  3189.  
  3190.     5.  Respond to the "Run File" prompt by typing LARGE/PAUSE.
  3191.  
  3192.     6.  Respond to the "List File" prompt by pressing the RETURN key, or
  3193.         type B:LARGE to get a linker map.
  3194.  
  3195.     7.  Respond to the "Libraries" prompt by pressing the RETURN key or with
  3196.         a library name (the library must be on A:).
  3197.  
  3198.     8.  Wait for linker to run, swapping the A: disk after prompts as
  3199.         necessary.
  3200.  
  3201.  
  3202.  8.5  Minimizing Load Module Size
  3203.  
  3204.  Some MS-Pascal load modules can be reduced in size by eliminating runtime
  3205.  modules your program doesn't use. Reductions can be made in several areas:
  3206.  
  3207.     1.  I/O
  3208.  
  3209.     2.  runtime error handling
  3210.  
  3211.     3.  error checking
  3212.  
  3213.  
  3214.  8.5.1  I/O
  3215.  
  3216.  Because most MS-Pascal programs perform I/O, they require linking to the
  3217.  MS-Pascal file system in the runtime library. However, some programs do not
  3218.  perform I/O and others perform I/O by directly calling the MS-Pascal Unit U
  3219.  file routines or calling operating system I/O routines. For more
  3220.  information on Unit U, see Section 10.2, "An Overview of the File
  3221.  System."
  3222.  
  3223.  Nonetheless, all programs include calls to INIFQQ and ENDYQQ, the
  3224.  procedures that initialize and terminate the file system. These calls
  3225.  increase the size of the load module by linking and loading routines that
  3226.  may never be used.
  3227.  
  3228.  If a program doesn't need the file system routines, you can eliminate
  3229.  unnecessary file support by declaring dummy INIFQQ and ENDYQQ subroutines
  3230.  in your program, as follows:
  3231.  
  3232.       PROCEDURE INIFQQ [PUBLIC];
  3233.       BEGIN
  3234.       END;
  3235.  
  3236.       PROCEDURE ENDYQQ [PUBLIC];
  3237.       BEGIN
  3238.       END;
  3239.  
  3240.  The linker will still load the Unit U procedures necessary to access the
  3241.  terminal (INIUQQ, ENDUQQ, PTYUQQ, PLYUQQ, and GTYUQQ), so that the runtime
  3242.  system can write any runtime error messages.
  3243.  
  3244.  However, if you do include the dummy procedures shown and the linker
  3245.  produces any error messages for global names that end with the "FQQ" or
  3246.  "UQQ" suffix, your program requires the file system and the process
  3247.  described above will not work. The most common ones would be NEWFQQ, the
  3248.  file variable initializer, and BUFFQQ, the lazy evaluation evaluator.
  3249.  
  3250.  On the other hand, if your program doesn't require the I/O-handling
  3251.  procedures called by Unit U, you can use the dummy file NULF.OBJ instead.
  3252.  NULF.OBJ contains the dummy subroutines for INIFQQ and ENDYQQ, as well as
  3253.  dummies for INIUQQ and ENDUQQ.
  3254.  
  3255.  
  3256.  8.5.2  Runtime Error Handling
  3257.  
  3258.  If runtime error handling is not required, the load module can be further
  3259.  reduced in size by eliminating the error message module and replacing it
  3260.  with the null object module, NULE6.OBJ. NULE6.OBJ provides for simple
  3261.  termination of a program if an error occurs.
  3262.  
  3263.  INUXQQ, the unit initialization helper, also resides in the error unit. If
  3264.  you want to replace error handling with NULE6, you must do any unit
  3265.  initialization yourself and remove the keyword BEGIN from all the
  3266.  interfaces in your source program.
  3267.  
  3268.  
  3269.  8.5.3  Error Checking
  3270.  
  3271.  Compiling and linking a program with the error-checking switches or
  3272.  metacommands on may generate up to 40 percent more code (or even more with
  3273.  $line+) than with these switches or metacommands off. Therefore, after a
  3274.  program has been successfully compiled, linked, and run, turn the error-
  3275.  checking switches off and do the entire process again to create a program
  3276.  that will run considerably faster.
  3277.  
  3278.  
  3279.  
  3280.  Chapter 9  Using Assembly Language Routines
  3281.  
  3282.  ───────────────────────────────────────────────────────────────────────────
  3283.  
  3284.  9.1  Calling Conventions
  3285.  
  3286.  9.2  Internal Representations of Data Types
  3287.  
  3288.  9.3  Interfacing to Assembly Language Routines
  3289.  
  3290.  
  3291.  
  3292.  After describing the MS-Pascal calling conventions and internal
  3293.  representations of data types, this chapter shows how to interface 8086
  3294.  assembly language routines to MS-Pascal compilands. The information in this
  3295.  chapter is not required for most MS-Pascal programs and is intended
  3296.  primarily for the advanced programmer who is familiar with the following
  3297.  material:
  3298.  
  3299.     1.  The EXTERN directive. (See Chapter 14, "Introduction to Procedures
  3300.         and Functions," of the Microsoft Pascal Reference Manual.)
  3301.  
  3302.     2.  Procedure and function parameters. (See Chapter 14, "Introduction to
  3303.         Procedures and Functions," of the Microsoft Pascal Reference
  3304.         Manual.)
  3305.  
  3306.     3.  MS-Macro Assembler. See your MS-DOS manual.
  3307.  
  3308.  
  3309.  9.1  Calling Conventions
  3310.  
  3311.  At runtime, each active procedure or function has a "frame" allocated on
  3312.  the stack. The frame contains the data shown in Figure 9.1.
  3313.  
  3314.  
  3315.                   ┌─────────────────────────────────────┐
  3316.                   │ Parameters                          │
  3317.                   ├─────────────────────────────────────┤
  3318.                   │ Two-byte address of long            │
  3319.                   │ function return value,if any        │
  3320.                   ├──────────────────────┬──────────────┤
  3321.                   │ Upper framepointer,  │ Four-byte    │
  3322.                   │ if any. Two-byte     │ return       │
  3323.                   │ return address1     │ address2    │
  3324.                   ├──────────────────────┴──────────────┤
  3325.  Frame pointer───│ Saved caller framepointer           │
  3326.                   ├─────────────────────────────────────┤
  3327.                   │ Short function return value, if any │
  3328.                   ├─────────────────────────────────────┤
  3329.                   │ Local data and temporaries          │
  3330.                   └─────────────────────────────────────┘
  3331.  
  3332.                   Figure 9.1.  Contents of the Frame
  3333.  
  3334.  
  3335.  The framepointer points at the saved caller framepointer, below the return
  3336.  address, and is used to access frame data. A procedure or function nested
  3337.  within another procedure or function has an upper framepointer, so it can
  3338.  access variables in the statically enclosing frame.
  3339.  
  3340.  The following takes place during a procedure or function call:
  3341.  
  3342.     1.  The caller saves any registers it needs (except the framepointer).
  3343.  
  3344.     2.  The caller pushes parameters in the same order as they are declared
  3345.         in the source and then performs the call.
  3346.  
  3347.     3.  The called routine pushes the old framepointer, sets up its new
  3348.         framepointer, and allocates any other stack locations needed. It
  3349.         also checks for adequate stack space if $stackck was on.
  3350.  
  3351.  To return to the calling routine, the called routine restores the caller's
  3352.  framepointer, releases the entire frame (including parameters), and
  3353.  returns. Not all of these steps need necessarily be taken in an assembly
  3354.  language routine. You must only ensure that the framepointer is not
  3355.  modified and that the entire frame, including all parameters, is popped off
  3356.  the stack before returning. For information on the assembly language
  3357.  interface, see Section 9.3, "Interfacing to Assembly Language Routines."
  3358.  
  3359.  The standard entry and exit sequences (with $stackck-) are as
  3360.  follows:
  3361.  
  3362.       PUSH    BP
  3363.       MOV     BP,SP
  3364.       {body of routine}
  3365.       MOV     SP,BP
  3366.       POP     BP
  3367.       RET     PARAMETERSIZE
  3368.  
  3369.  A function always returns its value in registers. For real types,
  3370.  structured types, and pointers to super arrays, regardless of length, the
  3371.  caller allocates a temporary frame for the result and passes the offset
  3372.  address to the function like a parameter. When the called routine returns,
  3373.  it places the address back in the normal return register (AX).
  3374.  
  3375.  8086 and 8088 microprocessors perform a long call if the called routine is
  3376.  PUBLIC or EXTERN. In all other cases, they perform a short call.
  3377.  
  3378.  The called routine must save the BP register, which contains the MS-Pascal
  3379.  framepointer, as well as save the DS segment register. The SS register is
  3380.  used by interrupt routines, both user-declared and 8087 support, to locate
  3381.  the default data segment, and so must not be changed (at least, if
  3382.  interrupts are enabled). Other registers (FLAGS, AX, BX, CX, DX, SI, DI,
  3383.  and ES) need not be saved.
  3384.  
  3385.  Functions return a one-byte value in AL, a two-byte value in AX, and
  3386.  a four-byte value in DX:AX (high part:low part, or segment:offset).
  3387.  
  3388.  
  3389.  9.2  Internal Representations of Data Types
  3390.  
  3391.  This section describes the internal representation of MS-Pascal data types.
  3392.  Programmers who use both MS-Pascal and MS-FORTRAN should pay particular
  3393.  attention to the data type and parameter passing differences when passing
  3394.  data between the two languages. For internal representations of MS-FORTRAN
  3395.  data types, see the Microsoft FORTRAN Compiler User's Guide.
  3396.  
  3397.     1.  INTEGER and WORD
  3398.  
  3399.         INTEGER values are 16-bit two's complement numbers, but a subrange
  3400.         requiring 8 bits or less (i.e., in the range -127 through 127) is
  3401.         allocated an 8-bit byte. WORD values are 16-bit unsigned numbers,
  3402.         but a WORD subrange in the range 0 through 255 is allocated an 8-bit
  3403.         byte. For 16-bit INTEGER and WORD values, the least significant byte
  3404.         has the lower, even address.
  3405.  
  3406.     2.  INTEGER4 and REAL
  3407.  
  3408.         INTEGER4 values are 32-bit two's complement numbers, with the least
  3409.         significant byte at the lowest, even address and more significant
  3410.         bytes at increasing addresses. There are no subranges for INTEGER4
  3411.         (as there are for INTEGER2).
  3412.  
  3413.         IEEE 4-byte real numbers have a sign bit, 8-bit excess 127 binary
  3414.         exponent, and a 24-bit mantissa. The mantissa represents a number
  3415.         between 1.0 and 2.0. Since the high-order bit of the mantissa is
  3416.         always 1, it is not stored in the number. This representation gives
  3417.         an exponent range of 10**38 and 7 digits of precision. The maximum
  3418.         real number is normally 1.701411E38.
  3419.  
  3420.         IEEE 8-byte real numbers have a similar format, except that the
  3421.         exponent is 11-bits excess 1023, and the mantissa has 52 bits (plus
  3422.         the implied high-order 1 bit). (This gives an exponent range of
  3423.         10**306 and 15 digits of precision.)
  3424.  
  3425.         In either case, a number with an exponent of all zeros is considered
  3426.         zero. An exponent of all ones is a flag for an invalid real number,
  3427.         or NAN ("Not A Number").
  3428.  
  3429.     3.  Single and Double DECIMAL floating-point
  3430.  
  3431.         Decimal floating-point numbers consist of a byte containing a sign
  3432.         bit and a 7-bit exponent in excess 64 notation followed by a
  3433.         mantissa consisting of 6 (single) and 14 (double) binary coded
  3434.         decimal digits packed two to a byte. (If the exponent byte is zero,
  3435.         the number is zero.) The allowable ranges of numbers are,
  3436.  
  3437.         single      +.1E-63 to +.999999E63
  3438.                     -.1E-63 to -.999999E63
  3439.         double      +.1E-63 to +.99999999999999E63
  3440.                     -.1E-63 to -.99999999999999E63
  3441.  
  3442.     4.  CHAR, BOOLEAN, and enumerated types
  3443.  
  3444.         CHAR values and BOOLEAN values take 8 bits. CHAR values correspond
  3445.         to the ASCII collating sequence. For BOOLEAN values, FALSE is 0 and
  3446.         TRUE is 1. The low-order bit (bit 0) is generally used to check this
  3447.         value. Bits 1 through 7 are presumed to be 0.
  3448.  
  3449.         Enumerated values take 8 bits if 256 or fewer values are declared;
  3450.         otherwise 16 bits are declared. Values are assigned starting at 0.
  3451.         Subrange values take either 8 or 16 bits.
  3452.  
  3453.     5.  Reference types
  3454.  
  3455.         Pointer values currently take 16 bits. A pointer is an offset within
  3456.         the current default data segment. Other representations, such as an
  3457.         offset from an address kept in a global variable or an address
  3458.         divided by a power of two, may be used in the future. A pointer to a
  3459.         super array type is followed by the bounds (see item number 6 of
  3460.         this list), increasing the length of the pointer value (DS/SS).
  3461.  
  3462.         ADR and ADS are offset addresses and segmented addresses, respec-
  3463.         tively. For segmented addresses, the offset is the lower address,
  3464.         and the segment follows.
  3465.  
  3466.         The heap contains heap blocks, which may be allocated or free. A
  3467.         heap block contains a header WORD, with a 15-bit length (in WORDs)
  3468.         and the lower-order bit, which is 1 for free blocks and 0 for
  3469.         allocated blocks. The starting and ending heap addresses are WORD
  3470.         variables in BEGHQQ and ENDHQQ.
  3471.  
  3472.     6.  Procedural and functional parameters
  3473.  
  3474.         Procedural parameters contain a reference to the procedure or
  3475.         function's location along with a reference to the "upper
  3476.         framepointer" (a list of stack frames of statically enclosing
  3477.         routines). The parameter always contains two words, in one of two
  3478.         formats. In the first format, the first word contains the actual
  3479.         routine's address (a local code segment offset), and the second word
  3480.         contains the upper framepointer. The upper framepointer is zero if
  3481.         the actual routine is not nested in a procedure or function and,
  3482.         therefore, the routine has no upper framepointer.
  3483.  
  3484.         In the second format, used for segmented address targets, the first
  3485.         word is zero and the second word contains a data segment offset
  3486.         address. This is an offset to two words in the constant area that
  3487.         contain the segmented address of the actual routine. There is never
  3488.         an upper framepointer in this case.
  3489.  
  3490.     7.  Super arrays
  3491.  
  3492.         A super array type's representation is similar whether it is a
  3493.         reference parameter or the referent of a pointer. First comes the
  3494.         address (reference parameter) or pointer value, which is either 2 or
  3495.         4 bytes long. Following the address are the upper bounds, which are
  3496.         signed or unsigned 16-bit quantities. The bounds occur in the same
  3497.         order as they are declared. A pointer value to a super array type is
  3498.         normally longer than other pointers, since the upper bounds are
  3499.         included.
  3500.  
  3501.     8.  Sets
  3502.  
  3503.         The number of bytes allocated for a SET is:
  3504.  
  3505.            (ORD (upperbound) DIV 16) * 2 + 2
  3506.  
  3507.         This is always an even number from 2 to 32 bytes. For example,
  3508.  
  3509.            SET OF 'A'..'Z'
  3510.  
  3511.         requires 12 bytes. Internally, a set consists of an array of bits,
  3512.         with one bit for every possible ORD value from 0 to the upper bound.
  3513.         Bits in a byte are accessed starting with the most significant bit.
  3514.         The occurrence of a given ORD value as an element of a set implies
  3515.         the bit is 1, and the byte and bit position of a given ORD
  3516.         value of any set is the same. For example, the ORD value of 'A' is
  3517.         65, and the second bit (i.e., 2 01000000) of the ninth byte in a set
  3518.         is 1 if 'A' is in the set.
  3519.  
  3520.     9.  Files
  3521.  
  3522.         A FILE type in a program is a record called a file control block (of
  3523.         type FCBFQQ) in the file unit. The initial portion of the FCBFQQ
  3524.         record is standard for all files, but the remainder is available for
  3525.         use by the particular target file system. The end of the FCB
  3526.         contains the current buffer variable. The internal form of a file
  3527.         varies depending on the target file system.
  3528.  
  3529.         Under MS-DOS, ASCII files consist of lines followed by a carriage
  3530.         return and linefeed pair, which together are a "line marker." MS-DOS
  3531.         binary files are simply a stream of bytes.
  3532.  
  3533.     10. Structures
  3534.  
  3535.         For arrays and records, the internal form is comprised of the
  3536.         internal forms of the components, in the same order as in the
  3537.         declaration. Arrays, records, variants, sets, and files always
  3538.         start on a word boundary. In any case, variables cannot be
  3539.         allocated more than MAXWORD (64K) bytes.
  3540.  
  3541.         A PACKED type has the same representation as an unpacked one.
  3542.  
  3543.         A variable or component 16 bits or larger is always aligned on a
  3544.         word boundary; therefore, it always has an even byte address. The
  3545.         only exception is when explicit field offsets are given by the user
  3546.         in a program.
  3547.  
  3548.         An 8-bit variable is also aligned on a word boundary, but an 8-bit
  3549.         component of a structure (array or record) is aligned on a byte
  3550.         boundary, which can be at an even or odd address. Currently, an
  3551.         array of 8-bit values starts on a word boundary. (This may change
  3552.         in future versions of MS-Pascal.)
  3553.  
  3554.  Some variables are initialized automatically, whether they reside in fixed
  3555.  memory, on the stack, or on the heap.
  3556.  
  3557.     1.  Files (FCBFQQ records) are initialized by calling NEWFQQ, by passing
  3558.         the size of a textfile line buffer or binary file component,
  3559.         and by passing a Boolean flag value to indicate whether the file is
  3560.         a textfile.
  3561.  
  3562.     2.  If $initck is on, INTEGER values and their 2-byte subranges are
  3563.         initialized to 16 8000, 1-byte INTEGER subranges to 16 80, IEEE REAL
  3564.         values to 16 FFFF, and pointers to 16 0001. The following variables
  3565.         are never initialized by $initck, however:
  3566.  
  3567.         a. variables found in a VALUE section
  3568.  
  3569.         b. variant fields in a record
  3570.  
  3571.         c. super arrays allocated on the heap
  3572.  
  3573.  The compiler generates the extra code necessary to initialize stack and
  3574.  heap variables.
  3575.  
  3576.  
  3577.  9.3  Interfacing to Assembly Language Routines
  3578.  
  3579.  In general, interfaced procedures and functions are declared EXTERN in the
  3580.  MS-Pascal source. When an EXTERN procedure or function is called, actual
  3581.  parameters are pushed on the stack in the order in which they are declared.
  3582.  If a parameter is a value parameter, an actual value is pushed on the
  3583.  stack.
  3584.  
  3585.  If a parameter is a VAR or CONST reference parameter, the address of the
  3586.  variable is pushed on the stack. Only the two-byte offset is pushed, and
  3587.  not the segment. The offset is within the default data segment, DS (where
  3588.  SS = DS).
  3589.  
  3590.  In contrast, a VARS or CONSTS parameter includes both a two-byte segment
  3591.  and a two-byte offset, with the segment pushed first.
  3592.  
  3593.  Super array reference parameters include their upper bounds, pushed as
  3594.  value parameters before the address is pushed. For multidimensional super
  3595.  arrays, bounds are pushed in reverse order (i.e., the last flexible bound
  3596.  is pushed first).
  3597.  
  3598.  For some functions, a final, hidden offset address for the return value
  3599.  temporary variable is pushed last.
  3600.  
  3601.  After all parameters have been pushed, the return address for PUBLIC and
  3602.  EXTERN procedures is pushed by a far call instruction. The return address
  3603.  is segmented, so the segment is pushed first, followed by the offset. This
  3604.  is the general starting state of the stack for any assembly language
  3605.  routine that wishes to access parameters.
  3606.  
  3607.  For example, assume that you have created and compiled the following
  3608.  program, which contains the EXTERN function ADD:
  3609.  
  3610.       PROGRAM ASM_INTERFACE (INPUT, OUTPUT);
  3611.       VAR I, TOTAL : INTEGER;
  3612.       FUNCTION ADD (VAR A:INTEGER; B:INTEGER):
  3613.          INTEGER; EXTERN;
  3614.       BEGIN
  3615.         I := 10;
  3616.         TOTAL := ADD (I, 15);
  3617.         WRITELN (OUTPUT, TOTAL)
  3618.       END.
  3619.  
  3620.  When the program executes the ADD function at runtime, it sets up the stack
  3621.  as shown in Figure 9.2.
  3622.  
  3623.  
  3624.    Higher
  3625.  │  addresses │                   │
  3626.               ├───────────────────┤
  3627.               │   DS offset high  │▒
  3628.               ├───────────────────┤▒ Parameter 1
  3629.               │   DS offset low   │▒
  3630.               ├───────────────────┤
  3631.               │   Integer high    │▒
  3632.               ├───────────────────┤▒ Parameter 2
  3633.               │   Integer low     │▒
  3634.               ├───────────────────┤
  3635.               │   Segment high    │▒
  3636.               ├───────────────────┤▒
  3637.               │   Segment low     │▒
  3638.               ├───────────────────┤▒ Return address
  3639.               │   Offset high     │▒
  3640.               ├───────────────────┤▒
  3641.  SP ──────── │   Offset low      │▒
  3642.  Stack        └───────────────────┘
  3643.  grows
  3644.  downward
  3645.  
  3646.               Figure 9.2.  Stack Before Transfer to ADD
  3647.  
  3648.  
  3649.  Before you could run such a program, however, you would have to link it to
  3650.  a routine that implements the ADD function. Implementation of ADD in
  3651.  assembly language might look like this:
  3652.  
  3653.       DATA   SEGMENT PUBLIC 'DATA'
  3654.                             ;PUBLIC and EXTERN data
  3655.                             ;declarations go here.
  3656.       DATA   ENDS
  3657.       DGROUP GROUP DATA
  3658.              ASSUME  CS:ADDS,DS:DGROUP,SS:DGROUP
  3659.  
  3660.       ADDS   SEGMENT 'CODE'
  3661.       PUBLIC ADD
  3662.       ADD    PROC FAR
  3663.              PUSH BP        ;Save framepointer on stack
  3664.              MOV  BP,SP     ;Address parameters
  3665.              MOV  AX,6[BP]  ;AX := value of B
  3666.              MOV  BX,8[BP]  ;BX := address of A
  3667.              ADD  AX,[BX]   ;AX := integer A + integer B
  3668.              POP  BP        ;Restore framepointer
  3669.              RET  4         ;Return, pop 4 bytes
  3670.       ADD    ENDP
  3671.       ADDS   ENDS
  3672.              END
  3673.  
  3674.  Remember that when an EXTERN procedure or function is called at runtime,
  3675.  parameters are pushed on the stack. An assembly language routine must rely
  3676.  on these pushed parameters being in a certain sequence and format. It must
  3677.  also remove all parameters from the stack before returning.
  3678.  
  3679.  Assembly language routines must save and restore the BP and DS registers.
  3680.  They must not even modify the SS register. However, the remaining
  3681.  registers (FLAGS, AX, BX, CX, DX, SI, DI, and ES) can be changed by the
  3682.  assembly language routines as needed.
  3683.  
  3684.  If the routine is a function, the return value is placed in registers. If
  3685.  the return value is a one-byte value, it is placed in the AL register, as
  3686.  shown in Figure 9.3. AH need not be set.
  3687.  
  3688.  
  3689.       ┌─────────────┬─────────────┐
  3690.       │   00000000  │   Low byte  │  Single byte
  3691.       └─────────────┴─────────────┘  return value
  3692.              AH            AL
  3693.  
  3694.              Figure 9.3.  One-Byte Return Value
  3695.  
  3696.  
  3697.  If the return value is a two-byte value, the returned value is placed in
  3698.  the AX register pair, high byte in AH and low byte in AL, as shown in
  3699.  Figure 9.4.
  3700.  
  3701.  
  3702.       ┌─────────────┬─────────────┐
  3703.       │   High byte │   Low byte  │  Single word
  3704.       └─────────────┴─────────────┘  return value
  3705.               AH           AL
  3706.  
  3707.               Figure 9.4.  Two-Byte Return Value
  3708.  
  3709.  
  3710.  If the return value is a four-byte value, the high part (or segment) of the
  3711.  return value is placed in the DX register and the low part (or offset) in
  3712.  the AX register. (This is sometimes shown as DX:AX.)  Note that this only
  3713.  applies to INTEGER4 and ADS types.
  3714.  
  3715.  Since MS-Pascal permits structured values to be retrieved by a function, it
  3716.  is possible for the return value's size in bytes to be extremely large.
  3717.  Therefore, for all function returns of any real or structured type (REAL4,
  3718.  REAL8, array, record, or set) or of a pointer to a super array type, the
  3719.  compiler allocates its own temporary variable. This occurs even if the size
  3720.  of the return value is 1, 2, or 4 bytes. The address of this temporary
  3721.  variable is pushed on the stack after all parameters, just before the
  3722.  return address is pushed, as shown in Figure 9.5. (This address is an
  3723.  offset, and therefore only one word is pushed.)
  3724.  
  3725.  
  3726.  
  3727.  │ Higher    │                 │
  3728.  │ addresses ├─────────────────┤
  3729.              │                 │
  3730.              │ Other parameters│
  3731.              │                 │
  3732.              ├─────────────────┤
  3733.              │ DS offset high  │▒
  3734.              ├─────────────────┤▒ Address of structure
  3735.              │ DS offset low   │▒
  3736.              ├─────────────────┤
  3737.              │ Segment high    │▒
  3738.              ├─────────────────┤▒
  3739.              │ Segment low     │▒
  3740.              ├─────────────────┤▒ Return address
  3741.              │ Offset high     │▒
  3742.              ├─────────────────┤▒
  3743.  SP ─────── │ Offset low      │▒
  3744.  Stack       └─────────────────┘
  3745.  grows
  3746.  downward
  3747.  
  3748.              Figure 9.5.  Four-Byte Return Value
  3749.  
  3750.  
  3751.  On exit from the function, the address of this temporary variable should be
  3752.  placed in the AX register in lieu of the full structure. This address is
  3753.  simply an offset returned in the AX register.
  3754.  
  3755.  You may wish to pass data using PUBLIC and EXTERN variables instead of
  3756.  parameters. If so, these variable declarations go into a segment named
  3757.  DATA with class name 'DATA', in group DGROUP. It is important that you give
  3758.  the correct segment, class, and group names, as shown in the last
  3759.  example.
  3760.  
  3761.  
  3762.  
  3763.  Chapter 10  Advanced Topics
  3764.  
  3765.  ───────────────────────────────────────────────────────────────────────────
  3766.  
  3767.  10.1  The Structure of the Compiler
  3768.  
  3769.         10.1.1  The Front End
  3770.  
  3771.         10.1.2  The Back End
  3772.  
  3773.                  10.1.2.1  Pass Two
  3774.  
  3775.                  10.1.2.2  Pass Three
  3776.  
  3777.  10.2  An Overview of the File System
  3778.  
  3779.  10.3  Runtime Architecture
  3780.  
  3781.         10.3.1  Runtime Routines
  3782.  
  3783.         10.3.2  Memory Organization
  3784.  
  3785.         10.3.3  Initialization and Termination
  3786.  
  3787.                  10.3.3.1  Machine Level Initialization
  3788.  
  3789.                  10.3.3.2  Program Level Initialization
  3790.  
  3791.                  10.3.3.3  Unit Level Initialization
  3792.  
  3793.                  10.3.3.4  Program Termination
  3794.  
  3795.         10.3.4  Error Handling
  3796.  
  3797.                  10.3.4.1  Machine Error Context
  3798.  
  3799.                  10.3.4.2  Source Error Context
  3800.  
  3801.  10.4  Floating-Point Operations
  3802.  
  3803.         10.4.1  The $floatcalls- Option
  3804.  
  3805.         10.4.2  The Alternate Math Package
  3806.  
  3807.         10.4.3  No Emulation Option
  3808.  
  3809.         10.4.4  Decimal Math Option
  3810.  
  3811.         10.4.5  Loading the Emulator Kernel Transcendentals
  3812.  
  3813.  10.5  MS-DOS 2.O Issues
  3814.  
  3815.         10.5.1  Interface to MS-DOS 2.0 File System
  3816.  
  3817.         10.5.2  Exit Status Available to MS-DOS 2.0
  3818.  
  3819.  
  3820.  
  3821.  This chapter contains advanced technical information that will be of
  3822.  interest primarily to experienced programmers. Since Microsoft Pascal and
  3823.  Microsoft FORTRAN (but not FORTRAN-80) have the same compiler back end, and
  3824.  share a common file and runtime system, much of the information that
  3825.  follows refers to both languages. Differences, where they exist, are noted.
  3826.  
  3827.  
  3828.  10.1  The Structure of the Compiler
  3829.  
  3830.  The compiler is divided into three phases, or passes, each of which
  3831.  performs a specific part of the compilation process. Figure 10.1
  3832.  illustrates the basic structure of the compiler and its relationship to
  3833.  the files that it reads and writes.
  3834.  
  3835.  
  3836.                The Compiler                Files
  3837.         ┌───────────────────────────┐
  3838.        ▒│ Pass One                  │
  3839.        ▒│                           │
  3840.        ▒│ Scanner                 ─┼──── Source
  3841.  Front ▒│ Low-level utilities     ──┼─── Sourcelist
  3842.  end   ▒│ Middle-level utilities  ──┼─── Icode ───┐
  3843.        ▒│ High-level utilities    ──┼─── Symtab   │
  3844.         ├───────────────────────────┤        │     │
  3845.        ▒│ Pass Two                ─┼────────┘     │
  3846.        ▒│                           │              │
  3847.        ▒│ Optimizer               ─┼──────────────┘
  3848.        ▒│ Code generator          ──┼─── Bincod ──┐
  3849.        ▒│ Link text emitter       ─┼────────┤     │
  3850.  Back  ▒│                         ──┼─── Object   │
  3851.  End   ▒│                         ──┼─── Symtab   │
  3852.        ▒├───────────────────────────┤        │     │
  3853.        ▒│ Pass Three              ─┼────────┘     │
  3854.        ▒│                           │              │
  3855.        ▒│ Object code lister      ─┼──────────────┘
  3856.        ▒│                         ──┼─── Objectlist
  3857.         └───────────────────────────┘
  3858.  
  3859.         Figure 10.1.  The Structure of the Compiler
  3860.  
  3861.  
  3862.  Pass one, which normally corresponds to a file named PAS1.EXE, constitutes
  3863.  the front end of the compiler and performs the following actions:
  3864.  
  3865.     1.  reads the source program
  3866.  
  3867.     2.  compiles the source into an intermediate form
  3868.  
  3869.     3.  writes the source listing file
  3870.  
  3871.     4.  writes the symbol table file
  3872.  
  3873.     5.  writes the intermediate code file
  3874.  
  3875.  Passes two and three (PAS2.EXE and PAS3.EXE) together make up the back end,
  3876.  which does the following:
  3877.  
  3878.     1.  optimizes the intermediate code
  3879.  
  3880.     2.  generates target code from intermediate code
  3881.  
  3882.     3.  writes and reads the intermediate binary file
  3883.  
  3884.     4.  writes the object (link text) file
  3885.  
  3886.     5.  writes the object listing file
  3887.  
  3888.  Both the front and back end of the compiler are written in Microsoft
  3889.  Pascal, in a source format that can be transformed into either relatively
  3890.  standard Pascal or into system level Microsoft Pascal. For information on
  3891.  these levels, see the Microsoft Pascal Reference Manual.
  3892.  
  3893.  All intermediate files contain MS-Pascal records. The front and back ends
  3894.  include a common constant and type definition file called PASCOM, which
  3895.  defines the intermediate code and symbol table types. The back ends use a
  3896.  similar file for the intermediate binary file definition. Formatted dump
  3897.  programs for all intermediate files and object files are available for
  3898.  special purpose debugging.
  3899.  
  3900.  The symbol table record is relatively complex, with a variant for every
  3901.  kind of identifier (assorted data types, variables, procedures and
  3902.  functions). The intermediate code (or Icode) record contains an Icode
  3903.  number, opcode, and up to four arguments; an argument can be the Icode
  3904.  number of another Icode to represent expressions in tree form, or something
  3905.  else (such as a symbol table reference, constant, or length). The
  3906.  intermediate binary code record contains several variants for absolute code
  3907.  or data bytes, public or external references, label references and
  3908.  definitions, etc.
  3909.  
  3910.  
  3911.  10.1.1  The Front End
  3912.  
  3913.  The  Microsoft Pascal front end can be divided into several parts:
  3914.  
  3915.     1.  the scanner
  3916.  
  3917.     2.  low-level utilities
  3918.  
  3919.     3.  intermediate-level utilities for identifiers, symbols, Icodes,
  3920.         memory allocation, and type compatibility
  3921.  
  3922.     4.  high-level routines for processing procedure and function calls,
  3923.         expressions, statements, and declarations
  3924.  
  3925.  The front end is driven by recursive descent syntax analysis, using a set
  3926.  of procedures such as EXPR (for expressions), STATEMT (for statements), and
  3927.  TYPEDEC (for type declarations).
  3928.  
  3929.  The front end maintains a "current" symbol and a "lookahead" symbol. While
  3930.  not necessary for parsing correct programs, these symbols are useful for
  3931.  error recovery. Syntax errors are processed by a procedure that forces the
  3932.  current symbol to one of a set of symbols legal at a given point. If the
  3933.  current symbol is wrong, but the following one is correct, the current
  3934.  symbol is deleted. In all cases the correct symbol is inserted if
  3935.  possible. However, common substitution mistakes, such as confusing (=) and
  3936.  (:=), cause only a warning message to be given during compilation.
  3937.  
  3938.  The scanner is relatively large, since it must process metalanguage and
  3939.  produce a listing with error messages, data about variables, and other
  3940.  information for the user.
  3941.  
  3942.  Intermediate code is written to the Icode file on disk as soon as it is
  3943.  generated: there is no reason to keep it in memory. The symbol table is
  3944.  built as a binary tree of identifiers with pointers to semantic records. At
  3945.  the end of each block, all new semantic records are written to the symbol
  3946.  table file. When an error is detected, all writing to intermediate files
  3947.  stops, since the code may not be acceptable to the back end. Detecting a
  3948.  warning, rather than an error, does not invalidate the intermediate files.
  3949.  
  3950.  
  3951.  10.1.2  The Back End
  3952.  
  3953.  Of the separate passes that make up the back end of the compiler, pass two
  3954.  is required while pass three is optional. Pass two produces the object
  3955.  file, while pass three produces the object listing.
  3956.  
  3957.  
  3958.  10.1.2.1  Pass Two
  3959.  
  3960.  The optimizer reads the interpass files in the following order: first the
  3961.  symbol table for a block is read; then the intermediate code for the block.
  3962.  Optimization is performed on each "basic block," that is, each block of
  3963.  intermediate code up to the first internal or user label or up to a fixed
  3964.  maximum number of Icodes, whichever comes first.
  3965.  
  3966.  Within this block, the optimizer can reorder and condense expressions so
  3967.  long as the intent of the programmer is preserved. For instance, in the
  3968.  following program fragment, the array address A [J, K] need be calculated
  3969.  only once.
  3970.  
  3971.       A [J, K] := A [J, K] + 1;
  3972.       {J := J - 1;}
  3973.       IF A [J, K] = MAX THEN PUNT;
  3974.  
  3975.  However, if the preceding program fragment is rewritten to include the
  3976.  assignment to J, shown in the fragment as a comment, the array address in
  3977.  the IF statement must be partially recalculated.
  3978.  
  3979.  This optimization is called common subexpression elimination. The optimizer
  3980.  also reorders expressions so that the most complicated parts are done
  3981.  first, when more registers for temporary values are available. It also
  3982.  does several other optimizations, such as:
  3983.  
  3984.     1.  constant folding not done by the front end
  3985.  
  3986.     2.  strength reduction (changing multiplications and divisions into
  3987.         shifts when possible)
  3988.  
  3989.     3.  peephole optimization (removing additions of zero, multiplications
  3990.         by one, and changing A := A + 1 to an internal increment memory
  3991.         Icode)
  3992.  
  3993.  The optimizer works by building a tree out of the intermediate codes for
  3994.  each statement and then transforming the list of statement trees.
  3995.  
  3996.  There are seven internal passes per basic block:
  3997.  
  3998.     1.  statement tree construction from the Icode stream
  3999.  
  4000.     2.  preliminary transformations to set address/value flags
  4001.  
  4002.     3.  length checks and type coercions
  4003.  
  4004.     4.  constant and address folding, and expression reordering
  4005.  
  4006.     5.  peephole optimization and strength reduction
  4007.  
  4008.     6.  machine-dependent transformations
  4009.  
  4010.     7.  common subexpression elimination
  4011.  
  4012.  Finally, the optimizer calls the code generator to translate the basic
  4013.  block from tree form to target machine code.
  4014.  
  4015.  The code generator must translate these trees into actual machine code. It
  4016.  uses a series of templates to generate more efficient code for special
  4017.  cases. For example, there is a series of templates for the addition
  4018.  operator. The first template checks for an addition of the constant one.
  4019.  If this addition is found, the template generates an increment instruction.
  4020.  If the template does not find an addition of one, then it gives up, and the
  4021.  next template gets control and checks for an addition of any constant. If
  4022.  this is found, the second template generates an add immediate instruction.
  4023.  
  4024.  The final template in the series must handle the general case. It moves the
  4025.  operands into registers (by recursively calling the code generator itself),
  4026.  then generates an add register instruction. There is a series of templates
  4027.  for every operation. The code generator must also keep track of register
  4028.  contents,  and several memory segment addresses (code, static variables,
  4029.  constant data, etc.). The code generator also allocates any needed
  4030.  temporary variables.
  4031.  
  4032.  The code generator writes a file of binary intermediate code (BINCOD),
  4033.  which contains actual byte values for machine instructions, symbolic
  4034.  references to external routines and variables, and other kinds of data. A
  4035.  final internal pass reads the BINCOD file and writes the object code file.
  4036.  
  4037.  
  4038.  10.1.2.2  Pass Three
  4039.  
  4040.  This short pass reads both the BINCOD file, described in the previous
  4041.  section, and a version of the symbol table file as updated by the optimizer
  4042.  and code generator. Using the data in these files, it writes the generated
  4043.  code in an assembler-like format.
  4044.  
  4045.  For more information about the compiler, especially the back end, see the
  4046.  article "Native-code Compilers are Portable and Fast" (James G. Letwin and
  4047.  Andrea C. Lewis, Electronic Design, May 14, 1981).
  4048.  
  4049.  
  4050.  10.2  An Overview of the File System
  4051.  
  4052.  Since Microsoft Pascal and Microsoft FORTRAN share the same file system,
  4053.  this section includes references to differences between the two, wherever
  4054.  they exist. Microsoft Pascal and Microsoft FORTRAN are designed to be
  4055.  easily interfaced to existing operating systems. The standard interface has
  4056.  two parts:
  4057.  
  4058.     1.  a file control block (FCB) declaration
  4059.  
  4060.     2.  a set of procedures and functions, called Unit U, that are called
  4061.         from Microsoft Pascal or Microsoft FORTRAN at runtime to perform
  4062.         input and output
  4063.  
  4064.  This interface supports three access methods: TERMINAL, SEQUENTIAL, and
  4065.  DIRECT.
  4066.  
  4067.  Each file has an associated FCB (file control block). The FCB record type
  4068.  begins with a number of standard fields that are independent of the
  4069.  operating system. Following these standard fields are fields such as
  4070.  channel numbers, buffers, and other data, that are dependent on the
  4071.  operating system.
  4072.  
  4073.  The advanced Microsoft Pascal user can access FCB fields directly, as
  4074.  explained in Chapter 8, "Files," of the Microsoft Pascal Reference Manual.
  4075.  There is no standard way to access FCB fields within Microsoft FORTRAN.
  4076.  
  4077.  Both Microsoft Pascal and Microsoft FORTRAN have two special file control
  4078.  blocks that correspond to the keyboard and the screen of your terminal.
  4079.  These two file control blocks are always available. In MS-Pascal, they are
  4080.  the predeclared files INPUT and OUTPUT (which you can reassign and
  4081.  generally treat like any other files); in MS-FORTRAN, they are unit number
  4082.  0 (or *) and accessed through a variable TRMVQQ, declared as follows:
  4083.  
  4084.       VAR TRMVQQ:  ARRAY [BOOLEAN] OF ADR OF FCBFQQ;
  4085.  
  4086.  The false element references the output file; the true element references
  4087.  the input file.
  4088.  
  4089.  For Microsoft Pascal files, each FCB ends with the buffer variable that
  4090.  contains the current file component. This means that the length of an FCB
  4091.  in Microsoft Pascal is the length of its fixed portion plus the length of
  4092.  the buffer variable. Microsoft FORTRAN files do not require buffer
  4093.  variables, so all are of a fixed length.
  4094.  
  4095.  File control blocks always reside in the default data segment, so they can
  4096.  be referenced with the offset (ADR) addresses instead of the segmented
  4097.  (ADS) addresses.
  4098.  
  4099.  Microsoft Pascal file variables can occur:
  4100.  
  4101.     1.  in static memory
  4102.  
  4103.     2.  on the stack as local variables
  4104.  
  4105.     3.  in the heap as heap variables
  4106.  
  4107.  In Microsoft Pascal, generated code initializes file control blocks when
  4108.  they are allocated and CLOSEs them when they are deallocated. FORTRAN files
  4109.  are allocated during OPEN and deallocated during CLOSE or at program
  4110.  termination.
  4111.  
  4112.  The manner of allocation and deallocation depends on the operating system.
  4113.  For example, a fixed number of file "slots" may be available, or the
  4114.  routines for Microsoft Pascal heap allocation may be used. In both
  4115.  Microsoft Pascal and Microsoft FORTRAN, an FCB can be created or destroyed,
  4116.  but never moved or copied.
  4117.  
  4118.  The Microsoft Pascal Compiler must know enough about an FCB to allocate
  4119.  one. Thus, it needs to know the length of an FCB less the length of its
  4120.  buffer variable.
  4121.  
  4122.  The Microsoft FORTRAN Compiler itself does not allocate files, so it
  4123.  doesn't need to know the length of an FCB.
  4124.  
  4125.  Unit U refers to the target operating system interface routines. The file
  4126.  routines specific to MS-Pascal are called Unit F; the file routines
  4127.  specific to Microsoft FORTRAN are called Unit V. Code generated by the
  4128.  compiler of either language contains calls to Unit F (Microsoft Pascal) or
  4129.  Unit V (Microsoft FORTRAN), which in turn call Unit U routines. This
  4130.  relationship is shown schematically in Figure 10.2.
  4131.  
  4132.  
  4133.  Microsoft Pascal                    Microsoft FORTRAN
  4134.       Compiler  ──── Code     Code ──── Compiler
  4135.                        │        │
  4136.                        │        │
  4137.                                
  4138.                      Unit F   Unit V
  4139.                         \       /
  4140.                          \     /
  4141.                           \   /
  4142.                            \ /
  4143.                             
  4144.                           Unit U
  4145.  
  4146.              Figure 10.2.  The Unit U Interface
  4147.  
  4148.  
  4149.  The file system uses the following naming convention for public linker
  4150.  names:
  4151.  
  4152.     1.  All linker globals are six alphabetic characters, ending with QQ.
  4153.         (This helps to avoid conflicts with program global names.)
  4154.  
  4155.     2.  The fourth letter indicates a general class, where:
  4156.  
  4157.         a. xxxFQQ is part of the generic Microsoft Pascal file unit.
  4158.  
  4159.         b. xxxVQQ is part of the generic Microsoft FORTRAN file unit.
  4160.  
  4161.         c. xxxUQQ is part of the operating system interface unit.
  4162.  
  4163.  File system error conditions may be detected at the lower Unit U level,
  4164.  detected at the higher Unit F or V level, or undetected. When a Unit U
  4165.  routine detects an error, it sets an appropriate flag in the FCB and
  4166.  returns to the calling Unit F or V routine. When Unit F or V detects an
  4167.  error or discovers Unit U has detected one, it takes one of two possible
  4168.  actions:
  4169.  
  4170.     1.  An immediate runtime error message is generated and the program
  4171.         terminates.
  4172.  
  4173.     2.  Unit F or V returns to the calling program if error trapping has
  4174.         been set (in Microsoft Pascal with the TRAP flag, in Microsoft
  4175.         FORTRAN with the ERR=nnn or IOSTAT=var clauses).
  4176.  
  4177.  Units F and V will not pass a file with an error condition to a Unit U
  4178.  routine. For some access methods, certain file operations may lead to an
  4179.  undetected error, such as reading past the end of a record (this condition
  4180.  has undefined results). Runtime errors that cause a program to terminate
  4181.  use the standard error-handling system, which gives the context of the
  4182.  error and provides entry to the target debugging system.
  4183.  
  4184.  The distributed implementation of the Microsoft Pascal Compiler includes
  4185.  the following three source files:
  4186.  
  4187.     1.  FINU contains procedure and function headers for all Unit U
  4188.         routines.
  4189.  
  4190.     2.  FINK contains the common FCB declarations for all MS-Pascal systems,
  4191.         along with the declaration of the FILEMODES type.
  4192.  
  4193.     3.  FINKxx contains the FCB declarations as extended for use in a
  4194.         particular environment. For the MS-DOS version 1.0 environment, the
  4195.         name is FINKXM. For the MS-DOS 2.0 environment, the name is FINKXU.
  4196.         (These extensions are currently the same for MS-DOS, CP/M-80(TM),
  4197.         and CP/M-86(R) environments.)
  4198.  
  4199.  The Microsoft Pascal Compiler runtime package supports MS-DOS 1.0 (2.0
  4200.  compatible ) I/O. A libarary named DOS2PAS.LIB is supplied with the Pascal
  4201.  Compiler. When this library is linked with a Pascal program, the program
  4202.  will use MS-DOS 2.0 I/O. In particular, the 2.0 MS-DOS Pascal I/O system
  4203.  takes advantage of pathnames and file handles.
  4204.  
  4205.  
  4206.  10.3  Runtime Architecture
  4207.  
  4208.  This section describes several topics related to the runtime structure of
  4209.  Microsoft Pascal and Microsoft FORTRAN, with mention of the languages'
  4210.  differences where they exist.
  4211.  
  4212.  
  4213.  10.3.1  Runtime Routines
  4214.  
  4215.  Microsoft Pascal and Microsoft FORTRAN runtime entry points and variables
  4216.  conform to the same naming convention: all names are six characters, and
  4217.  the last three are a unit identification letter followed by the letters
  4218.  "QQ". Table 10.1 shows the current unit identifier suffixes.
  4219.  
  4220.  
  4221.           Table 10.1
  4222.           Unit Identifier Suffixes
  4223. ╓┌─────────────────┌─────────────────────────────────────────────────────────╖
  4224.           Suffix   Unit Function
  4225.           ─────────────────────────────────────
  4226.           AQQ      Complex real
  4227.           BQQ      Compile time utilities
  4228.           CQQ      Encode, decode
  4229.           DQQ      Double precision real
  4230.           EQQ      Error handling
  4231.           FQQ      Microsoft Pascal file system
  4232.           GQQ      Generated code helpers
  4233.           HQQ      Heap allocator
  4234.           IQQ      Generated code helpers
  4235.           JQQ      Generated code helpers
  4236.           KQQ      FCB definition
  4237.           LQQ      STRING, LSTRING
  4238.           MQQ      Reserved
  4239.           NQQ      Long integer
  4240.           OQQ      Other miscellaneous routines
  4241.           PQQ      Pcode interpreter
  4242.           QQQ      Reserved
  4243.           RQQ      Real (single precision)
  4244.           Suffix   Unit Function
  4245.          RQQ      Real (single precision)
  4246.           SQQ      Set operations
  4247.           TQQ      $floatcalls interface
  4248.           UQQ      Operating system file system
  4249.           VQQ      Microsoft FORTRAN file system
  4250.           WQQ      Reserved
  4251.           XQQ      Initialize/terminate
  4252.           YQQ      Special utilities
  4253.           ZQQ      Reserved
  4254.  
  4255.  
  4256.  10.3.2  Memory Organization
  4257.  
  4258.  Memory on the 8086 is divided into segments, each containing up to 64K
  4259.  bytes. The relocatable object format and Microsoft LINK also put segments
  4260.  into classes and groups. All segments with the same class name are loaded
  4261.  next to each other. All segments with the same group name must reside in
  4262.  one area up to 64K long; that is, all segments in a group can be accessed
  4263.  with one 8086 segment register.
  4264.  
  4265.  Microsoft Pascal and Microsoft FORTRAN both define a single group, named
  4266.  DGROUP, which is addressed using the DS or SS segment register. Normally,
  4267.  DS and SS contain the same value, although DS may be changed temporarily to
  4268.  some other segment and changed back again. SS is never changed; its
  4269.  segment registers always contain abstract "segment values" and the contents
  4270.  are never examined or operated on. This provides compatibility with the
  4271.  Intel 80286 processor. Long addresses, such as MS-Pascal ADS variables or
  4272.  MS-FORTRAN named common blocks, use the ES segment register for
  4273.  addressing.
  4274.  
  4275.  Memory is allocated within DGROUP for all static variables, constants which
  4276.  reside in memory, the stack, the heap, and the segmented addresses of
  4277.  Microsoft FORTRAN blank common and named common blocks. The blank and
  4278.  named common blocks themselves reside in their own segments, not in
  4279.  DGROUP.
  4280.  
  4281.  Memory in DGROUP is allocated from the top down; that is, the highest
  4282.  addressed byte has DGROUP offset 65535, and the lowest allocated byte has
  4283.  some positive offset. This allocation means offset zero in DGROUP may
  4284.  address a byte in the code portion of memory, in the operating system below
  4285.  the code, or even below absolute memory address zero (in the latter case
  4286.  the values in DS and SS are "negative").
  4287.  
  4288.  DGROUP has two parts:
  4289.  
  4290.     1.  a variable length lower portion containing the heap and the stack
  4291.  
  4292.     2.  a fixed length upper portion containing static variables, constants,
  4293.         and the addresses for blank common and named common, and other data
  4294.         segments.
  4295.  
  4296.  After your program is loaded, during initialization (in ENTX6L), the fixed
  4297.  upper portion is moved upward as much as possible to make room for the
  4298.  lower portion. If there is enough memory, DGROUP is expanded to the full
  4299.  64K bytes; if there is not enough for this, it is expanded as much as
  4300.  possible.
  4301.  
  4302.  Figure 10.3 illustrates memory organization. The paragraphs following the
  4303.  figure describe memory contents, starting at the bottom (address zero),
  4304.  when a Microsoft FORTRAN or Microsoft Pascal program is running. Addresses
  4305.  are shown in "segment:offset" form.
  4306.  
  4307.  
  4308.    ┌──────── Top (highest address) ────────────┐
  4309.    │MS-DOS code for COMMAND (may be overlapped)│
  4310.    ├───────────────────────────────────────────┤
  4311.    │               Unused memory               │
  4312.    ├───────────────────────────────────────────┤
  4313.    │ HIMEM  segment           Class HIMEM      │
  4314.    │<name> segment(s)         Class COMMON     │
  4315.    │ COMMQQ segment           Class COMMON     │
  4316.    │ ─────────── DS offset 65536 ───────────── │
  4317.    │ CONST  segment           Class CONST      │
  4318.    │ COMADS segment           Class COMADS     │
  4319.    │ DATA   segment           Class DATA       │
  4320.    │ STACK  segment           Class STACK      │
  4321.    │ MEMORY segment           Class MEMORY     │
  4322.    │ HEAP   segment           Class MEMORY     │
  4323.    │ ─────────── DS offset >= 00 ───────────── │
  4324.    │ CODE segments [user and library routines] │
  4325.    │      MS-DOS code and data (fixed)         │
  4326.    └──────── Bottom (address 0:00) ────────────┘
  4327.  
  4328.              Figure 10.3.  Memory Organization
  4329.  
  4330.  
  4331.     1.  0000:0000
  4332.  
  4333.         The beginning of memory on an 8086 system contains interrupt
  4334.         vectors, which are segmented addresses. Usually the first 32 to 64
  4335.         are reserved for the operating system. Following these vectors is
  4336.         the resident portion of the operating system (MS-DOS in this case).
  4337.  
  4338.         MS-DOS provides for loading additional code above it, which remains
  4339.         resident and is considered part of the operating system as well.
  4340.         Examples of resident additional code are special device drivers for
  4341.         peripherals, a print spooler, or the debugger.
  4342.  
  4343.     2.  BASE:0000
  4344.  
  4345.         Here, BASE means the starting location for loaded programs,
  4346.         sometimes called the transient program area. When you invoke a
  4347.         Microsoft Pascal or Microsoft FORTRAN program, loading begins here.
  4348.         The beginning of your program contains the code portion, with one or
  4349.         more code segments. These code segments are in the same order as the
  4350.         object modules given to the linker, followed by object modules
  4351.         loaded from libraries.
  4352.  
  4353.     3.  DGROUP:LO
  4354.  
  4355.         Next comes the DGROUP data area, containing the following:
  4356.  
  4357.         Segment  Class   Description
  4358.         ────────────────────────────────────────────────────────────────────
  4359.         HEAP     MEMORY  Pointer variables, some files
  4360.         MEMORY   MEMORY  (not used, Intel compatible)
  4361.         STACK    STACK   Frame variables and data
  4362.         DATA     DATA    Static variables
  4363.         COMADS   COMADS  Address of named commons
  4364.         CONST    CONST   Constant data
  4365.  
  4366.         The stack and the heap grow toward each other, the stack downward
  4367.         and the heap upward.
  4368.  
  4369.     4.  DGROUP:TOP
  4370.  
  4371.         Here TOP means 64K bytes (4K paragraphs) above DGROUP:0000 (i.e.,
  4372.         just past the end of DGROUP). Microsoft FORTRAN blank and named
  4373.         common blocks and other data segments generated for FORTRAN start
  4374.         here. Named common has a segment name as declared in the Microsoft
  4375.         FORTRAN program as the common block name, and the class name COMMON.
  4376.         Each blank and named common block has one segmented (ADS) address in
  4377.         the COMADS segment in DGROUP. All references to common block
  4378.         component variables use offsets from this address.
  4379.  
  4380.     5.  HIMEM:0000
  4381.  
  4382.         The segment named HIMEM (class HIMEM) gives the highest used
  4383.         location in the program. The segment itself contains no
  4384.         data, but its address is used during initialization. Available
  4385.         memory starts here and can be accessed with Microsoft Pascal ADS
  4386.         variables.
  4387.  
  4388.     6.  COMMAND
  4389.  
  4390.         MS-DOS keeps its command processor (the part of itself which does
  4391.         COPY, DIR, and other resident commands) in the highest location in
  4392.         memory possible. Your Microsoft Pascal or Microsoft FORTRAN program
  4393.         may need this memory area in order to run. If so, the command
  4394.         processor is overwritten with program data. When your program
  4395.         finishes, the command processor is reloaded from the file COMAND.COM
  4396.         on the default drive.
  4397.  
  4398.         In some circumstances, the check may result in a message appearing
  4399.         on your screen telling you to insert a disk that contains the
  4400.         appropriate file, COMAND.COM. You can avoid this delay by making
  4401.         sure that COMAND.COM is on the disk in the default drive when the
  4402.         program ends.
  4403.  
  4404.  
  4405.  10.3.3  Initialization and Termination
  4406.  
  4407.  Every executable file contains one, and only one, starting address. As a
  4408.  rule, when MS-Pascal or MS-FORTRAN object modules are involved, this
  4409.  starting address is at the entry point BEGXQQ in the module ENTX. For some
  4410.  versions, the name ENTX may be appended with other letters. However, the
  4411.  name of the module always begins with the four letters "ENTX". An MS-Pascal
  4412.  or MS-FORTRAN program (as opposed to a module or implementation) has a
  4413.  starting address at the entry point ENTGQQ. BEGXQQ calls ENTGQQ.
  4414.  
  4415.  The following discussion assumes that an MS-Pascal or MS-FORTRAN main
  4416.  program along with other object modules is loaded and executed. However,
  4417.  you can also link a main program in assembly or some other language with
  4418.  other object modules in Microsoft Pascal or Microsoft FORTRAN. In this
  4419.  case, some of the initialization and termination done by the ENTX module
  4420.  may need to be done elsewhere.
  4421.  
  4422.  When a program is linked with the runtime library and execution begins,
  4423.  several levels of initialization are required. The levels are the
  4424.  following:
  4425.  
  4426.     1.  machine level initialization
  4427.  
  4428.     2.  program level initialization
  4429.  
  4430.     3.  unit level initialization
  4431.  
  4432.  The general scheme is shown in Figure 10.4.
  4433.  
  4434.  
  4435.       ENTX module
  4436.  
  4437.            BEGXQQ:  Set stackpointer, framepointer
  4438.                     Initialize PUBLIC variables
  4439.                     Set machine-dependent flags,
  4440.                       registers, and other values
  4441.                     Call INIX87
  4442.                     Call INIUQQ
  4443.                     Call BEGOQQ
  4444.                     Call ENTGQQ {Execute program}
  4445.  
  4446.            ENDXQQ:  {Terminations come here}
  4447.                     Call ENDOQQ
  4448.                     Call ENDYQQ
  4449.                     Call ENDUQQ
  4450.                     Call ENDX87
  4451.                     Exit to operating system
  4452.       ─────────────────────────────────────────────
  4453.       INTR Module
  4454.  
  4455.            INIX87:  Real processor initialization
  4456.            ENDX87:  Real processor termination
  4457.       ─────────────────────────────────────────────
  4458.       Unit U
  4459.  
  4460.            INIUQQ:  Operating system specific
  4461.                     file unit initialization
  4462.            ENDUQQ:  Operating system specific
  4463.                     file unit termination
  4464.       ─────────────────────────────────────────────
  4465.       MISO Module
  4466.  
  4467.            BEGOQQ:  (Other user initialization)
  4468.            ENDOQQ:  (Other user termination)
  4469.       ─────────────────────────────────────────────
  4470.       Program Module
  4471.  
  4472.              ENTGQQ:  Call INIFQQ
  4473.                       If $entry on, CALL ENTEQQ
  4474.                       Initialize static data
  4475.                       Initialize units
  4476.                       FOR program parameters DO
  4477.                         Call PPMFQQ
  4478.                       Execute program
  4479.                       If $entry on, CALL EXTEQQ
  4480.  
  4481.       Figure 10.4.  Microsoft Pascal Program Structure
  4482.  
  4483.  
  4484.  10.3.3.1  Machine Level Initialization
  4485.  
  4486.  The entry point of an MS-Pascal load module is the routine BEGXQQ, in the
  4487.  module ENTX. (The module may also be called ENTX8, ENTX6M, etc.) BEGXQQ
  4488.  does the following:
  4489.  
  4490.     1.  It moves constant and static variables upward (as described at the
  4491.         end of the introduction to this chapter), creating a gap for the
  4492.         stack and the heap. It sets the stackpointer to the top of this
  4493.         area. The initial stackpointer is put into PUBLIC variable STKBQQ
  4494.         and is used to restore the stackpointer after an interprocedure GOTO
  4495.         to the main program.
  4496.  
  4497.     2.  It sets the framepointer to zero.
  4498.  
  4499.     3.  It initializes a number of PUBLIC variables to zero or NIL. These
  4500.         include:
  4501.  
  4502.             RESEQQ, machine error context
  4503.             CSXEQQ, source error context list header
  4504.             CRUXQQ, initialized unit list header
  4505.             HDRFQQ, MS-Pascal open file list header
  4506.             HDRVQQ, MS-FORTRAN open file list header
  4507.  
  4508.     4.  It sets machine-dependent registers, flags, and other values.
  4509.  
  4510.     5.  It sets the heap control variables. BEGHQQ and CURHQQ are set to the
  4511.         lowest address for the heap; the word at this address is set to a
  4512.         heap block header for a free block the length of the initial heap.
  4513.         ENDHQQ is set to the address of the first word after the heap. The
  4514.         stack and the heap grow together, and the PUBLIC variable STKHQQ is
  4515.         set to the lowest legal stack address (ENDHQQ, plus a safety gap).
  4516.  
  4517.     6.  It calls INIX87, the real processor initializer, indirectly through
  4518.         segment EINQQQ. This routine initializes an 8087 or sets 8087
  4519.         emulator interrupt vectors, as appropriate.
  4520.  
  4521.     7.  It calls INIUQQ, the file unit initializer specific to the operating
  4522.         system. If the file unit is not used and you don't want it loaded, a
  4523.         dummy INIUQQ routine that just returns must be loaded.
  4524.  
  4525.     8.  It calls BEGOQQ, the escape initializer. In a normal load module, an
  4526.         empty BEGOQQ that only returns is included. However, this call
  4527.         provides an escape mechanism for any other initialization. For
  4528.         example, it could initialize tables for an interrupt driven profiler
  4529.         or a runtime debugger.
  4530.  
  4531.     9.  It calls ENTGQQ, the entry point of your Microsoft Pascal program.
  4532.  
  4533.  
  4534.  10.3.3.2  Program Level Initialization
  4535.  
  4536.  Your main program continues the initialization process. First, the
  4537.  language-specific file system is called, INIFQQ for MS-Pascal or INIVQQ for
  4538.  MS-FORTRAN. Both are parameterless procedures.
  4539.  
  4540.  If the main program is in Microsoft Pascal, and MS-FORTRAN file routines
  4541.  will be used, you must call INIVQQ to initialize the MS-FORTRAN file
  4542.  system. If the main program is in Microsoft FORTRAN, and MS-Pascal file
  4543.  routines will be used, you must call INIFQQ to initialize the MS-Pascal
  4544.  file system.
  4545.  
  4546.  MS-Pascal main programs automatically call INIFQQ; MS-FORTRAN main programs
  4547.  automatically call INIVQQ. To avoid loading the file system, you must
  4548.  provide an empty procedure to satisfy one or both of these calls.
  4549.  
  4550.  After file initialization, ENTEQQ is called to set the source error context
  4551.  (but only if $entry is on during compilation). Next, each file at the
  4552.  program level gets an initialization call to NEWFQQ.
  4553.  
  4554.  After static data initialization comes unit initialization. Every USES
  4555.  clause in the source, including those in INTERFACEs, generates a call to
  4556.  the initialization code for the unit.
  4557.  
  4558.  Units may or may not contain initialization code. If the interface contains
  4559.  a trailing pair of BEGIN and END statements, then initialization code in
  4560.  the implementation is presumed. Units are initialized in the order that the
  4561.  USES clauses are encountered.
  4562.  
  4563.  Finally, any program parameters are read or otherwise initialized, and your
  4564.  program begins. Program parameters are set in one of a number of ways,
  4565.  depending on the target operating system. In general, except for INPUT and
  4566.  OUTPUT, PPMFQQ is called for each parameter to set the parameter's string
  4567.  value as the next line in the file INPUT. Then one of the READFN routines
  4568.  "reads" and decodes the value, assigning it to the parameter. The
  4569.  parameter's identifier is passed to PPMFQQ for use as a prompt. PPMFQQ
  4570.  first calls PPMUQQ to get the text of any command line parameter or other
  4571.  parameters specific to the operating system. If PPMUQQ returns an error,
  4572.  then PPMFQQ does the prompting and reads the response directly.
  4573.  
  4574.  
  4575.  10.3.3.3  Unit Level Initialization
  4576.  
  4577.  Unit initialization is much like user program initialization. The following
  4578.  actions occur:
  4579.  
  4580.     1.  error context initialization if $entry metacommand was on during
  4581.         compilation
  4582.  
  4583.     2.  variable (file) initialization
  4584.  
  4585.     3.  unit initialization for USES clause
  4586.  
  4587.     4.  user's unit initialization
  4588.  
  4589.  Calls to initialize a unit may come from more than one unit. The unit
  4590.  interface has a version number, and each initialization call must check
  4591.  that the version number in effect when the unit was used in another
  4592.  compilation is the same as the version number in effect when the unit
  4593.  implementation itself was compiled. Except for this, unit initialization
  4594.  calls after the first one should have no effect; i.e., a unit's
  4595.  initialization code should be executed only once. Both version-number
  4596.  checking and single, initial-code execution are handled with code
  4597.  automatically generated at the start of the body of the unit. This has the
  4598.  effect of:
  4599.  
  4600.       IF INUXQQ (USEVERSION, OWNVERSION, INITREC, UNITID)
  4601.       THEN RETURN
  4602.  
  4603.  The interface version number used by the compiland using the interface is
  4604.  always passed as a value parameter to the implementation initialization
  4605.  code. This is passed as "useversion" to INUXQQ. The interface version
  4606.  number in the implementation itself is passed as "ownversion" to INUXQQ.
  4607.  INUXQQ generates an error if the two are unequal.
  4608.  
  4609.  INUXQQ also maintains a list of initialized units. INUXQQ returns true if
  4610.  the unit is found in the list, or else puts the unit in the list and
  4611.  returns false. The list header is CRUXQQ. A list entry passed to INUXQQ as
  4612.  "initrec" is initialized to the address of the unit's identifier (unitid),
  4613.  plus a pointer to the next entry.
  4614.  
  4615.  User modules (and uninitialized implementations of units) may have
  4616.  initialization code, much like a program and unit implementation's
  4617.  initialization code, but without user initialization code or INUXQQ calls.
  4618.  
  4619.  The initialization call for a module or uninitialized unit cannot be issued
  4620.  automatically. When the module is compiled, a warning is given if an
  4621.  initialization call will be required (i.e., if there are any files declared
  4622.  or USES clauses). To initialize a module, declare the module name as an
  4623.  external procedure and call it at the beginning of the program.
  4624.  
  4625.  
  4626.  10.3.3.4  Program Termination
  4627.  
  4628.  Program termination occurs in one of three ways:
  4629.  
  4630.     1.  The program may terminate normally, in which case the main program
  4631.         returns to BEGXQQ, at the location named ENDXQQ.
  4632.  
  4633.     2.  The program may terminate because of an error condition, either with
  4634.         a user call to ABORT or a runtime call to an error handling routine.
  4635.         In either case, an error message, error code, and error status are
  4636.         passed to EMSEQQ, which does whatever error handling it can and
  4637.         calls ENDXQQ.
  4638.  
  4639.     3.  ENDXQQ can be declared in an external procedure and called directly.
  4640.  
  4641.  ENDXQQ first calls ENDOQQ, the escape terminator, which normally just
  4642.  returns to ENDXQQ. Then ENDXQQ calls ENDYQQ, the generic file system
  4643.  terminator. ENDYQQ closes all open MS-Pascal and MS-FORTRAN files, using
  4644.  the file list headers HDRFQQ and HDRVQQ. ENDXQQ calls ENDUQQ, the file
  4645.  unit terminator that is operating system specific. Finally, ENDXQQ calls
  4646.  ENDX87 to terminate the real number processor (8087 or emulator) indirectly
  4647.  through segment EINQQQ. As with INIUQQ, INIFQQ, and INIVQQ, if your
  4648.  program requires no file handling, you will need to declare empty
  4649.  parameterless procedures for ENDYQQ and ENDUQQ. The main initialization
  4650.  and termination routines are in module ENTX. Procedures for BEGOQQ and
  4651.  ENDOQQ are in module MISO. ENDYQQ is in module ENDY.
  4652.  
  4653.  
  4654.  10.3.4  Error Handling
  4655.  
  4656.  Runtime errors are detected in one of four ways:
  4657.  
  4658.     1.  The user program calls EMSEQQ (i.e., ABORT).
  4659.  
  4660.     2.  A runtime routine calls EMSEQQ.
  4661.  
  4662.     3.  An error checking routine in the error module calls EMSEQQ.
  4663.  
  4664.     4.  An internal helper routine calls an error message routine in the
  4665.         error unit that, in turn, calls EMSEQQ.
  4666.  
  4667.  Handling an error detected at runtime usually involves identifying the type
  4668.  and location of the error and then terminating the program. The error type
  4669.  has three components:
  4670.  
  4671.     1.  a message
  4672.  
  4673.     2.  an error number
  4674.  
  4675.     3.  an error status
  4676.  
  4677.  In Microsoft Pascal, the message describes the error, and the number can be
  4678.  used to look up more information (see Appendix H, "Messages," in the
  4679.  Microsoft Pascal Reference Manual). In Microsoft FORTRAN, the message
  4680.  describes the error, and the number can be used to look up more information
  4681.  (see Appendix C, "Error Messages," in the Microsoft FORTRAN Reference
  4682.  Manual). In Microsoft FORTRAN, the error status value is used for special
  4683.  purposes and has no significance for the user. In Microsoft Pascal, the
  4684.  error status value is undefined, although for file system errors it may be
  4685.  an operating system return code. However, the error status value may also
  4686.  be used for other special purposes. Table 10.2 shows the general scheme for
  4687.  error code numbering.
  4688.  
  4689.  
  4690.  Table 10.2
  4691.  Error Code Classification
  4692.  
  4693.  Range           Classification
  4694.  ───────────────────────────────────────────────────────
  4695.     1- 999       Reserved for user ABORT calls
  4696.  1000-1099       Unit U file system errors
  4697.  1100-1199       Unit F file system errors
  4698.  1200-1299       Unit V file system errors
  4699.  1300-1999       Reserved
  4700.  2000-2049       Heap, stack, memory
  4701.  2050-2099       Ordinal and long integer arithmetic
  4702.  2100-2149       Real and double real arithmetic
  4703.  2150-2199       Structures, sets and strings
  4704.  2200-2399       Reserved
  4705.  2400-2449       Pcode interpreter
  4706.  2450-2499       Other internal errors
  4707.  2500-2999       Reserved
  4708.  
  4709.  
  4710.  An error location has two parts:
  4711.  
  4712.     1.  the machine error context
  4713.  
  4714.     2.  the source program context
  4715.  
  4716.  The machine error context is the program counter, stackpointer, and
  4717.  framepointer at the point of the error. The program counter is always the
  4718.  address following a call to a runtime routine (e.g., a return address). The
  4719.  source program context is optional; it is controlled by metacommands. If
  4720.  the $entry metacommand is on, the program context consists of:
  4721.  
  4722.     1.  the source filename of the compiland containing the error
  4723.  
  4724.     2.  the name of the routine in which the error occurred (program, unit,
  4725.         module, procedure, or function)
  4726.  
  4727.     3.  the line number of the routine in the listing file
  4728.  
  4729.     4.  the page number of the routine in the listing file
  4730.  
  4731.  If the $line metacommand is also on, the line number of the statement
  4732.  containing the error is also given. Setting $line also sets $entry.
  4733.  
  4734.  
  4735.  10.3.4.1  Machine Error Context
  4736.  
  4737.  Runtime routines are compiled by default with the $runtime metacommand set.
  4738.  This causes special calls to be generated at the entry and exit points of
  4739.  each runtime routine. The entry call saves the context at the point where
  4740.  a runtime routine is called by the user program. This context consists of
  4741.  the framepointer, stackpointer, and program counter. As a consequence of
  4742.  this saving of context, if an error occurs in a runtime routine, the error
  4743.  location is always in the user program. This is true even if runtime
  4744.  routines call other runtime routines. The exit call that is generated
  4745.  restores the context. The runtime entry helper, BRTEQQ, uses the runtime
  4746.  values shown in Table 10.3.
  4747.  
  4748.  
  4749.           Table 10.3
  4750.           Runtime Values in BRTEQQ
  4751.  
  4752.           Value     Description
  4753.           ─────────────────────────────────────
  4754.           RESEQQ    Stackpointer
  4755.           REFEQQ    Framepointer
  4756.           REPEQQ    Program counter offset
  4757.           RECEQQ    Program counter segment
  4758.  
  4759.  
  4760.  The first thing that BRTEQQ does is examine RESEQQ. If this value is not
  4761.  zero, the current runtime routine was called from another runtime routine
  4762.  and the error context has already been set, so it just returns. If RESEQQ
  4763.  is zero, however, the error context must be saved. The caller's
  4764.  stackpointer is determined from the current framepointer and stored in
  4765.  RESEQQ. The address of the caller's saved framepointer and return address
  4766.  (program counter) in the frame is determined. Then the caller's
  4767.  framepointer is saved in REFEQQ. The caller's program counter (i.e.,
  4768.  BRTEQQ's caller's return address) is saved: the offset in REPEQQ and the
  4769.  segment (if any) in RECEQQ.
  4770.  
  4771.  The runtime exit helper, ERTEQQ, has no parameters. It determines the
  4772.  caller's stackpointer (again, from the framepointer) and compares it
  4773.  against RESEQQ. If these values are equal, the original runtime routine
  4774.  called by your program is returning, so RESEQQ is set back to zero.
  4775.  
  4776.  EMSEQQ uses RESEQQ, REFEQQ, REPEQQ, and RECEQQ to display the machine error
  4777.  context.
  4778.  
  4779.  
  4780.  10.3.4.2  Source Error Context
  4781.  
  4782.  Giving the source error context involves extra overhead, since source
  4783.  location data must be included in the object code in some form. Currently,
  4784.  this is done with calls which set the current source context as it occurs.
  4785.  These calls can also be used to break program execution as part of the
  4786.  debug process. The overhead of source location data, especially line
  4787.  number calls, can be significant. Routine entry and exit calls, while
  4788.  requiring more overhead, are much less frequent, so the overhead is less.
  4789.  
  4790.  The procedure entry call to ENTEQQ passes two VAR parameters: the first is
  4791.  an LSTRING containing the source filename; the second is a record that
  4792.  contains the following:
  4793.  
  4794.     1.  the line number of the procedure (a WORD)
  4795.  
  4796.     2.  the page number of the procedure (a WORD)
  4797.  
  4798.     3.  the procedure or function identifier (an LSTRING)
  4799.  
  4800.  The filename is that of the compiland source (e.g., the main source
  4801.  filename, not the names of any $include files). The procedure identifier is
  4802.  the full identifier used in the source, not the linker name. If one name
  4803.  is given in an INTERFACE and another in a USES clause, the USES identifier
  4804.  is used. The line and page are those designated by the procedure header.
  4805.  
  4806.  Entry and exit calls are also generated for the main program, unit
  4807.  initialization, and module initialization, in which case the identifier is
  4808.  the program, unit, or module.
  4809.  
  4810.  The procedure exit call to EXTEQQ does not pass any parameters. It pops
  4811.  the current source routine context off a stack maintained in the
  4812.  heap.
  4813.  
  4814.  The line number call to LNTEQQ passes a line number as a value parameter.
  4815.  The current line number is kept in the PUBLIC variable CLNEQQ. Since the
  4816.  current routine is always available (because $line implies $entry), the
  4817.  compiland source filename and routine containing the line are available
  4818.  along with the line number. Line number calls are generated just before the
  4819.  code in the first statement on a source line. The statement can, of course,
  4820.  be part of a larger statement. The $line+ metacommand should be placed at
  4821.  least a couple of symbols before the start of the first statement intended
  4822.  for a line number call ($line- also takes effect "early").
  4823.  
  4824.  Most of the error handling routines are in modules ERRE and PASE. The
  4825.  source error context entry points ENTEQQ, EXTEQQ, and LNTEQQ are in the
  4826.  debug module, DEBE.
  4827.  
  4828.  
  4829.  10.4  Floating-Point Operations
  4830.  
  4831.  By default, the Microsoft Pascal Compiler generates calls to a real number
  4832.  math package to carry out floating-point operations. This gives the best
  4833.  tradeoff between runtime performance, code size, and flexibility. The real
  4834.  number math package is provided in the standard floating-point runtime
  4835.  library, MATH.LIB. It performs floating-point arithmetic according to the
  4836.  proposed IEEE real math standard, using an 80-bit internal form,
  4837.  irrespective of the precision of the operands.
  4838.  
  4839.  The real math package is also compatible with the 8087 numeric coprocessor.
  4840.  When you run your program on a machine with an 8087 installed, the real
  4841.  math package, which "emulates" the 8087, automatically uses the processor
  4842.  to carry out the arithmetic. This compatibility means that your programs
  4843.  will give the same, very accurate, results whether they run on a machine
  4844.  with an 8087 installed or in another processing environment. (In cases
  4845.  where the real math package is emulating the 8087, some transcendental
  4846.  functions may give different results, but the differences are very
  4847.  slight).
  4848.  
  4849.  Microsoft Pascal also provides options that allow you to tailor your
  4850.  program for performance and size on specific system configurations.
  4851.  Specifically, you can choose to have in-line 8087 instructions generated to
  4852.  perform floating-point operations, you can select a math package optimized
  4853.  for performance but which gives less accurate results, or you can eliminate
  4854.  the math package altogether if you know an 8087 will always be present when
  4855.  your program will be run.
  4856.  
  4857.  Don't forget that using these options will affect the portability of your
  4858.  program and the consistency of its results.
  4859.  
  4860.  
  4861.  10.4.1  The $floatcalls- Option
  4862.  
  4863.  The $floatcalls- metacommand directs the compiler to generate in-line
  4864.  instruction "skeletons" for floating-point operations. With $floatcalls-
  4865.  in your source code and the standard version of MATH.LIB linked into your
  4866.  program, fixups in MATH.LIB will cause the linker to transform the in-line
  4867.  instruction skeletons into software interrupts and control information.
  4868.  The interrupts and control information will be fielded at execution time by
  4869.  an emulator (software math package).
  4870.  
  4871.  When you run your program, the first time each such interrupt is executed,
  4872.  the emulator gets control. If you have an 8087 coprocessor installed, the
  4873.  emulator will overwrite the interrupt and control information with the
  4874.  equivalent 8087 instruction and re-execute it. This and all subsequent
  4875.  executions of the instruction will be carried out by the 8087. If you do
  4876.  not have an 8087, the emulator will use the control information to carry
  4877.  out a software equivalent of 8087 instruction processing. This will occur
  4878.  every time the instruction is executed.
  4879.  
  4880.  The in-line instructions typically require half as much code as the
  4881.  equivalent call sequence and also permit additional optimizations to be
  4882.  performed. Otherwise, nonfloating-point operations are unaffected, and the
  4883.  total reduction in code size will usually be between 10 and 30 per cent.
  4884.  
  4885.  $floatcalls- provides the most efficient execution if you have an 8087
  4886.  installed. However, if you do not, the interrupt mechanism and processing
  4887.  of control information that occurs every time an instruction is emulated is
  4888.  time-consuming and imposes a considerable overhead on the fundamental
  4889.  arithmetic operations. The overhead may be up to 25 percent on the simpler
  4890.  instructions (for example, FADD), but for the same reasons that reduced the
  4891.  impact of this option on code size, you should expect the overall overhead
  4892.  to be somewhat less than this, depending on the mix of instructions.
  4893.  
  4894.  The basic operations are, in fact, carried out by the same code that
  4895.  supports the calls to the emulator and using this option will have no
  4896.  effect on your program's results. Also, you can freely mix modules
  4897.  compiled with $floatcalls- with those compiled with the default option.
  4898.  You can even use a second metacommand, $floatcalls+, to switch between
  4899.  modes within the same module or even subroutine. However, this practice
  4900.  might not take effect exactly where you specified it, because optimizations
  4901.  may group statements or reorder code.
  4902.  
  4903.  ───────────────────────────────────────────────────────────────────────────
  4904.  Important
  4905.     You cannot use this option in any modules that will be linked with
  4906.     the fast math pack ALTMATH.LIB. You will get linker errors if you try.
  4907.  ───────────────────────────────────────────────────────────────────────────
  4908.  
  4909.  
  4910.  10.4.2  The Alternate Math Package
  4911.  
  4912.  The IEEE math standard as supported by the emulator is complicated, and the
  4913.  emulator, as a result, will contribute about 6.5K bytes to your program.
  4914.  Also, arithmetic to 80-bit precision is much more time-consuming than the
  4915.  minimum required to provide reasonable accuracy for 32-bit or even 64-bit
  4916.  floating-point numbers.
  4917.  
  4918.  If you do not require consistency with the 8087, or if the speed of your
  4919.  program is more important than accuracy, you can use the "Alternate Math
  4920.  Package" (AltMath Pack). This is a traditional floating-point support
  4921.  package. Its interface is compatible with the $floatcalls interface to the
  4922.  emulator, but it is optimized for speed. The results of your calculations
  4923.  will be less accurate, particularly for single precision arithmetic, and
  4924.  will, in general, be slightly different than those produced using the 8087
  4925.  or the emulator. However, basic operations will be typically at least
  4926.  twice as fast, and if you don't have an 8087, programs that do a lot of
  4927.  floating-point arithmetic will run much faster.
  4928.  
  4929.  The AltMath Pack assumes a much simpler model for floating-point arithmetic
  4930.  than the IEEE standard, although the external binary representation of real
  4931.  values is the same. For example, all overflow, divide-by-zero, and other
  4932.  exceptions that would result in a NAN ("Not A Number") error message in the
  4933.  IEEE model, will cause an error exit in the AltMath Pack model. Also,
  4934.  unlike the 8087 and emulator models that assume (and support) an infinite
  4935.  stack, the AltMath Pack assumes a fixed stack with a limited number of
  4936.  entries. This means that highly recursive functions may overflow the stack
  4937.  and generate an error.
  4938.  
  4939.  You select the AltMath Pack by linking with the library ALTMATH.LIB, which
  4940.  is provided with the compiler. This library contains only the AltMath Pack,
  4941.  and the remainder of the runtime is obtained from PASCAL.LIB. See Section
  4942.  6.1.2, "Linking Libraries," for a review of the procedure for linking
  4943.  auxiliary libraries. The following examples are equivalent:
  4944.  
  4945.           A> LINK your module ,,, altmath
  4946.           A> LINK your module ,,, altmath+pascal
  4947.  
  4948.  
  4949.  10.4.3  No Emulation Option
  4950.  
  4951.  As mentioned above, the emulator contributes about 6.5K bytes to the size
  4952.  of your program. If you have an 8087 installed, its only purpose is to
  4953.  translate your emulated instructions into actual 8087 instructions. You
  4954.  eliminate the emulator altogether if you know that your program will only
  4955.  run on machines that have an 8087.
  4956.  
  4957.  You do this by linking in the object module 8087.LIB, provided with the
  4958.  compiler. This replaces the emulator and fixes up the in-line instruction
  4959.  skeletons to actual 8087 instructions at link time. $floatcalls interfaces
  4960.  are provided which use the 8087 to carry out the operation, so that you can
  4961.  use 8087.LIB whether or not you have used $floatcalls.
  4962.  
  4963.  ───────────────────────────────────────────────────────────────────────────
  4964.  Note
  4965.     You cannot use 8087.LIB and ALTMATH.LIB in the same program.
  4966.  ───────────────────────────────────────────────────────────────────────────
  4967.  
  4968.  
  4969.  10.4.4  Decimal Math Option
  4970.  
  4971.  Microsoft Pascal supports an alternative floating-point format in which
  4972.  decimal floating-point numbers up to 14 digits and within a limited
  4973.  exponent range can be represented exactly. The results of the operations on
  4974.  the numbers in this format are also represented exactly if they are in the
  4975.  allowable range. This option is particularly useful in business and
  4976.  financial applications where exact results are important. You select the
  4977.  decimal format by using the $decmath metacommand in all of your program
  4978.  units that use floating-point. You must link with DECMATH.LIB to support
  4979.  this format.
  4980.  
  4981.  ───────────────────────────────────────────────────────────────────────────
  4982.  Note
  4983.     Decimal floating-point and IEEE floating-point are not compatible.
  4984.  ───────────────────────────────────────────────────────────────────────────
  4985.  
  4986.  
  4987.  10.4.5  Loading the Emulator Kernel Transcendentals
  4988.  
  4989.  The emulator is capable of emulating 8087 transcendental functions.
  4990.  However, if you write functions in 8087 assembly language that use 8087
  4991.  transcendental instructions, the emulator is not guaranteed to be present.
  4992.  To ensure that the emulator will be loaded with your program, you must add
  4993.  the following segment and variable to your assembly code:
  4994.  
  4995.       DATA SEGMENT PUBLIC 'DATA'
  4996.       EXTRN TUGRQQ:WORD
  4997.       DATA ENDS
  4998.  
  4999.  The above lines need not be added to assembly code if calls are made to the
  5000.  library transcendental intrinsics. In addition to the above precaution,
  5001.  assembly language programs containing 8087 instructions and intending to
  5002.  use the emulator library must be assembled with the most recent version of
  5003.  the Microsoft Macro Assembler using the assembler's "/E" switch.
  5004.  
  5005.  
  5006.  10.5  MS-DOS 2.0 Issues
  5007.  
  5008.  This version of the Microsoft Pascal Compiler is essentially an MS-DOS 1.25
  5009.  compiler. This means that Microsoft Pascal and programs compiled by it,
  5010.  will run on both versions of MS-DOS, but cannot take advantage of MS-DOS
  5011.  2.0 features such as pathnames.
  5012.  
  5013.  However, if you know that your program (not compiler) will only be required
  5014.  to run under MS-DOS 2.0, you can link with the special version of the
  5015.  Pascal file system, DOS2PAS.LIB, which contains the interface to the MS-DOS
  5016.  2.0 file system. The modules contained in DOS2PAS.LIB provide the interface
  5017.  described in Section 10.2, "An Overview of the File System," of this
  5018.  User's Guide.
  5019.  
  5020.  
  5021.  10.5.1  Interface to MS-DOS 2.0 File System
  5022.  
  5023.  However, an additional interface is provided to allow the MS-DOS 2.0
  5024.  "handle" of a Pascal file to be obtained. (A handle is an integer value
  5025.  recognized by the operating system as representing a file.) The
  5026.  function:
  5027.  
  5028.       FUNCTION HDLUQQ(VAR F : FCBFQQ) : INTEGER;
  5029.  
  5030.  returns the MS-DOS 2.0 file handle for a Pascal file. Consult the
  5031.  Microsoft Pascal Reference Manual, Sections 8.6, "File I/0: Extend Level,"
  5032.  and 8.7, "File I/O: System Level," and the version specific interface unit,
  5033.  FINKXM, on your disk for the definition of FCBFQQ.
  5034.  
  5035.  Programs linked with DOS2PAS.LIB, will give the runtime message
  5036.  
  5037.      Incorrect DOS version
  5038.  
  5039.  when run on earlier versions of MS-DOS.
  5040.  
  5041.  
  5042.  10.5.2  Exit Status Available to MS-DOS 2.0
  5043.  
  5044.  The compiler supplies an exit status to MS-DOS 2.0 that can be accessed via
  5045.  the "IF ERRORLEVEL n" batch command. The values returned by the compiler
  5046.  are:
  5047.  
  5048.       n Value          Meaning
  5049.       ──────────────────────────────────────────────────────────────────────
  5050.       0                No warnings for errors issued
  5051.       2                Warnings were issued
  5052.       4                Fatal errors encountered
  5053.  
  5054.  The user can set the global word DOSEQQ (defined in module ENTX) to any
  5055.  error code desired. For example,
  5056.         PROGRAM FOO;
  5057.             VAR DOSEQQ [ EXTERN ]: WORD;
  5058.             BEGIN
  5059.               {Set DOSEQQ to 0, i.e., No errors encountered.}
  5060.           DOSEQQ := 0;
  5061.           END.
  5062.  
  5063.  The value of DOSEQQ is passed to MS-DOS and this becomes the argument to
  5064.  ERRORLEVEL.
  5065.  
  5066.  
  5067.  
  5068.  Appendices
  5069.  
  5070.  ───────────────────────────────────────────────────────────────────────────
  5071.  
  5072.  A  Differences Between Versions 3.2 and 3.3
  5073.  B  Version Specifics
  5074.  C  Customizing i8087 Interrupts
  5075.  D  Exception Handling for 8087 Math
  5076.  E  Mixed-Language Programming
  5077.  F  Error Messages
  5078.  
  5079.  
  5080.  
  5081.  Appendix A  Differences Between Versions 3.2 and 3.3
  5082.  
  5083.  ───────────────────────────────────────────────────────────────────────────
  5084.  
  5085.  A.1  Using ADS and ADR With Expressions
  5086.  
  5087.  A.2  Addressing Procedures and Functions (ADSPROC and ADSFUNC)
  5088.  
  5089.  A.3  File Sharing
  5090.  
  5091.        A.3.1  Sharemodes
  5092.  
  5093.        A.3.2  Accessmodes
  5094.  
  5095.  A.4  File Locking
  5096.  
  5097.  A.5  Using the C "int" Type (INTEGERC)
  5098.  
  5099.  A.6  Using C Calling Conventions (C attribute)
  5100.  
  5101.  A.7  Using a Variable Number of Arguments (VARYING attribute)
  5102.  
  5103.  A.8  Compatibility with Version 3.2
  5104.  
  5105.  A.9  Creating Link Map Files With Microsoft LIB
  5106.  
  5107.  A.10 Changes to the Linker
  5108.  
  5109.         A.10.1  Setting the Maximum Number of Segments
  5110.  
  5111.         A.10.2  Using DOS Segment Order
  5112.  
  5113.  A.11 Modifying Executable Files With EXEPACK and EXEMOD
  5114.  
  5115.         A.11.1  The EXEPACK Utility
  5116.  
  5117.         A.11.2  The EXEMOD Utility
  5118.  
  5119.  A.12 The Microsoft Pascal Memory Model
  5120.  
  5121.  
  5122.  
  5123.  A.1  Using ADS and ADR With Expressions
  5124.  
  5125.  The ADS operator gives the full address (segment selector and offset) of
  5126.  the object to which it is applied. ADR gives the offset only. Version 3.2
  5127.  used an incorrect interpretation of precedence when these operators were
  5128.  used to address expressions. Version 3.3 uses the correct interpretation,
  5129.  which is described in the Microsoft Pascal Reference Manual. The ADS and
  5130.  ADR operators are of the same precedence as the NOT operator, and are of
  5131.  higher precedence than the other Pascal operators.
  5132.  
  5133.  If you have existing programs that use the incorrect precedence used in
  5134.  version 3.2, you must correct those programs if you want to compile them
  5135.  with version 3.3. For example, in version 3.3,
  5136.  
  5137.  ADS a + b
  5138.  
  5139.  is interpreted as
  5140.  
  5141.  (ADS a) + b
  5142.  
  5143.  (because the ADS operator is of higher precedence than the + operator) and
  5144.  will not compile. You cannot add b to the address of a.
  5145.  
  5146.  Version 3.2 interpreted
  5147.  
  5148.  ADS a + b
  5149.  
  5150.  as
  5151.  
  5152.  ADS (a + b)
  5153.  
  5154.  (incorrectly giving the addition operator higher precedence) which does
  5155.  compile. You can take the address of (a + b).
  5156.  
  5157.  If you have existing programs that take the address of an expression
  5158.  with either ADS or ADR, your program may not compile with version 3.3 of
  5159.  the Microsoft Pascal Compiler. If so, put parentheses around those
  5160.  expressions.
  5161.  
  5162.  The expressions
  5163.  
  5164.  ADS a
  5165.  
  5166.  and
  5167.  
  5168.  ADS (a)
  5169.  
  5170.  where a is a function, represent different values. The first expression
  5171.  evaluates to the address of the function (see the new predefined type
  5172.  ADSFUNC in Section A.2), and the second evaluates to the address of the
  5173.  result of the expression (the address of the value returned when a is
  5174.  called).
  5175.  
  5176.  
  5177.  A.2  Addressing Procedures and Functions (ADSPROC and ADSFUNC)
  5178.  
  5179.  The ADS operator can now be applied to procedures and functions, as well as
  5180.  to variables. When ADS is applied to a procedure, it produces a value of
  5181.  the predefined type ADSPROC. When it is applied to a function, it produces
  5182.  a value of the predefined type ADSFUNC. ADSPROC and ADSFUNC are similar in
  5183.  concept to ADSMEM.
  5184.  
  5185.  ADSPROC and ADSFUNC can be used to declare variables or formal
  5186.  parameters. To call a procedure or function with these variables or
  5187.  parameters, you must pass their value to an external, non-Pascal routine
  5188.  and then call that routine. Note that ADSPROC and ADSFUNC are compatible
  5189.  with C function pointers; Pascal procedure parameters are not.
  5190.  
  5191.  As with other address types, there is no type checking on assignments to
  5192.  ADSPROC or ADSFUNC. The compiler does not make sure that a function or
  5193.  procedure is being assigned or that the formal parameters are appropriate.
  5194.  You can also freely assign to and from other address types.
  5195.  
  5196.  
  5197.  Example
  5198.  
  5199.  This example could be used to communicate with a C routine that calls
  5200.  the routine af, then calls the routine ap with the result.
  5201.  
  5202.  program p(output);
  5203.  
  5204.  procedure cproc (ap: adsproc; af: adsfunc) [c] extern;
  5205.  
  5206.  procedure pproc (i: integer);
  5207.  begin
  5208.    writeln('C integer =', i);
  5209.  end;
  5210.  
  5211.  function pfunc :integer;
  5212.  var
  5213.    i: integer;
  5214.  begin
  5215.    readln (i);
  5216.    pfunc := i;
  5217.  end;
  5218.  
  5219.  begin
  5220.    cproc (pproc, pfunc);
  5221.  end.
  5222.  
  5223.  
  5224.  A.3  File Sharing
  5225.  
  5226.  In systems that use networking, more than one program can attempt to access
  5227.  the same file at the same time. Two new fields in the file control block,
  5228.  share and access, allow you to control access to files. These fields have
  5229.  the new predefined enumerated types sharemodes and accessmodes,
  5230.  respectively. The value of access determines how the first process to open
  5231.  a file can use that file. You can choose to be able to read the file, write
  5232.  to the file, or do both. The value of share determines how subsequent
  5233.  processes are allowed to access the file (while that file is still open).
  5234.  You can choose to allow subsequent processes to read the file, write to the
  5235.  file, do both, or do neither. You can also choose not to allow any
  5236.  processes, including the process which originally opened the file, to open
  5237.  the file (while the file is still open).
  5238.  
  5239.  
  5240.  A.3.1  Sharemodes
  5241.  
  5242.  To control how other processes may access a file that you are opening, set
  5243.  the share field in the file control block. This field has the new
  5244.  predefined enumerated type sharemodes. For example
  5245.  
  5246.   .
  5247.   .
  5248.  share:sharemodes
  5249.   .
  5250.   .
  5251.  
  5252.  The sharemodes type is defined as follows:
  5253.  
  5254.  TYPE
  5255.     sharemodes = (sm_COMPAT, {compatibility mode}
  5256.                   sm_DENYRW, {deny read/write mode}
  5257.                   sm_DENYWR, {deny write mode}
  5258.                   sm_DENYRD, {deny read mode }
  5259.                   sm_DENYNONE{deny none mode}
  5260.                  );
  5261.  
  5262.  The sharemode values are
  5263.  
  5264.    sm_COMPAT              Compatibility mode
  5265.  
  5266.                           This is the default.
  5267.  
  5268.                           When a file is open in compatibility mode, the
  5269.                           original USER (the process that opened the file)
  5270.                           may open the file in compatibility mode any number
  5271.                           of times. No other USER may open the file.
  5272.  
  5273.                           A file that is already open in a mode other than
  5274.                           compatibility mode cannot be opened in
  5275.                           compatibility mode.
  5276.  
  5277.    sm_DENYRW              Deny read/write mode
  5278.  
  5279.                           While a file is open in deny read/write mode, no
  5280.                           process may open the file.
  5281.  
  5282.    sm_DENYWR              Deny write mode
  5283.  
  5284.                           While a file is open in deny write mode, no
  5285.                           process may open the file with write access.
  5286.                           Other processes can open the file with read
  5287.                           access.
  5288.  
  5289.    sm_DENYRD              Deny read mode
  5290.  
  5291.                           While a file is open in deny read mode, no process
  5292.                           may open the file with read access. Other
  5293.                           processes can open the file with write access.
  5294.  
  5295.    sm_DENYNONE            Deny none mode.
  5296.  
  5297.                           While a file is open in deny none mode, any
  5298.                           process may open the file in any mode (except
  5299.                           compatibility mode).
  5300.  
  5301.  As with filename assignments, the share value must be set before the
  5302.  file is opened with reset or rewrite. For example,
  5303.  
  5304.  var
  5305.  f:text;
  5306.   .
  5307.   .
  5308.   .
  5309.   .
  5310.  f.share:=sm_COMPAT;
  5311.  assign(f.......);
  5312.  reset(f);
  5313.  
  5314.  If you change share, you must reset or rewrite the file before accessing
  5315.  the file again.
  5316.  
  5317.  
  5318.  A.3.2  Accessmodes
  5319.  
  5320.  The predefined type accessmode specifies the type of access the original
  5321.  process (the process that initially opened the file) will be making to a
  5322.  file. You specify accessmode by setting the value of the access field in
  5323.  the file variable.
  5324.  
  5325.  Accessmode is defined as
  5326.  
  5327.  TYPE
  5328.  accessmode=(am_read,am_write,am_readwrite)
  5329.  
  5330.  The accessmode values are
  5331.  
  5332.    am_read                The process can read the file.
  5333.  
  5334.    am_write               The process can write to the file.
  5335.  
  5336.    am_readwrite           The process can read and write to the file.
  5337.  
  5338.  The following example opens a file with share equal to sm_DENYRW and
  5339.  access equal to readwrite:
  5340.  
  5341.  var f: text;
  5342.  .
  5343.  .
  5344.  .
  5345.  f.share := sm_DENYRW;
  5346.  f.access := am_readwrite;
  5347.  assign(f,.....);
  5348.  rewrite(f);
  5349.  .
  5350.  .
  5351.  .
  5352.  
  5353.  If you open a file without assigning to access, the Pascal runtime system
  5354.  always attempts to open with an access value of am_readwrite. If the open
  5355.  fails, the runtime system will try to open the file again, first using
  5356.  am_write, then using am_read. Note that this is not the same as specifying
  5357.  access=am_readwrite. If you specify access=am_readwrite, and the file
  5358.  cannot be opened with both read and write access, the open will fail. The
  5359.  default behavior is most flexible.
  5360.  
  5361.  While am_readwrite is an appropriate default for single program
  5362.  environments, it is not always the best choice if a file will be shared.
  5363.  For example, suppose several processes want to read a file, and ensure that
  5364.  no process updates the file while they are reading it. The first process
  5365.  can open the file with share=sm_denywr, and default to access=am_readwrite.
  5366.  The share value will prevent other processes from writing to the file, and
  5367.  the access value will allow the first process to read the file. But no
  5368.  other process will be able to open that file with share=sm_denywr because
  5369.  the original process has access to writing to the file. However, if the
  5370.  first process opens the file with share=sm_denywr, and access=am_read, any
  5371.  number of processes may also open the file with share=sm_denywr and
  5372.  access=am_read.
  5373.  
  5374.  Table A.1 indicates the restrictions placed on opening a file that has
  5375.  already been opened with a particular value of share and access:
  5376.  
  5377.  
  5378.  Table A.1
  5379.  Share and Access Values
  5380. ╓┌──────────────────────────────────────┌────────────────────────────────────╖
  5381.  A File Opened With These               Can Subsequently be Opened
  5382.  Values of share and access:            (by any process, unless noted)
  5383.                                         With These Values of share
  5384.                                         and access:
  5385.  share =          access =              share =            access =
  5386.  ───────────────────────────────────────────────────────────────────────────
  5387.  sm_COMPAT        am_readwrite          sm_COMPAT        am_readwrite
  5388.                   am_read               by original      am_read
  5389.                   am_write              process only     am_write
  5390.  
  5391.  sm_DENYRW        am_readwrite          cannot be subsequently opened
  5392.                   am_read
  5393.                   am_write
  5394.  
  5395.  sm_DENYWR        am_readwrite          sm_DENYNONE        am_read
  5396.                   am_read               sm_DENYNONE        am_read
  5397.                                         sm_DENYWR
  5398.                   am_write              sm_DENYNONE        am_read
  5399.  A File Opened With These               Can Subsequently be Opened
  5400.  Values of share and access:            (by any process, unless noted)
  5401.                                         With These Values of share
  5402.                                         and access:
  5403.  share =          access =              share =            access =
  5404.                  am_write              sm_DENYNONE        am_read
  5405.                                         sm_DENYRD
  5406.  
  5407.  sm_DENYRD        am_readwrite          sm_DENYNONE        am_write
  5408.                   am_read               sm_DENYNONE        am_write
  5409.                                         sm_DENYWR
  5410.                   am_write              sm_DENYNONE        am_write
  5411.                                         sm_DENYRD
  5412.  
  5413.  sm_DENYNONE      am_readwrite          sm_DENYNONE        am_readwrite
  5414.                                                            am_read
  5415.                                                            am_write
  5416.                   am_read               sm_DENYNONE        am_readwrite
  5417.                                         sm_DENYWR          am_read
  5418.                                                            am_write
  5419.                   am_write              sm_DENYNONE        am_readwrite
  5420.  A File Opened With These               Can Subsequently be Opened
  5421.  Values of share and access:            (by any process, unless noted)
  5422.                                         With These Values of share
  5423.                                         and access:
  5424.  share =          access =              share =            access =
  5425.                  am_write              sm_DENYNONE        am_readwrite
  5426.                                         sm_DENYRD          am_read
  5427.                                                            am_write
  5428.  
  5429.  If, for example, a file is opened with share = sm_DENYWR and access =
  5430.  am_READ, that file can also be opened with share equal to either
  5431.  sm_DENYNONE or sm_DENYWR, and access equal to am_WRITE.
  5432.  
  5433.  
  5434.  A.4  File Locking
  5435.  
  5436.  A new procedure and ordinal type have been defined that allow you to lock a
  5437.  specific range of records in a DIRECT mode file, preventing access by other
  5438.  processes in a networked system. The procedure locking is defined as
  5439.  
  5440.  PROCEDURE locking (VAR f: FCBFQQ;
  5441.      MODE: lockmodes; M,N: INTEGER4);
  5442.  
  5443.  The parameters are
  5444.  
  5445.    M                An integer expression that is the number of the first
  5446.                     record to be locked. If M is zero (0), the next record
  5447.                     (the one which a sequential read, such as GET, would
  5448.                     read) will be locked.
  5449.  
  5450.    N                An integer expression that is the number of records to
  5451.                     be locked. If N is zero (0), one record is locked.
  5452.  
  5453.  The type lockmodes is defined as
  5454.  
  5455.  TYPE
  5456.    lockmodes = (lm_unlck, lm_lock, lm_nblck, lm_rlck, lm_nbrlck);
  5457.  
  5458.  The acceptable values of lockmodes are
  5459.  
  5460.    lm_nblck         Non-blocking lock
  5461.  
  5462.                     Lock the specified region (N records, starting at record
  5463.                     M). If any is already locked by a different process,
  5464.                     give an error. This is the default.
  5465.  
  5466.    lm_unlck         Unlock
  5467.  
  5468.                     Unlock the specified region (N records, starting at
  5469.                     record M)
  5470.  
  5471.    lm_lock          Lock
  5472.  
  5473.                     Lock the specified region (N records, starting at record
  5474.                     M). Wait for any part of the region locked by a
  5475.                     different process to become available.
  5476.  
  5477.    lm_rlck          Read lock
  5478.  
  5479.                     Same as lm_lock, except locks for write access only.
  5480.  
  5481.    lm_nbrlck        Non-blocking read lock.
  5482.  
  5483.                     Same as lm_nblck, except locks for write access only.
  5484.  
  5485.  The following example opens a DIRECT access file with share equal to
  5486.  sm_DENYNONE, locks two records starting at record 1, then unlocks them:
  5487.  
  5488.  type info=record...end;
  5489.  var f: file of info;
  5490.  f.mode:=DIRECT;
  5491.  f.share:=sm_DENYNONE;
  5492.  assign(f,...);
  5493.  reset(f);
  5494.  locking(f,lm_lock,1,2);
  5495.  get(f);
  5496.  locking(f,lm_unlck,1,2);
  5497.   .
  5498.   .
  5499.   .
  5500.  
  5501.  
  5502.  A.5  Using the C "int" Type (INTEGERC)
  5503.  
  5504.  Microsoft Pascal Version 3.3 supports a predefined type called INTEGERC.
  5505.  For a given processor and operating system, variables with the type
  5506.  INTEGERC are equivalent to variables with the C "int" type as defined by
  5507.  the Microsoft C Compiler for the same system. For the 8086 family of
  5508.  microprocessors, INTEGERC is equivalent to INTEGER2.
  5509.  
  5510.  
  5511.  A.6  Using C Calling Conventions (C attribute)
  5512.  
  5513.  You can use Microsoft C calling and external naming conventions for a
  5514.  particular procedure by specifying the C attribute in the procedure
  5515.  declaration. It has the same syntax as the PUBLIC attribute. For example,
  5516.  in the statement
  5517.  
  5518.  PROCEDURE myproc [public,c];
  5519.  
  5520.  myproc is a public procedure that uses C calling conventions. Calling
  5521.  conventions are discussed in Appendix E, "Mixed-Language Programming."
  5522.  
  5523.  
  5524.  A.7  Using a Variable Number of Arguments (VARYING attribute)
  5525.  
  5526.  VARYING can be specified with the C attribute. It means that the number of
  5527.  actual arguments may be different from the number of formal arguments.
  5528.  Actual arguments for which a formal argument is defined must follow the
  5529.  type rules. Actual arguments for which there are no formal arguments
  5530.  defined are assumed to be passed by value, with no type coercions. Note
  5531.  that a subprogram written in Pascal can only access arguments that are
  5532.  formally defined, so the latter case does not apply.
  5533.  
  5534.  When writing a Pascal procedure with the VARYING attribute, make sure
  5535.  your code does not execute references to arguments that are not passed in
  5536.  the call, or you will get undefined results. This usually means that you
  5537.  must tell the procedure which arguments were passed (usually by making one
  5538.  of the arguments describe the others).
  5539.  
  5540.  Note that the FORTRAN/Pascal calling sequence cannot support varying
  5541.  numbers of arguments; this attribute will not work unless you have also
  5542.  specified the C attribute on the subprogram.
  5543.  
  5544.  
  5545.  A.8  Compatibility with Version 3.2
  5546.  
  5547.  Apart from the changes identified in the previous sections, programs that
  5548.  compiled correctly with version 3.2 should compile correctly with version
  5549.  3.3.
  5550.  
  5551.  Object modules compiled with versions 3.2 and 3.3 can be linked
  5552.  together. However, your main program should be compiled with version 3.3.
  5553.  If you have existing assembly-language source files that rearrange memory
  5554.  from the default, they may have to be modified because the memory model has
  5555.  been changed. Refer to Section A.12, "The Microsoft Pascal Memory Model,"
  5556.  for information on assembly-language programs.
  5557.  
  5558.  The only change in the way the compiler is invoked is that file names
  5559.  are no longer changed to uppercase before being passed to the operating
  5560.  system. This has no effect on the behavior of the compiler because MS-DOS
  5561.  is not case sensitive.
  5562.  
  5563.  If your source files are very large, this version may no longer compile
  5564.  them. The compiler now uses a fixed stack internally, and highly nested
  5565.  recursions (such as unusually long expressions) may cause stack overflow.
  5566.  The fixed stack also reduces the amount of memory available to contain
  5567.  symbol table entries. However, the Pascal compiler makes more efficient
  5568.  use of memory for symbol tables than did Version 3.2.
  5569.  
  5570.  The memory allocation is preset to 6144 (6k) bytes. You can use the
  5571.  utility EXEMOD, as described in Section A.11.2, "The EXEMOD Utility," to
  5572.  change the allocation.
  5573.  
  5574.  The intermediate files produced by the first two passes of the compiler
  5575.  (PASIBF.BIN, PASIBF.SYM, PASIBF.TMP, and PASIBF.OID) are about one third
  5576.  the size of those produced by version 3.2.
  5577.  
  5578.  
  5579.  A.9  Creating Link Map Files With Microsoft LIB
  5580.  
  5581.  Now that Microsoft LIB is included with Microsoft Pascal, you can create
  5582.  link map files. Therefore, the .MAP files for each library are no longer
  5583.  included. To create a .MAP file, follow these steps:
  5584.  
  5585.      1.  Enter
  5586.  
  5587.          LIB
  5588.  
  5589.      2.  You receive the "Library name:" prompt. Enter the name of the
  5590.          library (PASCAL, MATH, 8087, DECMATH, or ALTMATH).
  5591.  
  5592.      3.  You then receive the "Operations:" prompt. Press return.
  5593.  
  5594.      4.  You receive the "List file:" prompt. Enter the name of the library,
  5595.          followed by the extension.
  5596.  
  5597.  For example, to create a .MAP file for the MATH library, you would use a
  5598.  procedure of the following type:
  5599.  
  5600.  LIB
  5601.  Library name: MATH
  5602.  Operations:
  5603.  Listing file: MATH.MAP
  5604.  
  5605.  You can create the same file (MATH.MAP) by entering the command line
  5606.  
  5607.  LIB MATH,MATH.MAP
  5608.  
  5609.  
  5610.  A.10  Changes to the Linker
  5611.  
  5612.  Version 3.3 of Microsoft Pascal comes with a new version of LINK: Version
  5613.  3.01. Version 3.01 has two new switches which allow you to set the maximum
  5614.  number of segments and use the DOS segment ordering convention. Sections
  5615.  A.10.1 and A.10.2 explain these new switches.
  5616.  
  5617.  Also, the default for the overlay interrupt number has been changed
  5618.  from CD to 3F.
  5619.  
  5620.  
  5621.  A.10.1  Setting the Maximum Number of Segments
  5622.  
  5623.  
  5624.  Syntax
  5625.  
  5626.  /SEGMENTS: number
  5627.  
  5628.  The /SEGMENTS option directs LINK to process no more than number
  5629.  segments per program. LINK displays an error message and stops if it
  5630.  encounters more than the given limit. The option is used to override the
  5631.  default limit of 128 segments.
  5632.  
  5633.  The number can be any integer value in the range 1 to 1024. It must be
  5634.  a decimal, octal, or hexadecimal number. Octal numbers must have a leading
  5635.  zero. Hexadecimal numbers must start with 0x.
  5636.  
  5637.  If /SEGMENTS is not given, LINK allocates enough memory space to
  5638.  process up to 128 segments. If a program has more than 128 segments, set
  5639.  the segment limit higher to increase the number of segments LINK can
  5640.  process.
  5641.  
  5642.  Minimum abbreviation: /SE
  5643.  
  5644.  
  5645.  Example
  5646.  
  5647.  LINK file.obj/SE:10,file.exe,,;
  5648.  
  5649.  This example sets the segment limit to 10.
  5650.  
  5651.  LINK moda+modb,run/SEGMENTS:0xff,ab.map,;
  5652.  
  5653.  
  5654.  This example sets the segment limit to 255 (FFH).
  5655.  
  5656.  LINK startup+file,file/SE:030,,;
  5657.  
  5658.  This example sets the segment limit to 24 (30 octal).
  5659.  
  5660.  
  5661.  A.10.2  Using DOS Segment Order
  5662.  
  5663.  
  5664.  Syntax
  5665.  
  5666.  /DOSSEG
  5667.  
  5668.  The /DOSSEG option causes LINK to arrange all segments in the
  5669.  executable file according to the MS-DOS segment ordering convention.
  5670.  This convention has the following rules:
  5671.  
  5672.      1.  All segments having the class name, CODE, are placed at the
  5673.          beginning of the executable file.
  5674.  
  5675.      2.  Any segments that do not belong to the group named DGROUP are
  5676.          placed immediately after the CODE segments.
  5677.  
  5678.      3.  All segments belonging to DGROUP are placed at the end of the file.
  5679.  
  5680.  Minimum abbreviation: /DO
  5681.  
  5682.  
  5683.  Example
  5684.  
  5685.  LINK start+test/DOSSEG,test,,math+common
  5686.  
  5687.  This command causes LINK to create an executable file, named "file.exe,"
  5688.  whose segments are arranged according to the MS-DOS segment ordering
  5689.  convention. The segments in the object files "start.obj" and "test.obj,"
  5690.  and any segments copied from the libraries math.lib and common.lib are
  5691.  arranged in the order specified above.
  5692.  
  5693.  
  5694.  A.11  Modifying Executable Files With EXEPACK and EXEMOD
  5695.  
  5696.  The EXEPACK and EXEMOD utilities (supplied with your compiler software)
  5697.  allow you to modify an executable program file. The EXEPACK utility
  5698.  "compresses" the executable file by removing sequences of null characters
  5699.  from the file and by optimizing the relocation table. Using EXEPACK, you
  5700.  can significantly reduce the size of the executable file and the time
  5701.  required for loading.
  5702.  
  5703.  The EXEMOD utility allows you to examine file header information, such
  5704.  as the size of the file and the number of relocation entries in the
  5705.  relocation table, and allows you to modify the initial stack pointer and
  5706.  maximum and minimum allocation values. The program assumes that you are
  5707.  familiar with the fields and format of the file header. See your Microsoft
  5708.  MS-DOS Programmer's Reference Manual for details.
  5709.  
  5710.  The following sections explain how to invoke and pass arguments to the
  5711.  EXEPACK and EXEMOD programs.
  5712.  
  5713.  
  5714.  A.11.1  The EXEPACK Utility
  5715.  
  5716.  
  5717.  Command
  5718.  
  5719.  EXEPACK executable-file output-file
  5720.  
  5721.  The output-file must have a different name than the executable-file.
  5722.  
  5723.  The EXEPACK utility reduces the size and loading time of an executable
  5724.  file by removing sequences of null characters from the given executable-
  5725.  file and optimizing the relocation table. The compressed file is written
  5726.  to the output file, and the original file is not modified.
  5727.  
  5728.  You can also use EXEPACK by specifying a new linker switch, /EXEPACK.
  5729.  
  5730.  Syntax
  5731.  
  5732.  /EXEPACK
  5733.  
  5734.  Specifying the /EXEPACK option has the same result as using the EXEPACK
  5735.  utility. The /EXEPACK option directs the linker to remove sequences of
  5736.  null bytes (00 hexadecimal) before the linker outputs an .EXE file.
  5737.  
  5738.  Minimum abbreviation: /E
  5739.  
  5740.  
  5741.  Example
  5742.  
  5743.  LINK file.obj/EXEPACK,file.exe,,;
  5744.  
  5745.  LINK file.obj,file.exe/E;
  5746.  
  5747.  LINK file/E;
  5748.  
  5749.  These examples all produce .EXE files (file.exe) with sequences of null
  5750.  bytes removed.
  5751.  
  5752.  The EXEPACK utility produces self-explanatory error messages if it is
  5753.  unable to compress the given file. For a listing of these messages, see
  5754.  Appendix F, "Error Messages."
  5755.  
  5756.  
  5757.  A.11.2  The EXEMOD Utility
  5758.  
  5759.  
  5760.  Command
  5761.  
  5762.  EXEMOD executable-file \z [/stack n] [/min n] [/max n]
  5763.  
  5764.  The EXEMOD utility modifies fields in the header according to instructions
  5765.  given on the command line. To display the header fields without modifying
  5766.  them, give the executable-file without any options.
  5767.  
  5768.  The options are shown with the forward slash (/) option character, but
  5769.  a hyphen (-) may be used instead if you prefer. They can be given in
  5770.  either uppercase or lowercase. The options have the effects listed below.
  5771.  
  5772.  
  5773.    Option           Effect
  5774.    ─────────────────────────────────────────────────────────────────────────
  5775.    /stack n         Sets the initial SP (stack pointer) value to n, where n
  5776.                     is a hexadecimal value in bytes. The minimum allocation
  5777.                     value is adjusted upward if necessary. There is no
  5778.                     default for n.
  5779.  
  5780.    /min n           Sets the minimum allocation value to n, where n is a
  5781.                     hexadecimal value in paragraphs. The actual value set
  5782.                     may be different from the requested value if adjustments
  5783.                     are necessary to accommodate the stack. There is no
  5784.                     default for n.
  5785.  
  5786.    /max n           Sets the maximum allocation to n, where n is a
  5787.                     hexadecimal value in paragraphs. The maximum allocation
  5788.                     value must be greater than or equal to the minimum
  5789.                     allocation value. There is no default for n.
  5790.  
  5791.  Notice that the modifications you can make with the /stack and /max
  5792.  options can also be made by relinking the program with the corresponding
  5793.  linker options (/STACK and /CPARMAXALLOC). The advantage of the EXEMOD
  5794.  utility is that it modifies the executable file directly, without requiring
  5795.  the program to be relinked.
  5796.  
  5797.  The EXEMOD program produces self-explanatory error messages when it is
  5798.  unable to carry out the given instructions. For a listing of these
  5799.  messages, see Appendix F, "Error Messages."
  5800.  
  5801.  ───────────────────────────────────────────────────────────────────────────
  5802.  Warning
  5803.     The /stack option can only be used on programs compiled with the
  5804.     Microsoft C Compiler Version 3.0 or later, the Microsoft Pascal Compiler
  5805.     Version 3.3 or later, or the Microsoft FORTRAN Compiler Version 3.3 or
  5806.     later. Use of the /stack option with other programs may cause the
  5807.     program to fail.
  5808.  ───────────────────────────────────────────────────────────────────────────
  5809.  
  5810.  
  5811.  A.12  The Microsoft Pascal Memory Model
  5812.  
  5813.  The memory model has been changed for version 3.3. If you use assembly
  5814.  language with Microsoft Pascal, you may have to modify your code.
  5815.  
  5816.  The following illustration shows a summary of the memory model.
  5817.  
  5818.  
  5819.              Logical Segment   Name      Class
  5820.           ┌──────────────────┬─────────┬──────────┐
  5821.           │  Code Segments   │         │          │  low addresses
  5822.           │  (may be many    │ module  │ CODE     │       
  5823.           │  physical        ├─────────┼──────────┤       │
  5824.           │  segments)       │ C_ETEXT │ ENDCODE  │       │
  5825.           ├──────────────────┼─────────┼──────────┤       │
  5826.           │  Far Data        │         │ FAR_DATA │       │
  5827.           │  Segments (may   │ ──FDATA │          │
  5828.           │  be many         │         │ │        │
  5829.           │  physical        ├─────────┼──────────┤       │
  5830.           │  segments        │ __FBSS  │ FAR_BSS  │       │
  5831.           ├──────────────────┼─────────┼──────────┤       │
  5832.           │  DGROUP Segment  │ NULL    │ BEGDATA  │       │
  5833.           │  (one physical   ├─────────┼──────────┤       │
  5834.           │  segment, with   │ _DATA   │ DATA     │       │
  5835.           │  increasing      ├─────────┼──────────┤       │
  5836.           │  offsets)        │ CONST   │ CONST    │       │
  5837.           │                  ├─────────┼──────────┤       │
  5838.           │                  │ _BSS    │ BSS      │       │
  5839.           │                  ├─────────┼──────────┤       
  5840.           │                  │ STACK   │  STACK   │  high addresses
  5841.           └──────────────────┴─────────┴──────────┘
  5842.  
  5843.  
  5844.  User programs can declare any additional segments they need, as long as
  5845.  they use the class names defined here to ensure they are loaded in the
  5846.  proper place in memory. (Only advanced users will ever need to do this.)
  5847.  The compiler often generates additional segments of the classes defined
  5848.  here for its own purposes.
  5849.  
  5850.  The following example is a Pascal routine that calls a routine written
  5851.  in assembly language for the 8086. The assembly-language routine adds real
  5852.  numbers. Note that to assemble this example, you need the Microsoft Macro
  5853.  Assembler version 1.25 or higher. This example should be assembled with the
  5854.  /E switch, which directs the assembler to generate 8087/80287 instructions
  5855.  that are compatible with the emulator. If you have version 3.0 or later
  5856.  of the Microsoft Macro Assembler, you should also specify the /MX switch,
  5857.  which tells the assembler to preserve lower case letters in public and
  5858.  external symbols when the object file is written.
  5859.  
  5860.  Assume the following Pascal program has been compiled:
  5861.  
  5862.  PROGRAM example2(input, output);
  5863.  VAR
  5864.          r: REAL;
  5865.          total: REAL;
  5866.  FUNCTION RADD (a,b: REAL): REAL;
  5867.          EXTERN;
  5868.  BEGIN
  5869.          r := 10.0;
  5870.          total := RADD(15.0,r);
  5871.          WRITELN(total)
  5872.  END.
  5873.  
  5874.  Note that R and the constant 15.0 will be passed by value. At runtime,
  5875.  just before the transfer to the function RADD, the stack would be in the
  5876.  following form (each box contains one byte):
  5877.  
  5878.  
  5879.               ┌─────────────────────────┐
  5880.               │  Most Significant Byte  │▒
  5881.               ├─────────────────────────┤▒
  5882.               │                         │▒ Argument 1 =
  5883.               ├─────────────────────────┤▒ constant 15.0
  5884.               │                         │▒
  5885.               ├─────────────────────────┤▒
  5886.               │  Least Significant Byte │▒
  5887.               ├─────────────────────────┤
  5888.               │  Most Significant Byte  │▒
  5889.               ├─────────────────────────┤▒
  5890.               │                         │▒ Argument 2 =
  5891.               ├─────────────────────────┤▒ 10.0 (value of variable R)
  5892.               │                         │▒
  5893.               ├─────────────────────────┤▒
  5894.               │  Least Significant Byte │▒
  5895.               ├─────────────────────────┤
  5896.               │       Offset High       │▒ Argument 3 =
  5897.               ├─────────────────────────┤▒ address of function
  5898.               │       Offset Low        │▒ return value
  5899.               ├─────────────────────────┤
  5900.               │      Segment High       │▒
  5901.               ├─────────────────────────┤▒
  5902.               │      Segment Low        │▒
  5903.               ├─────────────────────────┤▒ Return address
  5904.               │       Offset High       │▒
  5905.               ├─────────────────────────┤▒
  5906.        SP ── │       Offset Low        │▒
  5907.               └─────────────────────────┘
  5908.                  Stack grows downward
  5909.  
  5910.  
  5911.  The following assembly-language subroutine implements the real add
  5912.  function, RADD. Notice that this example uses an in-line version of the
  5913.  entry code and exit code. The entry and exit sequences make sure that any
  5914.  virtual memory accessed in the frame of a routine is actually mapped to
  5915.  physical memory.
  5916.  
  5917.  The entry code also verifies that the runtime stack is large enough for the
  5918.  local variables needed by the routine.
  5919.  
  5920.  Note that the function return value is in the location specified by
  5921.  BP+6.
  5922.  
  5923.  Note also that whenever the return value for a function is returned in
  5924.  a temporary variable created by the caller (rather than in registers) AX
  5925.  must be set to the two-byte offset address of this temporary variable by
  5926.  the function before it returns to the caller. In the following example,
  5927.  this is done by the mov ax, di instruction just before the standard exit
  5928.  sequence:
  5929.  
  5930.  extrn __chkstk:far      ;
  5931.  
  5932.  _DATA     segment public 'DATA'
  5933.            ;if your routine needs static data, declare it here
  5934.  _DATA     ends
  5935.  
  5936.  DGROUP    group _DATA
  5937.  
  5938.  RADD_TEXT segment 'CODE'
  5939.  
  5940.            assume cs:RADD_TEXT,ds:DGROUP,ss:DGROUP
  5941.  
  5942.            public RADD
  5943.  RADD      proc far
  5944.  
  5945.            ; Begin standard entry sequence
  5946.            inc bp              ; mark stack frame as a "far call" frame
  5947.            push bp             ; save old frame pointer
  5948.            mov bp,sp           ; set up new frame pointer
  5949.            mov ax,0            ; set AX to tot. # bytes for local vars
  5950.            call __chkstk       ; reserve space on stack for local vars
  5951.            push di             ; save C register variables (si and di)
  5952.            push si
  5953.            ; End standard entry sequence
  5954.  
  5955.            fld dword ptr [bp+12]; push 1st param on 80287 stack
  5956.  
  5957.            fld dword ptr [bp+8]; push 2nd param on 80287 stack
  5958.  
  5959.            faddp st(1),st      ; add top two items on 80827 stack
  5960.  
  5961.            mov di,[bp+6]       ; di = addr of function return var
  5962.            fstp dword ptr [di] ; store result in func. ret. var
  5963.            fwait
  5964.            mov ax, di          ; return address of result variable
  5965.  
  5966.            ; Begin standard exit sequence
  5967.            pop si              ; restore C register variables
  5968.            pop di
  5969.            mov sp,bp           ; recover space used by local variables
  5970.            pop bp              ; restore old frame pointer
  5971.            dec bp              ; restore low bit (used as frame marker)
  5972.            ; End standard exit sequence
  5973.  
  5974.            ret 10              ; return and recover space in parameters
  5975.  
  5976.  RADD      endp
  5977.  
  5978.  RADD_TEXT ends
  5979.  
  5980.  end
  5981.  
  5982.  
  5983.  
  5984.  Appendix B  Version Specifics
  5985.  
  5986.  ───────────────────────────────────────────────────────────────────────────
  5987.  
  5988.  B.1  Implementation Additions
  5989.  
  5990.  B.2  Implementation Restrictions
  5991.  
  5992.  B.3  Unimplemented Features
  5993.  
  5994.  
  5995.  
  5996.  Microsoft Pascal has been implemented for a number of different
  5997.  microcomputer operating systems. This appendix describes the current
  5998.  implementation of the MS-Pascal language for MS-DOS. It discusses additions
  5999.  and restrictions to the language described in the current Microsoft Pascal
  6000.  Reference Manual, and identifies features of MS-Pascal that are not yet
  6001.  implemented.
  6002.  
  6003.  For changes and additions to the MS-Pascal Compiler or language that may
  6004.  have been made after publication of this User's Guide and companion
  6005.  reference manual, see the README.DOC file, if present, provided on disk
  6006.  with the system files.
  6007.  
  6008.  
  6009.  B.1  Implementation Additions
  6010.  
  6011.  The following additions have been made to the language described in the May
  6012.  1983 release of the Microsoft Pascal Reference Manual.
  6013.  
  6014.     1.  The following function can be declared EXTERN:
  6015.  
  6016.            FUNCTION DOSXQQ
  6017.               (COMMAND, PARAMETER: WORD): BYTE;
  6018.  
  6019.         This function invokes the operating system, passing a command in the
  6020.         AH register and an additional parameter in the DX register. The BYTE
  6021.         function return value is identical to the value returned by the
  6022.         operating system in AL, the accumulator.
  6023.  
  6024.         The PUBLIC variables CRCXQQ and CRDXQQ contain the values of the CX
  6025.         and DX registers after the call. The value of CRCXQQ is also loaded
  6026.         into CX before the call.
  6027.  
  6028.         Several operating system functions are particularly useful:
  6029.  
  6030.         a. DOSXQQ (1, 0);
  6031.  
  6032.            Returns the next character typed. If no character has been typed,
  6033.            DOSXQQ waits for input. The ASCII value of the typed character is
  6034.            returned, and the typed character is echoed on the terminal
  6035.            screen.
  6036.  
  6037.         b. DOSXQQ (2, WRD ('x'));
  6038.  
  6039.            Outputs the character 'x' to your terminal. The function return
  6040.            value should be ignored. The CONTROL-S and CONTROL-Q commands to
  6041.            stop and start scrolling, and the CONTROL-P command to toggle the
  6042.            printer, are executed if entered. Tabs are expanded.
  6043.  
  6044.         c. DOSXQQ (6, 255);
  6045.  
  6046.            Returns the next character typed on the keyboard, or zero, if no
  6047.            character has been typed. CONTROL-S, CONTROL-Q, and CONTROL-P are
  6048.            not treated specially. The character typed is not echoed on the
  6049.            terminal screen.
  6050.  
  6051.         d. DOSXQQ (6, WRD ('x'));
  6052.  
  6053.            Outputs the character 'x' to your terminal. This is the same as
  6054.            DOSXQQ (2, WRD ('x')), above, except that CONTROL-S, CONTROL-Q,
  6055.            and CONTROL-P are not treated specially. The function return
  6056.            value should be ignored in this case.
  6057.  
  6058.         e. DOSXQQ (11, 0);
  6059.  
  6060.            Returns screen status. The value 255 is returned if a character
  6061.            has been typed; a 0 is returned if a character has not been
  6062.            typed. This function is used to check for a keypress condition
  6063.            without actually reading the character.
  6064.  
  6065.         f. DOSXQQ (13, 0);
  6066.  
  6067.            This function is not necessary in MS-DOS, but is provided for
  6068.            compatibility with other operating systems (CP/M(R) and
  6069.            CP/M-86(R)), where this function resets disk tables.
  6070.  
  6071.     2.  The following MS-Pascal filenames are available to indicate devices:
  6072.  
  6073.         Name   Description       MS-DOS Code
  6074.         ────────────────────────────────────────────────────────────────────
  6075.         USER   Console           1, 2, and 6
  6076.         LINE   Auxiliary input   3, 4
  6077.  
  6078.         Special MS-DOS filenames, like CON and NUL, are also available (see
  6079.         your MS-DOS manual for details). However, using CON for the terminal
  6080.         causes buffering of input and output data and precludes
  6081.         interactive input and output. The filename USER should be used
  6082.         instead.
  6083.  
  6084.     3.  Program parameters are available. When a program starts, there is a
  6085.         prompt for every program parameter. You may also give program
  6086.         parameters on the command line with which you invoke the program. If
  6087.         a program requires more parameters than appear on the command line,
  6088.         the remaining parameters are prompted for.
  6089.  
  6090.         For example, assume that you want to execute the following program:
  6091.  
  6092.             PROGRAM DEMO (INFILE, OUTFILE, P1, P2, P3);
  6093.             VAR  INFILE, OUTFILE : TEXT;
  6094.                    P1, P2, P3   : INTEGER;
  6095.             BEGIN
  6096.               .
  6097.               .
  6098.             END.
  6099.  
  6100.         From the command line, you could run this program as follows:
  6101.  
  6102.             A:DEMO DATA1.FIL DATA2.FIL 7 8 123
  6103.  
  6104.         If you give only the first parameter on the command line, the
  6105.         compiler will proceed to prompt you as follows (your responses are
  6106.         shown in italics):
  6107.  
  6108.             A: DEMO DATA1.FIL
  6109.             OUTFILE: DATA2.FIL 7
  6110.             P2: 8
  6111.             P3: 123
  6112.  
  6113.         An LSTRING parameter value of NULL cannot be read from the command
  6114.         line and is assumed to be missing. You can enter it by pressing the
  6115.         RETURN key in response to the prompt.
  6116.  
  6117.     4. The PUBLIC variable CESXQQ, containing the segment register value
  6118.         for the start of the MS-DOS data area, is available. This allows you
  6119.         to reference the command line, as shown:
  6120.  
  6121.             VAR MSDATA : ADS OF LSTRING (80);
  6122.                 CESXQQ [EXTERN] : WORD;
  6123.             BEGIN
  6124.               MSDATA.S := CESXQQ; MSDATA.R := 128;
  6125.               {MSDATA^ now contains the command line.}
  6126.             END;
  6127.  
  6128.         The MS-DOS data area also contains, at offset 2, the upper memory
  6129.         limit, expressed as the segment (i.e., paragraph) address of the
  6130.         first byte after available memory. The lower memory segment address
  6131.         is simply 4K paragraphs (i.e., 64K bytes) above the default data
  6132.         segment. For example:
  6133.  
  6134.             VAR LOMADS, HIMADS, MSDATA: ADS OF WORD;
  6135.                 CESXQQ [EXTERN] : WORD;
  6136.             BEGIN
  6137.                LOMADS := ADS LOMADS;
  6138.                LOMADS.S := LOMADS.S + 4096;
  6139.                LOMADS.R := 0;
  6140.                {LOMADS is first available address.}
  6141.  
  6142.                MSDATA.S := CESXQQ; MSDATA.R := 2;
  6143.                HIMADS.S := MSDATA^; HIMADS.R := 0;
  6144.                {HIMADS is first unavailable address.}
  6145.             END;
  6146.  
  6147.     5.  TIME, TICS, and DATE are supported for MS-DOS systems with clocks.
  6148.         TICS returns hundredths of seconds.
  6149.  
  6150.     6.  Real number conversion utilities
  6151.  
  6152.         Releases of MS-Pascal starting with 3.0 use the IEEE real number
  6153.         format. Releases of MS-Pascal earlier than 3.0 used the Microsoft
  6154.         real number format. The two formats are not compatible. However, if
  6155.         you need to convert real numbers from one format to the other, you
  6156.         may do so with the following library routines:
  6157.  
  6158.         a. Single Precision Reals
  6159.  
  6160.            Microsoft to IEEE format
  6161.  
  6162.              PROCEDURE M2ISQQ (vars rms, rieee: real4)
  6163.  
  6164.            IEEE to Microsoft format
  6165.  
  6166.              PROCEDURE I2MSQQ (vars rieee, rms: real4)
  6167.  
  6168.            RMS and RIEEE are real numbers in Microsoft format and in
  6169.            IEEE format, respectively.
  6170.  
  6171.         b. Double Precision Reals
  6172.  
  6173.            Microsoft to IEEE format
  6174.  
  6175.              PROCEDURE M2IDQQ (vars dms , dieee: real8)
  6176.  
  6177.            IEEE to Microsoft format
  6178.  
  6179.              PROCEDURE I2MDQQ (vars dieee , dms: real8)
  6180.  
  6181.            DMS and DIEEE are real numbers in Microsoft format and in
  6182.            IEEE format, respectively.
  6183.  
  6184.     7.  Bankers' rounding is used when truncating real numbers that end with
  6185.         .5; that is, odd numbers are rounded up to an even integer, even
  6186.         numbers are rounded down to an even integer. For example:
  6187.  
  6188.            TRUNC(4.5) = 4
  6189.            TRUNC (207.5) = 208
  6190.  
  6191.  
  6192.  B.2  Implementation Restrictions
  6193.  
  6194.  The following restrictions apply to this implementation of MS-Pascal:
  6195.  
  6196.     1.  Identifiers can have up to 31 characters. Longer identifiers are
  6197.         truncated.
  6198.  
  6199.     2.  Numeric constants can have up to 31 characters. Like identifiers,
  6200.         numeric constants longer than 31 characters are truncated.
  6201.  
  6202.     3.  The PORT attribute for variables is identical to the ORIGIN
  6203.         attribute. It does not use I/O port addresses.
  6204.  
  6205.     4.  The maximum level to which procedures can be statically nested is
  6206.         15. Dynamic nesting of procedures is limited by the size of the
  6207.         stack.
  6208.  
  6209.     5.  The FORTRAN attribute does nothing. MS-Pascal and MS-FORTRAN share
  6210.         the same code generator and calling sequence. MS-FORTRAN parameters
  6211.         are always passed as MS-Pascal VARS parameters.
  6212.  
  6213.     6.  $simple currently turns off common subexpression optimization. $size
  6214.         and $speed turn it back on (and have no other effect).
  6215.  
  6216.  
  6217.  B.3  Unimplemented Features
  6218.  
  6219.  The following MS-Pascal features are not presently implemented, or are
  6220.  implemented only as discussed below:
  6221.  
  6222.     1.  OTHERWISE is not accepted in RECORD declarations.
  6223.  
  6224.     2.  Code is generated for PURE functions, but no checking is done.
  6225.  
  6226.     3.  The extend level operators SHL, SHR, and ISR are not available.
  6227.  
  6228.     4.  No checking is done for invalid GOTOs.
  6229.  
  6230.     5.  READ, READLN, and DECODE cannot have M and N parameters.
  6231.  
  6232.     6.  Enumerated I/O, permitting the reading and writing of enumerated
  6233.         constants as strings, is not available.
  6234.  
  6235.     7.  The metacommands $tagck, $standard, $extend, and $system can be
  6236.         given, but have no effect.
  6237.  
  6238.     8.  The $inconst metacommand does not accept string constants.
  6239.  
  6240.  
  6241.  
  6242.  Appendix C  Customizing i8087 Interrupts
  6243.  
  6244.  ───────────────────────────────────────────────────────────────────────────
  6245.  
  6246.  
  6247.  
  6248.  This appendix describes how to customize the i8087 interrupts on your
  6249.  computer system. Before proceeding, you should be familiar with the
  6250.  following:
  6251.  
  6252.     1.  the Intel publication, iAPX 86/20, 88/20 Numeric Supplement
  6253.  
  6254.     2.  MS-Macro, the Microsoft Macro Assembler
  6255.  
  6256.     3.  DEBUG, the MS-DOS debugger utility
  6257.  
  6258.  In addition, we recommend that you make backup copies of any of the disks
  6259.  you plan to modify.
  6260.  
  6261.  To change the way the runtime library processes interrupts, you must use
  6262.  the MS-DOS debugger DEBUG (or a similar utility). Although this utility is
  6263.  intended primarily for debugging assembly language programs, you can also
  6264.  use it to alter the binary contents of any file. You will use this second
  6265.  capability of DEBUG to customize 8087.LIB and MATH.LIB for a particular
  6266.  hardware configuration. 8087.LIB, the 8087 version of the runtime library,
  6267.  contains the following assembly language structure:
  6268.  
  6269.       i8087control STRUC
  6270.       LABX87          DB   '<8087>';48-bit tag
  6271.       EOIX87          DB   0       ;EOI instruction
  6272.       PRTX87          DB   0       ;i8259 port number
  6273.       SHRX87          DB   0       ;Shared interrupt device
  6274.       INTX87          DB   2       ;i8087 interrupt vector
  6275.       INTOFFSET       DW   0       ;
  6276.       i8087control ENDS
  6277.  
  6278.  This structure defines the default control values used by the runtime
  6279.  library to handle 8087 interrupts. Each of the elements of the structure is
  6280.  described briefly below:
  6281.  
  6282.     1.  LABX87
  6283.  
  6284.         A string label. LABX87 exists solely to locate the other structure
  6285.         fields in the executable binaries and libraries.
  6286.  
  6287.     2.  EOIX87
  6288.  
  6289.         The hexadecimal value of the i8259 "end of interrupt" instruction
  6290.         for a particular implementation. To the 8087 interrupt handler
  6291.         supplied by Microsoft, any nonzero value of this byte indicates the
  6292.         presence of an i8259 interrupt controller.
  6293.  
  6294.     3.  PRTX87
  6295.  
  6296.         The control port number associated with an i8259, if present.
  6297.  
  6298.     4.  SHRX87
  6299.  
  6300.         If nonzero, an indication that the i8087 shares its interrupt vector
  6301.         with another device. In such a case, when the 8087 interrupt handler
  6302.         supplied by Microsoft determines that an interrupt it receives is
  6303.         not an 8087 interrupt, it passes control to the other interrupt
  6304.         device.
  6305.  
  6306.     5.  INTX87
  6307.  
  6308.         The interrupt vector number to which the 8087 is connected.
  6309.  
  6310.  Depending on the setup of your computer system, any or all (or none) of the
  6311.  last four items may require changing. Specifically, you must alter this
  6312.  structure if your hardware configuration meets any of the following
  6313.  criteria:
  6314.  
  6315.     1.  It uses an 8087 interrupt vector number other than 2.
  6316.  
  6317.     2.  It uses an 8259 interrupt controller.
  6318.  
  6319.     3.  The 8087 shares interrupts with another device on the same vector.
  6320.  
  6321.  The example on the following pages demonstrates how to change all of the
  6322.  interrupt parameters on the 8087. In the example, the following specific
  6323.  changes are made:
  6324.  
  6325.     1.  The 8087 interrupt control block is altered to set EOIX87 to 255
  6326.         decimal, thus informing the software that an i8259 exists and that
  6327.         its EOI instruction is 255.
  6328.  
  6329.     2.  The i8259 should issue its EOI request through port number 254
  6330.         (PRTX87).
  6331.  
  6332.     3.  The nonzero value of SHRX87 indicates that the 8087 shares its
  6333.         interrupts with another device.
  6334.  
  6335.     4.  The interrupt vector number of the i8087 is changed to 4.
  6336.  
  6337.  These values are used merely for the purpose of this sample session.
  6338.  Consult your hardware manual for the values required for your computer
  6339.  system.
  6340.  
  6341.  For the sake of brevity and clarity, not all of the screen display
  6342.  issued by the debugger is shown in the example, only the parts that apply
  6343.  specifically to this procedure. Also, on most screens, the information
  6344.  shown in lines 4, 7, 8, and 10 will run to 80 columns on an 80-column
  6345.  screen.
  6346.  
  6347.  Numbers 1 through 13 at the left-hand margin of the sample session do not
  6348.  appear on the screen; rather, they refer to the corresponding numbered
  6349.  comments on the page following the sample session. See your MS-DOS manual
  6350.  for complete details on using DEBUG.
  6351.  
  6352.  Sample DEBUG Session to Customize i8087 Interrupts
  6353.  
  6354.     1.  >
  6355.  
  6356.     2.  >debug b:8087.lib
  6357.  
  6358.     3.  DEBUG-86  version 2.10
  6359.  
  6360.     4.  >r
  6361.         AX=0000  BX=0001  CX=B800  DX=0000
  6362.         SP=FFEE  BP=0000  SI=0000  DI=0000
  6363.         DS=0AF9  ES=0AF9  SS=0AF9  CS=0AF9
  6364.         IP=0100   NV UP DI PL NZ NA PO NC
  6365.         0AF9:0100 F0            LOCK
  6366.         0AF9:0101 FD            STD
  6367.  
  6368.     5.  >s ds:100 lefff '8087>'
  6369.  
  6370.     6.  0AF9:2370
  6371.  
  6372.     7.  >d af9:2370
  6373.         0AF9:2370  38 30 38 37 3E 00 00 00   8087>...
  6374.                    02 00 00 F8 A0 DF 00 02   ...x _..
  6375.  
  6376.     8.  >d af9:2375
  6377.         0AF9:2375  00 00 00-02 00 00 F8 A0   .....x
  6378.                    DF 00 02                  _..
  6379.  
  6380.     9.  >e af9:2375
  6381.         0AF9:2375 00.ff  00.fe  00.1
  6382.         0AF9:2378 02.4
  6383.  
  6384.     10. >d af9:2375
  6385.          0AF9:2375  FF FE 01-04 00 00 F8 A0   ......x
  6386.                     DF 00 02                  _..
  6387.  
  6388.     11. >w
  6389.  
  6390.     12. >q
  6391.  
  6392.     13. >
  6393.  
  6394.  
  6395.  Comments for Sample DEBUG Session
  6396.  
  6397.     1.  MS-DOS prompt.
  6398.  
  6399.     2.  Call DEBUG with 8087.LIB.
  6400.  
  6401.     3.  DEBUG utility prompt.
  6402.  
  6403.     4.  Instruct debugger to show 8086 registers.
  6404.  
  6405.     5.  Instruct debugger to search efff bytes beginning at DS:100 for the
  6406.         string '8087>'.
  6407.  
  6408.     6.  String found at 0AF9:2370.
  6409.  
  6410.     7.  Instruct debugger to display the string.
  6411.  
  6412.     8.  Advance to the beginning of the 'i8087control' structure.
  6413.  
  6414.     9.  Instruct the debugger to make the following alterations:
  6415.  
  6416.           EOIX87 to FF hex, 255 decimal
  6417.           PRTX87 to FE hex, 254 decimal
  6418.           SHRX87 to 1 hex
  6419.           INTX87 to 4
  6420.  
  6421.     10. Instruct the debugger to display any changes.
  6422.  
  6423.     11. Write any changes to the source file.
  6424.  
  6425.     12. Stop the debugger.
  6426.  
  6427.     13. MS-DOS prompt returns.
  6428.  
  6429.  
  6430.  
  6431.  Appendix D  Exception Handling For 8087 Math
  6432.  
  6433.  ───────────────────────────────────────────────────────────────────────────
  6434.  
  6435.  D.1  Processing Environment Control
  6436.  
  6437.        D.1.1  The STATUS Word
  6438.  
  6439.        D.1.2  The CONTROL Word
  6440.  
  6441.  D.2  Reading and Setting STATUS and CONTROL Values
  6442.  
  6443.  D.3  Formats for STATUS and CONTROL Words
  6444.  
  6445.  
  6446.  
  6447.  The five exceptions to floating-point arithmetic that are required by the
  6448.  IEEE standard are supported by the 8087 coprocessor and the real math
  6449.  support routines. Those which would result in a NAN ("Not A Number") error
  6450.  message when enabled, are enabled by default. The others are disabled.
  6451.  They are not affected by the $debug metacommand but are controlled by a
  6452.  STATUS word and a CONTROL word.
  6453.  
  6454.  The following list contains the five exceptions and their default and
  6455.  alternate actions:
  6456.  
  6457.     1.  Invalid Operation--Any operation with a NAN, square
  6458.         root(-1), 0*INF, etc.
  6459.  
  6460.         Default action:     Enabled, gives runtime error 2136
  6461.         Alternate action:   Disabled, returns a NAN
  6462.  
  6463.     2.  Divide by zero--r/0.0
  6464.  
  6465.         Default action:     Enabled, gives runtime error 2100
  6466.         Alternate action:   Disabled, returns a properly
  6467.                             signed INF (infinity)
  6468.  
  6469.     3.  Overflow--Operation results in a number greater than
  6470.         maximum representable number.
  6471.  
  6472.         Default action:     Enabled, gives runtime error 2101
  6473.         Alternate action:   Disabled, returns INF
  6474.  
  6475.     4.  Underflow--Operation results in a number smaller than
  6476.         smallest valid representable number.
  6477.  
  6478.         Default action:     Disabled, returns zero
  6479.         Alternate action:   Enabled, gives runtime error 2135
  6480.  
  6481.     5.  Precision--Occurs whenever a result is subject to
  6482.         rounding error.
  6483.  
  6484.         Default action:     Disabled, returns properly
  6485.                             rounded result
  6486.         Alternate action:   Enabled, gives runtime error 2139
  6487.  
  6488.  
  6489.  D.1  Processing Environment Control
  6490.  
  6491.  Two memory locations control the 8086 and the 8087 processors. These are
  6492.  called the STATUS word and CONTROL word. The effect of these memory
  6493.  locations is discussed in the following paragraphs.
  6494.  
  6495.  
  6496.  D.1.1  The STATUS Word
  6497.  
  6498.  When one of the exceptional conditions occurs, the appropriate bit in the
  6499.  STATUS word is set. This flag will remain set to indicate that the
  6500.  exception occurred until cleared by the user. If you set the bit in the
  6501.  CONTROL word relating to a given exception, that exception is masked and
  6502.  the operation proceeds with a supplied default. If the bit is unset, any
  6503.  exception of that type generates an error message, halts the operation, and
  6504.  your program will stop. In either case the exception is ORed into the
  6505.  STATUS word.
  6506.  
  6507.  
  6508.  D.1.2  The CONTROL Word
  6509.  
  6510.  In addition to masking exceptional conditions, the CONTROL word is also
  6511.  used to set modes for the internal arithmetic required by the IEEE
  6512.  standard. These are:
  6513.  
  6514.  
  6515.  Rounding Control
  6516.  
  6517.  Round to nearest (or even), Up, Down, or Chop
  6518.  
  6519.  
  6520.  Precision Control
  6521.  
  6522.  Determines at which bit of the mantissa rounding should take place (24, 53,
  6523.  or 64). Note all results are done to 64 bits regardless of the precision
  6524.  control. It only affects the rounding in the internal form. On storage
  6525.  any result is again rounded to the storage precision.
  6526.  
  6527.  
  6528.  Infinity Control
  6529.  
  6530.  Affine mode is the familar + and - INF style of arithmetic. Projective mode
  6531.  is a mode where + and - INF are considered to be the same number. The
  6532.  principal effect is to change the nature of comparisons. (Projective INF
  6533.  does not compare with anything but itself.)
  6534.  
  6535.  The CONTROL word defaults are currently:
  6536.  
  6537.     Infinity control = affine
  6538.     Rounding control = near
  6539.     Precision control = 64 bits
  6540.     Interrupt-enable mask = unmasked
  6541.     Precision mask = masked
  6542.     Underflow mask = masked
  6543.     Overflow mask = unmasked
  6544.     Zerodivide mask = unmasked
  6545.     Denormalized operand mask = unmasked
  6546.     Invalid operation mask = unmasked
  6547.  
  6548.  Special exception handling routines handle stack exceptions and denormal
  6549.  propagation. For these routines to work correctly, the 8087 CONTROL word
  6550.  and auxiliary variables need to be set up as done by LCWRQQ. Use LCWRQQ to
  6551.  revise the 8087 CONTROL word.
  6552.  
  6553.  ───────────────────────────────────────────────────────────────────────────
  6554.  Important
  6555.     Do not alter the 8087 CONTROL word with an FLDCW instruction  when using
  6556.     the 8087 with a Microsoft language.
  6557.  ───────────────────────────────────────────────────────────────────────────
  6558.  
  6559.  Since the denormal exception is not a part of the IEEE standard, LCWRQQ
  6560.  always alters the user's parameter word to unmask denormals and thus handle
  6561.  them with the Microsoft exception handler. The user cannot affect the
  6562.  handling of denormals with LCWRQQ.
  6563.  
  6564.  Since stack overflow and underflow are indicated by the 8087 with an
  6565.  invalid exception, the invalid exception bit is also always unmasked by
  6566.  LCWRQQ. However, when an invalid exception occurs and it is not stack
  6567.  overflow or underflow, then the invalid exception bit of the user's
  6568.  control word input to LCWRQQ controls the handling of the exception.
  6569.  
  6570.  The following list of control words defines the masking settings for the
  6571.  overflow, zerodivide, and invalid operation exceptions that are associated
  6572.  with several optional control words. Control word 4914 specifies the
  6573.  default masking settings that are customary during 8087 operations.
  6574.  
  6575.  
  6576.  Control word      Overflow  Zerodivide  Invalid
  6577.  ───────────────────────────────────────────────────────────────────────────
  6578.  4914 = 1332h      unmasked   unmasked   unmasked
  6579.  4915 = 1333h      unmasked   unmasked   masked
  6580.  4918 = 1336h      unmasked   masked     unmasked
  6581.  4919 = 1337h      unmasked   masked     masked
  6582.  4922 = 133Ah      masked     unmasked   unmasked
  6583.  4923 = 133Bh      masked     unmasked   masked
  6584.  4926 = 133Eh      masked     masked     unmasked
  6585.  4927 = 133Fh      masked     masked     masked
  6586.  
  6587.  
  6588.  D.2  Reading and Setting STATUS and CONTROL Values
  6589.  
  6590.  The values of the STATUS word and CONTROL word can be read and set using
  6591.  the following procedures and functions:
  6592.  
  6593.  The procedure LCWRQQ loads the 8087 CONTROL word.
  6594.  
  6595.           PROCEDURE LCWRQQ (consts w: word);
  6596.  
  6597.  The function SCWRQQ stores the 8087 CONTROL word.
  6598.  
  6599.           FUNCTION SCWRQQ : word;
  6600.  
  6601.  The function SCWRQQ stores the 8087 CONTROL word.
  6602.  
  6603.           FUNCTION SSWRQQ : word;
  6604.  
  6605.  If you disable the above exceptions listed at the beginning of this
  6606.  appendix, you will either get NAN, Infinite, or Indefinite values in your
  6607.  variables. If you print such a value, the output field will contain NAN,
  6608.  INF, or IND padded with periods to the field width. If the output field
  6609.  has less than three spaces, only periods will be printed.
  6610.  
  6611.  
  6612.  D.3  Formats for STATUS and CONTROL words
  6613.  
  6614.  The bit locations for storing the cumulative record of exceptions are
  6615.  defined in the diagrams that follow.
  6616.  
  6617.  
  6618.             15                  8  7  6  5  4  3  2  1  0
  6619.  STATUS    │   hi byte unused     │  │  │PE│UE│OE│ZE│  │IE│
  6620.                                           │  │  │  │     │
  6621.      Precision Exception ─────────────────┘  │  │  │     │
  6622.      Underflow Exception ────────────────────┘  │  │     │
  6623.      Overflow Exception ────────────────────────┘  │     │
  6624.      Zero Divide Exception ────────────────────────┘     │
  6625.      Invalid Exception ──────────────────────────────────┘
  6626.  
  6627.          (All other bits unused, may be either 1 or 0)
  6628.  
  6629.  
  6630.  CONTROL     15 14 13 12 11-10  9-8   7  6  5  4  3  2  1  0
  6631.             │  │  │  │IC│ RC  │ PC  │  │  │PM│UM│OM│ZM│  │IM│
  6632.                        │   │     │          │  │  │  │     │
  6633.  (a) Infinity Control ─┘   │     │          │  │  │  │     │
  6634.  (b) Round Control ────────┘     │          │  │  │  │     │
  6635.  (c) Precision Control ──────────┘          │  │  │  │     │
  6636.                                             │  │  │  │     │
  6637.      Precision Mask ────────────────────────┘  │  │  │     │
  6638.      Underflow Mask ───────────────────────────┘  │  │     │
  6639.      Overflow Mask ───────────────────────────────┘  │     │
  6640.      Zero Divide Mask ───────────────────────────────┘     │
  6641.      Invalid Mask ─────────────────────────────────────────┘
  6642.  
  6643.          (All other bits unused, may be either 1 or 0)
  6644.  
  6645.      (a) Infinity Control
  6646.              0 = Projective
  6647.              1 = Affine
  6648.      (b) Round Control
  6649.              00 = Round nearest or even
  6650.              01 = Round down (toward -INF)
  6651.              10 = Round up   (toward +INF)
  6652.              11 = Chop (Truncate toward 0)
  6653.      (c) Precision Control
  6654.              00 = 24 bits of mantissa
  6655.              01 = (reserved)
  6656.              10 = 53 bits of mantissa
  6657.              11 = 64 bits of mantissa
  6658.  
  6659.  
  6660.  
  6661.  Appendix E  Mixed-Language Programming
  6662.  
  6663.  ───────────────────────────────────────────────────────────────────────────
  6664.  
  6665.  
  6666.  
  6667.               ╔══════════════════════════════════════════╗
  6668.               ║  Appendix E, Mixed-Language Programming, ║
  6669.               ║  is superceded by the Mixed Languages    ║
  6670.               ║  Programming Guide found under the       ║
  6671.               ║  Languages menu.                         ║
  6672.               ╚══════════════════════════════════════════╝
  6673.  
  6674.  
  6675.  
  6676.  Appendix F  Error Messages
  6677.  
  6678.  ───────────────────────────────────────────────────────────────────────────
  6679.  
  6680.  F.1  How the Compiler Handles Error Locations
  6681.  
  6682.        F.1.1  Source Program Context
  6683.  
  6684.        F.1.2  Machine Error Context
  6685.  
  6686.        F.1.3  How Source Program Context is Handled
  6687.  
  6688.  F.2  Compile Time Error Messages
  6689.  
  6690.  F.3  Compiler Back End Errors
  6691.  
  6692.  F.4  Runtime File System Errors (1000-1199)
  6693.  
  6694.        F.4.1  Operating System Runtime Errors (1000-1099)
  6695.  
  6696.        F.4.2  Microsoft Pascal File System Errors (1100-1199)
  6697.  
  6698.        F.4.3  Other Runtime Errors (2000-2999)
  6699.  
  6700.        F.4.4  Memory Errors (2000-2049)
  6701.  
  6702.        F.4.5  Ordinal Arithmetic Errors (2050-2099)
  6703.  
  6704.        F.4.6  Type REAL Arithmetic Errors (2100-2149)
  6705.  
  6706.        F.4.7  Structured Type Errors (2150-2199)
  6707.  
  6708.        F.4.8  INTEGER4 Errors (2200-2249)
  6709.  
  6710.        F.4.9  Other Errors (2400-2999)
  6711.  
  6712.  F.5  Unnumbered Error Messages
  6713.  
  6714.  F.6  Linker Error Messages
  6715.  
  6716.  F.7  EXEPACK Error Messages
  6717.  
  6718.  F.8  EXEMOD Error Messages
  6719.  
  6720.  
  6721.  
  6722.  This appendix explains what happens when errors occur, and lists the error
  6723.  messages generated by the compiler, the linker, EXEMOD, and EXEPACK.
  6724.  
  6725.  Error messages are organized by where they occur. The following table
  6726.  shows how error messages are numbered:
  6727.  
  6728.  
  6729.               Table F.1
  6730.               How Errors are Numbered
  6731.  
  6732.               Error Code   Type of Error
  6733.               ────────────────────────────────────────────────
  6734.                   1-899    Front end errors
  6735.                 900-999    Back end errors
  6736.               1000-1099    Unit U file system errors
  6737.               1200-1299    Unit V file system errors
  6738.               1300-1999    Reserved
  6739.               2000-2049    Heap, stack, memory
  6740.               2050-2099    Ordinal and long integer arithmetic
  6741.               2100-2149    Real and double real arithmetic
  6742.               2150-2199    Structures, sets, and strings
  6743.               2200-2399    Reserved
  6744.               2400-2449    Pcode interpreter
  6745.               2450-2499    Other internal errors
  6746.               2500-2999    Reserved
  6747.  
  6748.  Some errors are unnumbered. These errors occur during linking, or
  6749.  during use of EXEMOD and EXEPACK, and are listed in the sections
  6750.  "Unnumbered Errors," "Linker Errors," "EXEPACK Errors," and "EXEMOD
  6751.  Errors."
  6752.  
  6753.  
  6754.  F.1  How the Compiler Handles Error Locations
  6755.  
  6756.  This section describes two ways the compiler displays information about
  6757.  error locations.
  6758.  
  6759.  
  6760.  F.1.1  Source Program Context
  6761.  
  6762.  If an error occurs during compile time, the error number, source line
  6763.  number, and sometimes the text of the source line containing the error are
  6764.  printed on your screen (and in your source listing file, if you have
  6765.  requested one). If the $debug+ metacommand is present, additional
  6766.  information, called the source program context appears, including
  6767.  
  6768.      1.  the source filename of the compiland containing the error
  6769.  
  6770.      2.  the name of the procedure or function containing the error
  6771.  
  6772.      3.  the listing line number of the first line of the statement
  6773.          containing the error
  6774.  
  6775.  You can also get this information for errors that occur during runtime,
  6776.  but only if you compiled the program with the $debug+ metacommand. If
  6777.  you compiled without the $debug+ metacommand and errors occur during
  6778.  runtime, the filename and line number will not be be printed on your
  6779.  screen.
  6780.  
  6781.  Giving the source program context during runtime involves extra
  6782.  overhead, since source location data must be included in the object code in
  6783.  some form. This is done with calls that set the current source context as
  6784.  it occurs. The overhead of source location data, especially line number
  6785.  calls, can be significant. Section F.1.3, "How Source Program Context is
  6786.  Handled," explains how the compiler provides this information.
  6787.  
  6788.  
  6789.  F.1.2  Machine Error Context
  6790.  
  6791.  There is another way of determining where an error occurred, called the
  6792.  machine error context. This information is provided in most runtime error
  6793.  messages. The machine error context is always available, but to use this
  6794.  information you must access certain global variables.
  6795.  
  6796.  The machine error context is made up of
  6797.  
  6798.      1.  the program counter (PC) at the point of the error
  6799.  
  6800.      2.  the stack segment (SS) at the point of the error
  6801.  
  6802.      3.  the framepointer (FP) at the point of the error
  6803.  
  6804.      4.  the stackpointer (SP) at the point of the error
  6805.  
  6806.  For runtime errors, this information will be printed on your screen in
  6807.  this format:
  6808.  
  6809.  ? Error: Data format error in file -
  6810.    Error Code 1233, Status 000E
  6811.  PC = 000C: 0006; SS = 0047, FP = 003F, SP = 1C1C
  6812.  
  6813.  The values of PC, SS, FP, and SP are in hexadecimal.
  6814.  
  6815.  The machine error context does not indicate the location of errors
  6816.  within runtime routines. If an error is in a runtime routine, the machine
  6817.  error context indicates where the user program called the runtime routine
  6818.  or routines. The program counter is always the address following a call to
  6819.  a runtime routine (a return address).
  6820.  
  6821.  You can usually use the program counter (PC) value along with a link
  6822.  map file to find the routine in which the error occurred. Read the
  6823.  addresses in the section of the link map file that is sorted by address
  6824.  until you find a pair that brackets the PC value. The first address of the
  6825.  pair should be the name of the routine that was executing when the error
  6826.  occurred. This does not work for routines that don't have public names.
  6827.  Sometimes the stack segment (SS) and stackpointer (SP) values are useful in
  6828.  determining if there has been a stack overflow. Check the link map file
  6829.  (or use a debugger); if SP is close to or below the location of the label
  6830.  "_end'', there was probably a stack overflow.
  6831.  
  6832.  The variables that contain the machine error context are used by the
  6833.  runtime entry helper, BRTEQQ, as follows:
  6834.  
  6835.    This variable:         Contains:
  6836.  ───────────────────────────────────────────────────────────────────────────
  6837.    RESEQQ                 Stackpointer
  6838.    REFEQQ                 Framepointer
  6839.    REPEQQ                 Program counter offset
  6840.    RECEQQ                 Program counter segment
  6841.  
  6842.  
  6843.  F.1.3  How Source Program Context is Handled
  6844.  
  6845.  This information is not necessary for most Microsoft Pascal programmers.
  6846.  It is provided for advanced programmers because it can be useful for
  6847.  machine-language debugging or for writing specialized debugging aids.
  6848.  
  6849.  The routine EMSEQQ is called when an error is detected during runtime.
  6850.  The source program context entry points are ENTEQQ, EXTEQQ, and LNTEQQ:
  6851.  they are in the debug module, DEBE.
  6852.  
  6853.  The procedure entry call to ENTEQQ passes two VAR parameters: the first
  6854.  is an LSTRING containing the source filename; the second is a record that
  6855.  contains
  6856.  
  6857.      1.  the line number of the procedure (a WORD)
  6858.  
  6859.      2.  the page number of the procedure (a WORD)
  6860.  
  6861.      3.  the subroutine or function name (an LSTRING)
  6862.  
  6863.  The filename is that of the compiland (the main source filename, not the
  6864.  names of any $include files). The procedure name is the full name used in
  6865.  the source, not the linker name. The line number is the first executable
  6866.  statement in the procedure. Entry and exit calls are also generated for
  6867.  the main program, in which case the name is the program name.
  6868.  
  6869.  The procedure exit call to EXTEQQ passes no parameters. It pops the
  6870.  current source routine context off a stack maintained in the heap.
  6871.  
  6872.  The line number call to LNTEQQ passes a line number as a value
  6873.  parameter. The current line number is kept in the PUBLIC variable CLNEQQ.
  6874.  Since the current routine is always available, the compiland source
  6875.  filename and routine containing the line are available along with the line
  6876.  number. Line number calls are generated just before the code in the first
  6877.  statement on a source line. The statement can, of course, be part of a
  6878.  larger statement.
  6879.  
  6880.  
  6881.  F.2  Compile Time Error Messages
  6882.  
  6883.  This section lists, in numerical order, all of the numbered messages issued
  6884.  by the Microsoft Pascal Compiler.
  6885.  
  6886.  Error and warning messages consist of a number and a message. Most
  6887.  messages appear with a row of dashes and an arrow that points to the
  6888.  location of the error; messages 128, 129, and 130 appear after the body of
  6889.  the routine in which they occur.
  6890.  
  6891.  If the word "Warning" appears before a message, the intermediate code
  6892.  files produced by the compiler are correct. A warning is an error that the
  6893.  compiler attempts to correct so that the compiled source may run correctly.
  6894.  Common errors that generate warnings include substitution mistakes, such as
  6895.  using a colon (:) instead of an equal sign (=), and syntax errors like
  6896.  using a semicolon (;) before an ELSE. The condition that produced the
  6897.  message is not severe, but is considered unsafe. If you get a warning
  6898.  message, you should correct the source file; otherwise you will get the
  6899.  same warning message every time you compile.
  6900.  
  6901.  Errors are conditions in the program that the compiler cannot correct.
  6902.  The compiler recovers from most errors and continues the compilation, but
  6903.  the object file will not be correct. There are a few errors (called
  6904.  "panic" errors) from which the compiler cannot recover. When a panic error
  6905.  is detected the compiler displays the following message:
  6906.  
  6907.  Compiler Cannot Continue!
  6908.  
  6909.  and lists the rest of the program without compiling it. Writing to
  6910.  intermediate files stops and the intermediate files are discarded. Errors
  6911.  900 through 904 also cause immediate termination.
  6912.  
  6913.  The compiler also makes a number of internal consistency checks. These
  6914.  checks should always be correct and never give an internal error. When
  6915.  internal errors occur, the error messages have the following format:
  6916.  
  6917.  Error: Compiler Internal Error
  6918.  
  6919.  or
  6920.  
  6921.  *** Internal Error NNN
  6922.  
  6923.  NNN is the internal error number, which ranges from 1 to 999. There is
  6924.  little you can do when an internal error occurs, except report it to
  6925.  Microsoft and perhaps modify your program near the line where the error
  6926.  occurred.
  6927.  
  6928.  The following list includes the error number and message, and a brief
  6929.  explanation of the condition that generates the message:
  6930.  
  6931. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  6932.  Code           Message
  6933.  ───────────────────────────────────────────────────────────────────────────
  6934.  101            Invalid Line Number
  6935.  
  6936.                 There are more than 32767 lines in the source file.
  6937.  
  6938.  
  6939.  102            Line Too Long Truncated
  6940.  
  6941.                 There are more than 142 characters in the line.
  6942.  
  6943.  
  6944.  103            Identifier Too Long Truncated
  6945.  
  6946.                 An identifier is longer than 32 characters, and has been
  6947.                 truncated.
  6948.  
  6949.  
  6950.  104            Number Too Long Truncated
  6951.  
  6952.                 A numeric constant is longer than 32 characters and has been
  6953.  Code           Message
  6954.                A numeric constant is longer than 32 characters and has been
  6955.                 truncated.
  6956.  
  6957.  
  6958.  105            End Of String Not Found
  6959.  
  6960.                 The line ended before the closing quotation mark was found.
  6961.  
  6962.  
  6963.  106            Assumed String
  6964.  
  6965.                 The compiler encountered double quotation marks (") or back
  6966.                 quotation marks (') and assumed that they enclosed a string.
  6967.                 Use single quotation marks (') instead.
  6968.  
  6969.  
  6970.  107            Unexpected End Of File
  6971.  
  6972.                 While scanning, the compiler found an unexpected end of file
  6973.                 in a number, metacommand, or other illegal location.
  6974.  Code           Message
  6975.                in a number, metacommand, or other illegal location.
  6976.  
  6977.  
  6978.  108            Meta Command Expected Command Ignored
  6979.  
  6980.                 The compiler found a dollar sign ($) at the start of a
  6981.                 comment, but no metacommand identifier.
  6982.  
  6983.  
  6984.  109            Unknown Meta Command Ignored
  6985.  
  6986.                 The compiler found a metacommand identifier that it didn't
  6987.                 recognize or that is invalid in this version of Microsoft
  6988.                 Pascal.
  6989.  
  6990.  
  6991.  110            Constant Identifier Unknown Or Invalid Assumed Zero
  6992.  
  6993.                 The constant identifier following a metacommand is unknown
  6994.                 (as in $debug:A) or of the wrong type. The compiler has
  6995.  Code           Message
  6996.                (as in $debug:A) or of the wrong type. The compiler has
  6997.                 replaced the unknown or incorrect value with zero.
  6998.  
  6999.  
  7000.  112            Invalid Numeric Constant Assumed Zero
  7001.  
  7002.                 The constant following a metacommand was a numeric constant
  7003.                 (e.g., $debug:123456) that has the wrong format or is out of
  7004.                 range. The compiler has replaced the incorrect value with
  7005.                 zero.
  7006.  
  7007.  
  7008.  113            Invalid Meta Value Assumed Zero
  7009.  
  7010.                 The value following a metacommand is neither a constant nor
  7011.                 an identifier. The compiler has replaced the incorrect
  7012.                 value with zero.
  7013.  
  7014.  
  7015.  114            Invalid Meta Command
  7016.  Code           Message
  7017. 114            Invalid Meta Command
  7018.  
  7019.                 The compiler expected but did not find one of the following
  7020.                 after a metacommand: +, -, or :. The compiler has ignored
  7021.                 the metacommand.
  7022.  
  7023.  
  7024.  115            Wrong Type Value For Meta Command Skipped
  7025.  
  7026.                 The value following the metacommand was an integer, but
  7027.                 should have been a string (or vice versa). The compiler
  7028.                 ignored the metacommand.
  7029.  
  7030.  
  7031.  116            Meta Value Out Of Range Skipped
  7032.  
  7033.                 The integer value given for the $linesize metacommand was
  7034.                 below 16 or above 160. Or, "n" is neither 4 nor 8 for
  7035.                 $real:n, nor 2 for $integer. In any of these cases, the
  7036.                 compiler ignores the metacommand.
  7037.  Code           Message
  7038.                compiler ignores the metacommand.
  7039.  
  7040.  
  7041.  117            File Identifier Too Long Skipped
  7042.  
  7043.                 The string value given for the filename in an $include
  7044.                 metacommand was longer than 96 characters. The compiler
  7045.                 ignored the metacommand.
  7046.  
  7047.  
  7048.  118            Too Many File Levels
  7049.  
  7050.                 There are too many nested levels of files brought in by the
  7051.                 $include metacommand. The $include metacommand is ignored.
  7052.  
  7053.  
  7054.  119            Invalid Initialize Metacommand
  7055.  
  7056.                 A $pop metacommand has no corresponding $push metacommand.
  7057.  
  7058.  Code           Message
  7059. 
  7060.  
  7061.  120            CONST Identifier Expected
  7062.  
  7063.                 The compiler didn't find an identifier following an $inconst
  7064.                 metacommand. The $inconst metacommand is ignored.
  7065.  
  7066.  
  7067.  121            Invalid INPUT Number Assumed Zero
  7068.  
  7069.                 The user input invoked by $inconst was invalid and is
  7070.                 assumed to be zero.
  7071.  
  7072.  
  7073.  122            Invalid Meta Command Skipped
  7074.  
  7075.                 The compiler found an $if metacommand but no subsequent
  7076.                 $then or $else. The compiler ignores the $if command.
  7077.  
  7078.  
  7079.  Code           Message
  7080. 
  7081.  123            Unexpected Meta Command Skipped
  7082.  
  7083.                 The compiler found a $then metacommand unrelated to any $if
  7084.                 metacommand. The $then command is ignored.
  7085.  
  7086.  
  7087.  124            Unexpected Meta Command
  7088.  
  7089.                 The compiler found a metacommand not enclosed in comment
  7090.                 delimiters, but processed it anyway.
  7091.  
  7092.  
  7093.  126            Invalid Real Constant
  7094.  
  7095.                 The compiler found a type real constant with a leading or a
  7096.                 trailing decimal point. The constant's value is accepted
  7097.                 anyway.
  7098.  
  7099.  
  7100.  Code           Message
  7101. 
  7102.  127            Invalid Character Skipped
  7103.  
  7104.                 The compiler found a character in the source file that is
  7105.                 not acceptable in program text.
  7106.  
  7107.  
  7108.  128            Forward Proc Missing: procedure
  7109.  
  7110.                 The compiler found a procedure or function declared FORWARD
  7111.                 but couldn't find the procedure or function itself.
  7112.  
  7113.  
  7114.  129            Label Not Encountered : label
  7115.  
  7116.                 The compiler couldn't find any use of a label declared in a
  7117.                 LABEL section.
  7118.  
  7119.  
  7120.  130            Program Parameter Bad : parameter
  7121.  Code           Message
  7122. 130            Program Parameter Bad : parameter
  7123.  
  7124.                 The compiler encountered a program parameter that was never
  7125.                 declared or has an unacceptable type.
  7126.  
  7127.  
  7128.  133            Type Size Overflow
  7129.  
  7130.                 The data type declared implies a structure bigger than the
  7131.                 maximum of 65534 bytes.
  7132.  
  7133.  
  7134.  134            Constant Memory Overflow
  7135.  
  7136.                 Constant memory allocation has exceeded the maximum of 65534
  7137.                 bytes.
  7138.  
  7139.  
  7140.  135            Static Memory Overflow
  7141.  
  7142.  Code           Message
  7143. 
  7144.                 Static memory allocation has exceeded the maximum of 65534
  7145.                 bytes.
  7146.  
  7147.  
  7148.  136            Stack Memory Overflow
  7149.  
  7150.                 Stack frame memory allocation has exceeded the maximum of
  7151.                 65534 bytes.
  7152.  
  7153.  
  7154.  137            Integer Constant Overflow
  7155.  
  7156.                 The value of a type INTEGER, signed constant expression is
  7157.                 out of range.
  7158.  
  7159.  
  7160.  138            Word Constant Overflow
  7161.  
  7162.                 The value of a type WORD constant or other unsigned constant
  7163.  Code           Message
  7164.                The value of a type WORD constant or other unsigned constant
  7165.                 expression is out of range.
  7166.  
  7167.  
  7168.  139            Value Not In Range For Record
  7169.  
  7170.                 In a structured constant, or in the long form of the NEW
  7171.                 procedure, DISPOSE procedure, the SIZEOF function, or other
  7172.                 application, the record tag value is not in the range of the
  7173.                 variant.
  7174.  
  7175.  
  7176.  140            Too Many Compiler Labels
  7177.  
  7178.                 Your program is too big. You must break your program into
  7179.                 smaller pieces.
  7180.  
  7181.  
  7182.  141            Compiler
  7183.  
  7184.  Code           Message
  7185. 
  7186.                 This message should never appear. If it does, please report
  7187.                 the condition to Microsoft Corporation.
  7188.  
  7189.  
  7190.  142            Too Many Identifier Levels
  7191.  
  7192.                 The identifier scope level exceeds 15. This is a "panic
  7193.                 error" from which the compiler cannot recover. The rest of
  7194.                 the file is not compiled.
  7195.  
  7196.  
  7197.  143            Compiler
  7198.  
  7199.                 This message should never appear. If it does, please report
  7200.                 the condition to Microsoft Corporation.
  7201.  
  7202.  
  7203.  144            Compiler
  7204.  
  7205.  Code           Message
  7206. 
  7207.                 This message should never appear. If it does, please report
  7208.                 the condition to Microsoft Corporation.
  7209.  
  7210.  
  7211.  145            Identifier Already Declared
  7212.  
  7213.                 The compiler found an identifier declared more than once in
  7214.                 a given scope level.
  7215.  
  7216.  
  7217.  146            Unexpected End Of File
  7218.  
  7219.                 While parsing, the compiler found an end-of-file in the
  7220.                 wrong place, for example in a statement or declaration.
  7221.  
  7222.  
  7223.  147            : Assumed =
  7224.  
  7225.                 The compiler found a colon where there should have been an
  7226.  Code           Message
  7227.                The compiler found a colon where there should have been an
  7228.                 equal sign and proceeded as if the correct symbol were
  7229.                 present.
  7230.  
  7231.  
  7232.  148            = Assumed :
  7233.  
  7234.                 The compiler found an equal sign where it expected a colon
  7235.                 and proceeded as if the correct symbol were present.
  7236.  
  7237.  
  7238.  149            := Assumed =
  7239.  
  7240.                 The compiler found a colon followed by an equal sign where
  7241.                 it expected an equal sign only and proceeded as if the
  7242.                 correct symbol were present.
  7243.  
  7244.  
  7245.  150            = Assumed :=
  7246.  
  7247.  Code           Message
  7248. 
  7249.                 The compiler found an equal sign where it expected a colon
  7250.                 followed by an equal sign and proceeded as if the correct
  7251.                 symbol were present.
  7252.  
  7253.  
  7254.  151            [ Assumed (
  7255.  
  7256.                 The compiler found a left bracket where it expected a left
  7257.                 parenthesis and proceeded as if the correct symbol were
  7258.                 present.
  7259.  
  7260.  
  7261.  152            ( Assumed [
  7262.  
  7263.                 The compiler found a left parenthesis where it expected a
  7264.                 left bracket and proceeded as if the correct symbol were
  7265.                 present.
  7266.  
  7267.  
  7268.  Code           Message
  7269. 
  7270.  153            ) Assumed ]
  7271.  
  7272.                 The compiler found a right parenthesis where it expected a
  7273.                 right bracket and proceeded as if the correct symbol were
  7274.                 present.
  7275.  
  7276.  
  7277.  154            ] Assumed )
  7278.  
  7279.                 The compiler found a right bracket where it expected a right
  7280.                 parenthesis and proceeded as if the correct symbol were
  7281.                 present.
  7282.  
  7283.  
  7284.  155            ; Assumed ,
  7285.  
  7286.                 The compiler found a semicolon where it expected a comma and
  7287.                 proceeded as if the correct symbol were present.
  7288.  
  7289.  Code           Message
  7290. 
  7291.  
  7292.  156            , Assumed ;
  7293.  
  7294.                 The compiler found a comma where it expected a semicolon and
  7295.                 proceeded as if the correct symbol were present.
  7296.  
  7297.  
  7298.  162            Insert Symbol
  7299.  
  7300.                 The compiler didn't find a symbol it expected, but proceeded
  7301.                 as if it were present. This message should not occur; it is
  7302.                 a minor compiler error. If it does, please report it to
  7303.                 Microsoft Corporation.
  7304.  
  7305.  
  7306.  163            Insert ,
  7307.  
  7308.                 The compiler didn't find a comma where it expected one, but
  7309.                 proceeded as if it were present.
  7310.  Code           Message
  7311.                proceeded as if it were present.
  7312.  
  7313.  
  7314.  164            Insert ;
  7315.  
  7316.                 The compiler didn't find a semicolon where it expected one,
  7317.                 but proceeded as if it were present.
  7318.  
  7319.  
  7320.  165            Insert =
  7321.  
  7322.                 The compiler didn't find an equal sign where it expected
  7323.                 one, but proceeded as if it were present.
  7324.  
  7325.  
  7326.  166            Insert :=
  7327.  
  7328.                 The compiler didn't find a colon followed by an equal sign
  7329.                 where it expected one, but proceeded as if it were present.
  7330.  
  7331.  Code           Message
  7332. 
  7333.  
  7334.  167            Insert OF
  7335.  
  7336.                 The compiler didn't find an OF where it expected one, but
  7337.                 proceeded as if it were present.
  7338.  
  7339.  
  7340.  168            Insert ]
  7341.  
  7342.                 The compiler didn't find a right bracket where it expected
  7343.                 one, but proceeded as if it were present.
  7344.  
  7345.  
  7346.  169            Insert )
  7347.  
  7348.                 The compiler didn't find a right parenthesis where it
  7349.                 expected one, but proceeded as if it were present.
  7350.  
  7351.  
  7352.  Code           Message
  7353. 
  7354.  170            Insert [
  7355.  
  7356.                 The compiler didn't find a left bracket where it expected
  7357.                 one, but proceeded as if it were present.
  7358.  
  7359.  
  7360.  171            Insert (
  7361.  
  7362.                 The compiler didn't find a left parenthesis where it
  7363.                 expected one, but proceeded as if it were present.
  7364.  
  7365.  
  7366.  172            Insert DO
  7367.  
  7368.                 The compiler didn't find a DO where it expected one, but
  7369.                 proceeded as if it were present.
  7370.  
  7371.  
  7372.  173            Insert :
  7373.  Code           Message
  7374. 173            Insert :
  7375.  
  7376.                 The compiler didn't find a colon where it expected one, but
  7377.                 proceeded as if it were present.
  7378.  
  7379.  
  7380.  174            Insert .
  7381.  
  7382.                 The compiler didn't find a period where it expected one, but
  7383.                 proceeded as if it were present.
  7384.  
  7385.  
  7386.  175            Insert ..
  7387.  
  7388.                 The compiler didn't find a double period where it expected
  7389.                 one, but proceeded as if it were present.
  7390.  
  7391.  
  7392.  176            Insert END
  7393.  
  7394.  Code           Message
  7395. 
  7396.                 The compiler didn't find an END where it expected one, but
  7397.                 proceeded as if it were present.
  7398.  
  7399.  
  7400.  177            Insert TO
  7401.  
  7402.                 The compiler didn't find a TO where it expected one, but
  7403.                 proceeded as if it were present.
  7404.  
  7405.  
  7406.  178            Insert THEN
  7407.  
  7408.                 The compiler didn't find a THEN where it expected one, but
  7409.                 proceeded as if it were present.
  7410.  
  7411.  
  7412.  179            Insert *
  7413.  
  7414.                 The compiler didn't find an asterisk where it expected one,
  7415.  Code           Message
  7416.                The compiler didn't find an asterisk where it expected one,
  7417.                 but proceeded as if it were present.
  7418.  
  7419.  
  7420.  185            Invalid Symbol Begin Skip
  7421.  
  7422.                 The compiler found a symbol it expected, but only after some
  7423.                 other invalid symbols. The invalid symbols were skipped,
  7424.                 beginning at the point where message 185 appears and ending
  7425.                 where message 186 appears.
  7426.  
  7427.  
  7428.  186            End Skip
  7429.  
  7430.                 The compiler found a symbol it expected, but only after some
  7431.                 other invalid symbols. The invalid symbols were skipped,
  7432.                 beginning at the point where message 185 appears and ending
  7433.                 where message 186 appears.
  7434.  
  7435.  
  7436.  Code           Message
  7437. 
  7438.  187            End Skip
  7439.  
  7440.                 This message marks the end of skipped source text for any
  7441.                 message that ended with the phrase "Begin Skip," except
  7442.                 message 185.
  7443.  
  7444.  
  7445.  188            Section Or Expression Too Long
  7446.  
  7447.                 Try rearranging the program or breaking up expressions with
  7448.                 assignments to intermediate values.
  7449.  
  7450.  
  7451.  189            Invalid Set Operator Or Function
  7452.  
  7453.                 Your source file includes an incorrect use of a set operator
  7454.                 or function (for example, attempting to use the MOD operator
  7455.                 or the ODD function with sets).
  7456.  
  7457.  Code           Message
  7458. 
  7459.  
  7460.  190            Invalid Real Operator Or Function
  7461.  
  7462.                 Your source file includes an incorrect use of an operator or
  7463.                 function on a REAL value (for example, MOD operator or ODD
  7464.                 function with reals).
  7465.  
  7466.  
  7467.  191            Invalid Value Type For Operator Or Function
  7468.  
  7469.                 For example, MOD operator or ODD function with enumerated
  7470.                 type.
  7471.  
  7472.  
  7473.  195            Compiler
  7474.  
  7475.                 This message should never appear. If it does, please report
  7476.                 the condition to Microsoft Corporation.
  7477.  
  7478.  Code           Message
  7479. 
  7480.  
  7481.  196            Zero Size Value
  7482.  
  7483.                 Your source file includes the empty record "RECORD END" as
  7484.                 if it had a size.
  7485.  
  7486.  
  7487.  197            Compiler
  7488.  
  7489.                 This message should never appear. If it does, please report
  7490.                 the condition to Microsoft Corporation.
  7491.  
  7492.  
  7493.  198            Constant Expression Value Out Of Range
  7494.  
  7495.                 The value of a constant expression is out of range in an
  7496.                 array index, subrange assignment, or other subrange.
  7497.  
  7498.  
  7499.  Code           Message
  7500. 
  7501.  199            Integer Type Not Compatible With Word Type
  7502.  
  7503.                 An expression tries to mix INTEGER and WORD type values.
  7504.                 This error indicates confusing signed and unsigned
  7505.                 arithmetic; either change the positive signed value to
  7506.                 unsigned with WRD () or change the unsigned value (MAXINT)
  7507.                 to signed with ORD ().
  7508.  
  7509.  
  7510.  201            Types Not Assignment Compatible
  7511.  
  7512.                 You have attempted to use incompatible types in an
  7513.                 assignment statement or value parameter. See the Microsoft
  7514.                 Pascal Reference Manual for type compatibility rules.
  7515.  
  7516.  
  7517.  202            Types Not Compatible In Expression
  7518.  
  7519.                 You have attempted to mix incompatible types in an
  7520.  Code           Message
  7521.                You have attempted to mix incompatible types in an
  7522.                 expression. See the Pascal Reference Manual for type
  7523.                 compatibility rules.
  7524.  
  7525.  
  7526.  203            Not Array Begin Skip
  7527.  
  7528.                 A variable followed by a left bracket (or parenthesis) is
  7529.                 not an array. The compiler skipped from here to where
  7530.                 message 187 appears.
  7531.  
  7532.  
  7533.  204            Invalid Ordinal Expression Assumed Integer Zero
  7534.  
  7535.                 The expression has the wrong type or a type that is not
  7536.                 ordinal. The compiler assumed the value of the expression
  7537.                 to be zero.
  7538.  
  7539.  
  7540.  205            Invalid Use Of PACKED Components
  7541.  Code           Message
  7542. 205            Invalid Use Of PACKED Components
  7543.  
  7544.                 A component of a PACKED structure has no address (it may not
  7545.                 be on a byte boundary) and cannot be passed by reference.
  7546.  
  7547.  
  7548.  206            Not Record Field Ignored
  7549.  
  7550.                 A variable followed by a period is not a record, address, or
  7551.                 file, and was ignored by the compiler.
  7552.  
  7553.  
  7554.  207            Invalid Field
  7555.  
  7556.                 A valid field name does not follow a record variable and a
  7557.                 period, and was ignored by the compiler.
  7558.  
  7559.  
  7560.  208            File Dereference Considered Harmful
  7561.  
  7562.  Code           Message
  7563. 
  7564.                 This message appears when you are using a file buffer as a
  7565.                 reference parameter to a procedure, a function, or as a
  7566.                 record in a WITH statement. When the compiler calculates
  7567.                 the address of a file buffer variable, it cannot do the
  7568.                 special actions normally done with buffer variables (i.e.,
  7569.                 lazy evaluation for textfiles, or concurrency for binary
  7570.                 files). If the file position changes, the buffer variable
  7571.                 at this address may not be valid, thus such a practice is
  7572.                 considered harmful.
  7573.  
  7574.  
  7575.  209            Cannot Dereference Value
  7576.  
  7577.                 The variable followed by an arrow is not a pointer, address,
  7578.                 or file; therefore the compiler cannot dereference the value
  7579.                 pointed to.
  7580.  
  7581.  
  7582.  210            Invalid Segment Address
  7583.  Code           Message
  7584. 210            Invalid Segment Address
  7585.  
  7586.                 A variable resides at a segmented address, but a default
  7587.                 segment address is needed. You may need to make a local copy
  7588.                 of the variable.
  7589.  
  7590.  
  7591.  211            Ordinal Expression Invalid Or Not Constant
  7592.  
  7593.                 The compiler found an invalid or nonconstant expression
  7594.                 where it expected a constant ordinal expression.
  7595.  
  7596.  
  7597.  214            Out Of Range For Set 255 Assumed
  7598.  
  7599.                 The compiler found an element of a set constant whose
  7600.                 ordinal value exceeded 255 and assumed a value of 255.
  7601.  
  7602.  
  7603.  215            Type Too Long Or Contains File Begin Skip
  7604.  Code           Message
  7605. 215            Type Too Long Or Contains File Begin Skip
  7606.  
  7607.                 The compiler found a structured constant that either exceeds
  7608.                 255 bytes or contains a FILE or LSTRING type.
  7609.  
  7610.  
  7611.  216            Extra Array Components Ignored
  7612.  
  7613.                 The compiler found an array constant that had too many
  7614.                 components for the array type. The excess components were
  7615.                 ignored.
  7616.  
  7617.  
  7618.  217            Extra Record Components Ignored
  7619.  
  7620.                 The compiler found a record constant that had too many
  7621.                 components for the record type. The excess components were
  7622.                 ignored.
  7623.  
  7624.  
  7625.  Code           Message
  7626. 
  7627.  218            Constant Value Expected Zero Assumed
  7628.  
  7629.                 The compiler found a nonconstant value in a structured
  7630.                 constant and assumed its value was zero.
  7631.  
  7632.  
  7633.  220            Compiler
  7634.  
  7635.                 This message should never appear. If it does, please report
  7636.                 the condition to Microsoft Corporation.
  7637.  
  7638.  
  7639.  221            Components Expected For Type
  7640.  
  7641.                 The compiler found too few components for the type of a
  7642.                 structured constant.
  7643.  
  7644.  
  7645.  222            Overflow 255 Components In String Constant
  7646.  Code           Message
  7647. 222            Overflow 255 Components In String Constant
  7648.  
  7649.                 The compiler found a string constant that exceeded 255
  7650.                 bytes.
  7651.  
  7652.  
  7653.  223            Use NULL
  7654.  
  7655.                 Use the predeclared constant NULL instead of two quotation
  7656.                 marks.
  7657.  
  7658.  
  7659.  224            Cannot Assign With Supertype Lstring
  7660.  
  7661.                 A super array LSTRING cannot be the source or the target of
  7662.                 an assignment.
  7663.  
  7664.  
  7665.  225            String Expression Not Constant
  7666.  
  7667.  Code           Message
  7668. 
  7669.                 String concatenation with the asterisk applies only to
  7670.                 constants.
  7671.  
  7672.  
  7673.  226            String Expected Character 255 Assumed
  7674.  
  7675.                 The compiler found a string constant with no characters,
  7676.                 perhaps the result of using NULL, and assumed the value
  7677.                 CHR(255).
  7678.  
  7679.  
  7680.  227            Invalid Address Of Function
  7681.  
  7682.                 An assignment or other address reference to the function
  7683.                 value is not within the scope of the function. Or, RESULT is
  7684.                 used outside the scope of the function.
  7685.  
  7686.  
  7687.  228            Cannot Assign To Variable
  7688.  Code           Message
  7689. 228            Cannot Assign To Variable
  7690.  
  7691.                 Assignment to READONLY, CONST, or FOR control variables is
  7692.                 not permitted.
  7693.  
  7694.  
  7695.  230            Unknown Identifier Assumed Integer Begin Skip
  7696.  
  7697.                 The compiler found an unknown identifier, for which it
  7698.                 requires an address, and has skipped to a comma, semicolon,
  7699.                 or right parenthesis.
  7700.  
  7701.  
  7702.  231            VAR Parameter Or WITH Record Assumed Integer Begin Skip
  7703.  
  7704.                 The compiler found an invalid symbol where it requires an
  7705.                 address, and has skipped to a comma, semicolon, or right
  7706.                 parenthesis.
  7707.  
  7708.  
  7709.  Code           Message
  7710. 
  7711.  232            Cannot Assign To Type
  7712.  
  7713.                 The target of an assignment is a file or cannot be assigned
  7714.                 for some other reason.
  7715.  
  7716.  
  7717.  233            Invalid Procedure Or Function Parameter Begin Skip
  7718.  
  7719.                 The compiler found an incorrect use of an intrinsic
  7720.                 procedure or function. The error could be one of the
  7721.                 following:
  7722.  
  7723.                 1.  The first parameter of NEW or DISPOSE is not a pointer
  7724.                     variable.
  7725.  
  7726.                 2.  The record tag value of a NEW, DISPOSE, or SIZEOF
  7727.                     couldn't be found.
  7728.  
  7729.                 3.  The super array in a NEW, DISPOSE, or SIZEOF had too
  7730.  Code           Message
  7731.                3.  The super array in a NEW, DISPOSE, or SIZEOF had too
  7732.                     many bounds.
  7733.  
  7734.                 4.  The super array in a NEW, DISPOSE, or SIZEOF had too few
  7735.                     bounds.
  7736.  
  7737.                 5.  The super array for a NEW or SIZEOF has been given no
  7738.                     bounds.
  7739.  
  7740.                 6.  You attempted to use a WRD or ORD function on a value
  7741.                     not of an ordinal type.
  7742.  
  7743.                 7.  You attempted to use the LOWER or UPPER functions on an
  7744.                     invalid value or type.
  7745.  
  7746.                 8.  You attempted to use PACK or UNPACK on a super array or
  7747.                     file, or an array that is or is not packed as expected.
  7748.  
  7749.                 9.  The first parameter for a RETYPE is not a type
  7750.                     identifier.
  7751.  Code           Message
  7752.                    identifier.
  7753.  
  7754.                 10. The parameter for a RESULT function is not a function
  7755.                     identifier.
  7756.  
  7757.                 11. You attempted to use an intrinsic procedure or function
  7758.                     not available in this version of Microsoft Pascal.
  7759.  
  7760.                 12. The ORD or WRD of an INTEGER4 value is out of range.
  7761.  
  7762.                 13. The parameter given for HIWORD or LOWORD is not an
  7763.                     ordinal or INTEGER4.
  7764.  
  7765.  
  7766.  234            Type Invalid Assumed Integer
  7767.  
  7768.                 The parameter given to READ, WRITE, ENCODE, or DECODE is not
  7769.                 of type INTEGER, WORD, INTEGER4, REAL, BOOLEAN, enumerated,
  7770.                 a pointer; or, the parameter given for a READ or WRITE is
  7771.                 not of type CHAR, STRING, LSTRING; or, the parameter for a
  7772.  Code           Message
  7773.                not of type CHAR, STRING, LSTRING; or, the parameter for a
  7774.                 READFN is not of one of these types or type FILE. The
  7775.                 compiler assumed it to be of type INTEGER. This error also
  7776.                 occurs if a program parameter does not have a readable type,
  7777.                 in which case the error occurs at the keyword BEGIN for the
  7778.                 main program.
  7779.  
  7780.  
  7781.  235            Assumed File INPUT
  7782.  
  7783.                 Because the first parameter for a READFN is not a file,
  7784.                 INPUT is assumed.
  7785.  
  7786.  
  7787.  236            Invalid Segment For File
  7788.  
  7789.                 File parameters must always reside in the default segment.
  7790.  
  7791.  
  7792.  237            Assumed INPUT
  7793.  Code           Message
  7794. 237            Assumed INPUT
  7795.  
  7796.                 INPUT was not given as a program parameter and has been
  7797.                 assumed.
  7798.  
  7799.  
  7800.  238            Assumed OUTPUT
  7801.  
  7802.                 OUTPUT was not given as a program parameter and has been
  7803.                 assumed.
  7804.  
  7805.  
  7806.  239            Not Lstring Or Invalid Segment
  7807.  
  7808.                 The target of a READSET, ENCODE, or DECODE must be an
  7809.                 LSTRING in the default segment. One or both of these
  7810.                 conditions is missing.
  7811.  
  7812.  
  7813.  242            File Parameter Expected Begin Skip
  7814.  Code           Message
  7815. 242            File Parameter Expected Begin Skip
  7816.  
  7817.                 The READSET procedure expects, but cannot find, a textfile
  7818.                 parameter. The compiler ignored the procedure and resumed
  7819.                 where message 187 appears.
  7820.  
  7821.  
  7822.  243            Character Set Expected
  7823.  
  7824.                 The READSET procedure expects, but cannot find, a SET OF
  7825.                 CHAR parameter.
  7826.  
  7827.  
  7828.  244            Unexpected Parameter Begin Skip
  7829.  
  7830.                 The compiler found more than one parameter given for an EOF,
  7831.                 EOLN, or PAGE, and ignored the extra one.
  7832.  
  7833.  
  7834.  245            Not Text File
  7835.  Code           Message
  7836. 245            Not Text File
  7837.  
  7838.                 You attempted to use an EOLN, PAGE, READLN, or WRITELN on a
  7839.                 file that is not a textfile.
  7840.  
  7841.  
  7842.  248            Size Not Identical
  7843.  
  7844.                 The RETYPE function may not work as intended, since the
  7845.                 parameters given are of unequal length.
  7846.  
  7847.  
  7848.  249            Procedural Type Parameter List Not Compatible
  7849.  
  7850.                 The parameter lists for formal and actual procedure
  7851.                 parameters are not compatible. That is, the number of
  7852.                 parameters, the function result type, a parameter type, or
  7853.                 attributes are different.
  7854.  
  7855.  
  7856.  Code           Message
  7857. 
  7858.  250            Cannot Use Procedure With Attribute
  7859.  
  7860.                 You attempted to call a procedure with the attribute
  7861.                 INTERRUPT, directly or indirectly. INTERRUPT does not allow
  7862.                 this.
  7863.  
  7864.  
  7865.  251            Unexpected Parameter Begin Skip
  7866.  
  7867.                 The compiler found a left parenthesis, indicating a
  7868.                 procedure or function, but no parameters, and has skipped to
  7869.                 where message 187 appears.
  7870.  
  7871.  
  7872.  252            Cannot Use Procedure Or Function As Parameter
  7873.  
  7874.                 You attempted to pass an intrinsic procedure or function as
  7875.                 a parameter, which is not permitted.
  7876.  
  7877.  Code           Message
  7878. 
  7879.  
  7880.  253            Parameter Not Procedure Or Function Begin Skip
  7881.  
  7882.                 The compiler expected, but cannot find, a procedural
  7883.                 parameter here, and has skipped to where message 187
  7884.                 appears.
  7885.  
  7886.  
  7887.  254            Supertype Array Parameter Not Compatible
  7888.  
  7889.                 The actual parameter given is not of the same type or is not
  7890.                 derived from the same super type as the formal parameter.
  7891.  
  7892.  
  7893.  255            Compiler
  7894.  
  7895.                 This message should never appear. If it does, please report
  7896.                 the condition to Microsoft Corporation.
  7897.  
  7898.  Code           Message
  7899. 
  7900.  
  7901.  256            VAR Or CONST Parameter Types Not Identical
  7902.  
  7903.                 The actual and formal reference parameter types are not
  7904.                 identical, as they must be.
  7905.  
  7906.  
  7907.  257            Parameter List Size Wrong Begin Skip
  7908.  
  7909.                 The compiler found too many or too few parameters in a list.
  7910.                 If too many, the excess parameters were skipped.
  7911.  
  7912.  
  7913.  258            Invalid Procedural Parameter To EXTERN
  7914.  
  7915.                 A procedure or function that is neither PUBLIC nor EXTERN is
  7916.                 being passed as a parameter to a procedure or function
  7917.                 declared EXTERN. (The compiler invokes the actual procedure
  7918.                 or function with intrasegment calls, and so cannot pass them
  7919.  Code           Message
  7920.                or function with intrasegment calls, and so cannot pass them
  7921.                 to an external code segment.)
  7922.  
  7923.  
  7924.  259            Invalid Set Constant For Type
  7925.  
  7926.                 The set is not constant, base types are not identical, or
  7927.                 the constant is too big.
  7928.  
  7929.  
  7930.  260            Unknown Identifier In Expression Assumed Zero
  7931.  
  7932.                 The identifier in an expression is undefined or possibly
  7933.                 misspelled.
  7934.  
  7935.  
  7936.  261            Identifier Wrong In Expression Assumed Zero
  7937.  
  7938.                 The identifier in an expression is incorrect (e.g., file
  7939.                 type identifier) and was assumed to be zero.
  7940.  Code           Message
  7941.                type identifier) and was assumed to be zero.
  7942.  
  7943.  
  7944.  262            Assumed Parameter Index Or Field Begin Skip
  7945.  
  7946.                 After error 260 or 261, anything in parentheses or square
  7947.                 brackets, or a dot followed by an identifier, is skipped.
  7948.  
  7949.  
  7950.  265            Invalid Numeric Constant Assumed Zero
  7951.  
  7952.                 There is a decode error in an assumed INTEGER or INTEGER4
  7953.                 literal constant; the number may be too big, or contain
  7954.                 invalid characters. The incorrect constant was assumed to
  7955.                 be zero.
  7956.  
  7957.  
  7958.  267            Invalid Real Numeric Constant
  7959.  
  7960.                 There is a decode error in an assumed type REAL literal
  7961.  Code           Message
  7962.                There is a decode error in an assumed type REAL literal
  7963.                 constant; the number may be too big, or contain invalid
  7964.                 characters.
  7965.  
  7966.  
  7967.  268            Cannot Begin Expression Skipped
  7968.  
  7969.                 The compiler found an illegal symbol at the beginning of an
  7970.                 expression and deleted the symbol.
  7971.  
  7972.  
  7973.  269            Cannot Begin Expression Assumed Zero
  7974.  
  7975.                 At the beginning of an expression the compiler found a
  7976.                 symbol that is permitted within an expression, but not at
  7977.                 the beginning (a floating-point number beginning with a .
  7978.                 instead of a 0, for example). The compiler placed a 0 before
  7979.                 the symbol.
  7980.  
  7981.  
  7982.  Code           Message
  7983. 
  7984.  270            Constant Overflow
  7985.  
  7986.                 The divisor in a DIV or MOD function is the constant zero
  7987.                 (INTEGER or WORD), which is not permitted.
  7988.  
  7989.  
  7990.  272            Word Constant Overflow
  7991.  
  7992.                 A WORD constant minus a WORD constant gave a negative
  7993.                 result. A WORD constant is always a positive value.
  7994.  
  7995.  
  7996.  275            Invalid Range
  7997.  
  7998.                 The lower bound of a subrange is greater than the upper
  7999.                 bound (e.g., 2..1).
  8000.  
  8001.  
  8002.  276            CASE Constant Expected
  8003.  Code           Message
  8004. 276            CASE Constant Expected
  8005.  
  8006.                 The compiler expects, but cannot find, a constant value for
  8007.                 a CASE statement or record variant.
  8008.  
  8009.  
  8010.  277            Value Already In Use
  8011.  
  8012.                 In a CASE statement or record variant, the value was already
  8013.                 assigned (as in CASE 1..3: XXX; 2: YYY; END).
  8014.  
  8015.  
  8016.  279            Label Expected
  8017.  
  8018.                 The compiler expects, but cannot find, a label.
  8019.  
  8020.  
  8021.  280            Invalid Integer Label
  8022.  
  8023.                 A label uses nondecimal notation (e.g., 8_77), which is not
  8024.  Code           Message
  8025.                A label uses nondecimal notation (e.g., 8_77), which is not
  8026.                 allowed.
  8027.  
  8028.  
  8029.  281            Label Assumed Declared
  8030.  
  8031.                 The compiler found a label that did not appear in the LABEL
  8032.                 section.
  8033.  
  8034.  
  8035.  283            Expression Not Boolean Type
  8036.  
  8037.                 The expression following an IF, WHILE, or UNTIL statement
  8038.                 must be BOOLEAN.
  8039.  
  8040.  
  8041.  284            Skip To End Of Statement
  8042.  
  8043.                 The compiler found, and skipped, an unexpected ELSE or UNTIL
  8044.                 clause.
  8045.  Code           Message
  8046.                clause.
  8047.  
  8048.  
  8049.  285            Compiler
  8050.  
  8051.                 This message should never appear. If it does, please report
  8052.                 the condition to Microsoft Corporation.
  8053.  
  8054.  
  8055.  286            ; Ignored
  8056.  
  8057.                 The compiler found, and ignored, a semicolon before an ELSE
  8058.                 statement. (The semicolon is not required in this case.)
  8059.  
  8060.  
  8061.  288            : Skipped
  8062.  
  8063.                 The compiler found, and ignored, a colon after an OTHERWISE
  8064.                 statement. (The colon is not required in this case.)
  8065.  
  8066.  Code           Message
  8067. 
  8068.  
  8069.  289            Variable Expected For FOR Statement Begin Skip
  8070.  
  8071.                 The compiler expected, but couldn't find, a variable
  8072.                 identifier after a FOR statement and skipped to where
  8073.                 message 187 appears.
  8074.  
  8075.  
  8076.  291            FOR Variable Not Ordinal Or Static Or Declared In Procedure
  8077.  
  8078.                 The compiler found an incorrect control variable in a FOR
  8079.                 statement. Control variables may not be any of the
  8080.                 following:
  8081.  
  8082.                 1.  type REAL, INTEGER4, or another non-ordinal type
  8083.  
  8084.                 2.  the component of an array, record, or file type
  8085.  
  8086.                 3.  the referent of a pointer type or address type
  8087.  Code           Message
  8088.                3.  the referent of a pointer type or address type
  8089.  
  8090.                 4.  in the stack or heap, unless locally declared
  8091.  
  8092.                 5.  nonlocally declared, unless in static memory
  8093.  
  8094.                 6.  a reference parameter (VAR or VARS parameter)
  8095.  
  8096.                 7.  a variable with a segmented ORIGIN attribute
  8097.  
  8098.  
  8099.  292            Skip To :=
  8100.  
  8101.                 The compiler expected, but could not find, an assignment in
  8102.                 a FOR statement, and skipped to the next :=.
  8103.  
  8104.  
  8105.  293            GOTO Invalid
  8106.  
  8107.                 The GOTO or label involves an invalid GOTO statement or a
  8108.  Code           Message
  8109.                The GOTO or label involves an invalid GOTO statement or a
  8110.                 nonexistent label.
  8111.  
  8112.  
  8113.  294            GOTO Considered Harmful
  8114.  
  8115.                 If the $goto metacommand is on, the compiler found a GOTO
  8116.                 statement.
  8117.  
  8118.  
  8119.  296            Label Not Loop Label
  8120.  
  8121.                 The label after a BREAK or CYCLE statement is not a loop
  8122.                 label (i.e., does not label a FOR, WHILE, or REPEAT
  8123.                 statement).
  8124.  
  8125.  
  8126.  297            Not In Loop
  8127.  
  8128.                 The compiler found a BREAK or CYCLE statement outside a FOR,
  8129.  Code           Message
  8130.                The compiler found a BREAK or CYCLE statement outside a FOR,
  8131.                 WHILE, or REPEAT statement.
  8132.  
  8133.  
  8134.  298            Record Expected Begin Skip
  8135.  
  8136.                 The compiler expected, but could not find, a record variable
  8137.                 in a WITH statement and skipped to where message 187
  8138.                 appears.
  8139.  
  8140.  
  8141.  300            Label Already In Use Previous Use Ignored
  8142.  
  8143.                 The compiler found a label that already been used and
  8144.                 ignored the previous use.
  8145.  
  8146.  
  8147.  301            Invalid Use Of Procedure Or Function Parameter
  8148.  
  8149.                 The compiler found a procedure parameter used as a function
  8150.  Code           Message
  8151.                The compiler found a procedure parameter used as a function
  8152.                 or a function parameter used as a procedure.
  8153.  
  8154.  
  8155.  303            Unknown Identifier Skip Statement
  8156.  
  8157.                 The compiler found an undefined (or possibly misspelled)
  8158.                 identifier at the beginning of a statement and ignored the
  8159.                 entire statement.
  8160.  
  8161.  
  8162.  304            Invalid Identifier Skip Statement
  8163.  
  8164.                 The compiler found an incorrect identifier at the beginning
  8165.                 of a statement (e.g., file type identifier) and ignored the
  8166.                 entire statement.
  8167.  
  8168.  
  8169.  305            Statement Not Expected
  8170.  
  8171.  Code           Message
  8172. 
  8173.                 The compiler found a MODULE or uninitialized IMPLEMENTATION
  8174.                 with a body enclosed with the reserved words BEGIN and END.
  8175.  
  8176.  
  8177.  306            Function Assignment Not Found
  8178.  
  8179.                 The compiler expects, but cannot find, an assignment of the
  8180.                 value of a function somewhere in its body.
  8181.  
  8182.  
  8183.  307            Unexpected END Skipped
  8184.  
  8185.                 The compiler found, and ignored, an END without a matching
  8186.                 BEGIN, CASE, or RECORD.
  8187.  
  8188.  
  8189.  308            Compiler
  8190.  
  8191.                 This message should never appear. If it does, please report
  8192.  Code           Message
  8193.                This message should never appear. If it does, please report
  8194.                 the condition to Microsoft Corporation.
  8195.  
  8196.  
  8197.  309            Attribute Invalid
  8198.  
  8199.                 The compiler found an attribute valid only for procedures
  8200.                 and functions given to a variable, an attribute valid only
  8201.                 for a variable given to a procedure or function, or an
  8202.                 invalid mix of attributes (e.g., PUBLIC and EXTERN).
  8203.  
  8204.  
  8205.  310            Attribute Expected
  8206.  
  8207.                 The compiler expected, but could not find, a valid attribute
  8208.                 following the left bracket.
  8209.  
  8210.  
  8211.  311            Skip To Identifier
  8212.  
  8213.  Code           Message
  8214. 
  8215.                 The compiler skipped an invalid (i.e., unexpected) symbol to
  8216.                 get to the identifier that follows.
  8217.  
  8218.  
  8219.  312            Identifier Expected
  8220.  
  8221.                 The compiler expected, but could not find, a list of
  8222.                 identifiers.
  8223.  
  8224.  
  8225.  314            Identifier Expected Skip To ;
  8226.  
  8227.                 The compiler expected, but could not find, the declaration
  8228.                 of a new identifier, and skipped to the next semicolon.
  8229.  
  8230.  
  8231.  315            Type Unknown Or Invalid Assumed Integer Begin Skip
  8232.  
  8233.                 The return type for a parameter or function is incorrect;
  8234.  Code           Message
  8235.                The return type for a parameter or function is incorrect;
  8236.                 that is, it is not an identifier or is undeclared, or the
  8237.                 value parameter or function value is a file or super array.
  8238.                 The compiler assumed the type is INTEGER and skipped to
  8239.                 where message 187 appears.
  8240.  
  8241.  
  8242.  316            Identifier Expected
  8243.  
  8244.                 The compiler expects, but cannot find, an identifier after
  8245.                 the word PROCEDURE or FUNCTION in parameter list.
  8246.  
  8247.  
  8248.  318            Compiler
  8249.  
  8250.                 This message should never appear. If it does, please report
  8251.                 the condition to Microsoft Corporation.
  8252.  
  8253.  
  8254.  319            Compiler
  8255.  Code           Message
  8256. 319            Compiler
  8257.  
  8258.                 This message should never appear. If it does, please report
  8259.                 the condition to Microsoft Corporation.
  8260.  
  8261.  
  8262.  320            Previous Forward Skip Parameter List
  8263.  
  8264.                 The compiler found a definition of a FORWARD (or INTERFACE)
  8265.                 procedure or function that unnecessarily repeats the
  8266.                 parameter list and function return type.
  8267.  
  8268.  
  8269.  321            Not EXTERN
  8270.  
  8271.                 The compiler found a procedure or function with the ORIGIN
  8272.                 attribute but missing the required EXTERN attribute.
  8273.  
  8274.  
  8275.  322            Invalid Attribute With Function Or Parameter
  8276.  Code           Message
  8277. 322            Invalid Attribute With Function Or Parameter
  8278.  
  8279.                 The compiler found an incorrectly used INTERRUPT procedure,
  8280.                 that is, one that has parameters or is a function.
  8281.  
  8282.  
  8283.  323            Invalid Attribute In Procedure Or Function
  8284.  
  8285.                 The compiler found a nested procedure or function that has
  8286.                 attributes or is declared EXTERN. Neither of these
  8287.                 conditions is permitted.
  8288.  
  8289.  
  8290.  324            Compiler
  8291.  
  8292.                 This message should never appear. If it does, please report
  8293.                 the condition to Microsoft Corporation.
  8294.  
  8295.  
  8296.  325            Already Forward
  8297.  Code           Message
  8298. 325            Already Forward
  8299.  
  8300.                 You attempted to use FORWARD twice for the same procedure or
  8301.                 function.
  8302.  
  8303.  
  8304.  326            Identifier Expected For Procedure Or Function
  8305.  
  8306.                 The compiler expects, but cannot find, an identifier
  8307.                 following the keywords PROCEDURE or FUNCTION.
  8308.  
  8309.  
  8310.  327            Invalid Symbol Skipped
  8311.  
  8312.                 The compiler found, and ignored, a FORWARD or EXTERN
  8313.                 directive in an interface.
  8314.  
  8315.  
  8316.  328            EXTERN Invalid With Attribute
  8317.  
  8318.  Code           Message
  8319. 
  8320.                 The compiler found an EXTERN procedure also declared PUBLIC.
  8321.                 This is not permitted.
  8322.  
  8323.  
  8324.  329            Ordinal Type Identifier Expected Integer Assumed Begin Skip
  8325.  
  8326.                 The compiler expected, but could not find, an ordinal type
  8327.                 identifier for a record tag type. It skipped what was given
  8328.                 in the source file and assumed type INTEGER.
  8329.  
  8330.  
  8331.  330            Contains File Cannot Initialize
  8332.  
  8333.                 You have used a file in a record variant. This is allowed,
  8334.                 but considered unsafe, and is not initialized automatically
  8335.                 with the usual NEWFQQ call.
  8336.  
  8337.  
  8338.  331            Type Identifier Expected Assumed Character
  8339.  Code           Message
  8340. 331            Type Identifier Expected Assumed Character
  8341.  
  8342.                 The compiler expects, but cannot find, an ordinal type
  8343.                 identifier. It assumes that what it does find is of type
  8344.                 CHAR.
  8345.  
  8346.  
  8347.  333            Not Supertype Assumed String
  8348.  
  8349.                 The compiler found what looks like a super array type
  8350.                 designator. However, the type identifier is not for a super
  8351.                 array type, so the compiler assumed it to be of the super
  8352.                 array type STRING.
  8353.  
  8354.  
  8355.  334            Type Expected Integer Assumed
  8356.  
  8357.                 The compiler expected, but could not find, a type clause or
  8358.                 type identifier and assumed the expected type to be type
  8359.                 INTEGER.
  8360.  Code           Message
  8361.                INTEGER.
  8362.  
  8363.  
  8364.  335            Out Of Range 255 For Lstring
  8365.  
  8366.                 The compiler found an LSTRING designator whose upper bound
  8367.                 exceeds 255.
  8368.  
  8369.  
  8370.  336            Cannot Use Supertype Use Designator
  8371.  
  8372.                 A super array type can be used only as a reference parameter
  8373.                 or a pointer referent. Other variables cannot be given a
  8374.                 super array type. Use a super array designator.
  8375.  
  8376.  
  8377.  337            Supertype Designator Not Found
  8378.  
  8379.                 The compiler expected, but could not find, a super array
  8380.                 designator that gives the upper bounds of the super array.
  8381.  Code           Message
  8382.                designator that gives the upper bounds of the super array.
  8383.  
  8384.  
  8385.  338            Contains File Cannot Initialize
  8386.  
  8387.                 The compiler found a super array of a file type. While
  8388.                 allowed, this is considered unsafe and is not initialized
  8389.                 automatically with the usual NEWFQQ call.
  8390.  
  8391.  
  8392.  339            Supertype Not Array Skip To ; Assumed Integer
  8393.  
  8394.                 The compiler expected, but could not find, the keyword ARRAY
  8395.                 following SUPER in a type clause. It assumed that the type
  8396.                 is INTEGER and skipped to the next semicolon.
  8397.  
  8398.  
  8399.  340            Invalid Set Range Integer Zero To 255 Assumed
  8400.  
  8401.                 The compiler found an invalid range for the base type of a
  8402.  Code           Message
  8403.                The compiler found an invalid range for the base type of a
  8404.                 set and assumed it to be of type INTEGER with a range from
  8405.                 zero to 255.
  8406.  
  8407.  
  8408.  341            File Contains File
  8409.  
  8410.                 The compiler found, but does not permit, a file type that
  8411.                 contains a file type, either directly or indirectly.
  8412.  
  8413.  
  8414.  342            PACKED Identifier Invalid Ignored
  8415.  
  8416.                 The compiler expected, but could not find, one of words
  8417.                 ARRAY, RECORD, SET, or FILE following the reserved word
  8418.                 PACKED. A type identifier following PACKED is not
  8419.                 permitted.
  8420.  
  8421.  
  8422.  343            Unexpected PACKED
  8423.  Code           Message
  8424. 343            Unexpected PACKED
  8425.  
  8426.                 The compiler found the keyword PACKED applied to a
  8427.                 nonstructured type.
  8428.  
  8429.  
  8430.  345            Skip To ;
  8431.  
  8432.                 The compiler expected, but could not find, a semicolon at
  8433.                 the end of a declaration which is not at the end of the
  8434.                 line. It assumed the next semicolon is the end of the
  8435.                 declaration.
  8436.  
  8437.  
  8438.  346            Insert ;
  8439.  
  8440.                 The compiler expected, but could not find, a semicolon at
  8441.                 the end of the declaration which coincides with the end of a
  8442.                 line. It inserted a semicolon where it expected to find
  8443.                 one.
  8444.  Code           Message
  8445.                one.
  8446.  
  8447.  
  8448.  347            Cannot Use Value Section With ROM Memory
  8449.  
  8450.                 If the $rom metacommand is on, your program may not contain
  8451.                 a VALUE section.
  8452.  
  8453.  
  8454.  348            UNIT Procedure Or Function Invalid EXTERN
  8455.  
  8456.                 A required EXTERN declaration occurs later than it should in
  8457.                 an IMPLEMENTATION. Any interface procedures and functions
  8458.                 not implemented must be declared EXTERN at the beginning.
  8459.  
  8460.  
  8461.  350            Not Array Begin Skip
  8462.  
  8463.                 In a VALUE section, the variable followed by a left bracket
  8464.                 is not an array.
  8465.  Code           Message
  8466.                is not an array.
  8467.  
  8468.  
  8469.  351            Not Record Begin Skip
  8470.  
  8471.                 The variable followed by a period, in a VALUE section, is
  8472.                 not a record type.
  8473.  
  8474.  
  8475.  352            Invalid Field
  8476.  
  8477.                 Within a VALUE section, the identifier assumed to be a field
  8478.                 is not in the record.
  8479.  
  8480.  
  8481.  353            Constant Value Expected
  8482.  
  8483.                 Within a VALUE section, a variable has been initialized to
  8484.                 something other than a constant.
  8485.  
  8486.  Code           Message
  8487. 
  8488.  
  8489.  354            Not Assignment Operator Skip To ;
  8490.  
  8491.                 Within a VALUE section, the assignment operator is missing.
  8492.  
  8493.  
  8494.  355            Cannot Initialize Identifier Skip To ;
  8495.  
  8496.                 Within a VALUE section, there is a symbol that is not a
  8497.                 variable declared at this level in fixed (STATIC) memory.
  8498.                 Or, it has an illegal ORIGIN or EXTERN attribute.
  8499.  
  8500.  
  8501.  356            Cannot Use Value Section
  8502.  
  8503.                 A VALUE section has been incorrectly included in the
  8504.                 INTERFACE, rather than in the IMPLEMENTATION.
  8505.  
  8506.  
  8507.  Code           Message
  8508. 
  8509.  357            Unknown Forward Pointer Type Assumed Integer
  8510.  
  8511.                 The identifier for the referent of a reference type declared
  8512.                 earlier in this TYPE (or VAR) section was never declared
  8513.                 itself.
  8514.  
  8515.  
  8516.  358            Pointer Type Assumed Forward
  8517.  
  8518.                 The TYPE section includes a pointer or address type for
  8519.                 which the referent type was already declared in an enclosing
  8520.                 scope. Since the identifier for the referent type was
  8521.                 declared again later in the same TYPE section, the compiler
  8522.                 used the second definition. In the following example the
  8523.                 forward type, REAL, is used:
  8524.  
  8525.                 PROGRAM outside;
  8526.                 TYPE a = WORD;
  8527.                 PROCEDURE b;
  8528.  Code           Message
  8529.                PROCEDURE b;
  8530.                 TYPE c= a;
  8531.                 a = REAL;
  8532.  
  8533.  
  8534.  359            Cannot Use Label Section
  8535.  
  8536.                 The compiler found a LABEL section incorrectly included in
  8537.                 an INTERFACE, rather than in an IMPLEMENTATION.
  8538.  
  8539.  
  8540.  360            Forward Pointer To Supertype
  8541.  
  8542.                 The referent of a reference type declared in this TYPE
  8543.                 section is a super array type. The declaration of the super
  8544.                 array type doesn't occur until after the reference.
  8545.  
  8546.  
  8547.  361            Constant Expression Expected Zero Assumed
  8548.  
  8549.  Code           Message
  8550. 
  8551.                 An expression in a CONST section is not a constant.
  8552.  
  8553.  
  8554.  362            Attribute Invalid
  8555.  
  8556.                 A VAR section mixes incorrectly the PUBLIC or ORIGIN
  8557.                 attribute with EXTERN. Or, ORIGIN appears in attribute
  8558.                 brackets after the keyword VAR.
  8559.  
  8560.  
  8561.  364            Contains File Initialize Module
  8562.  
  8563.                 The compiler found an uninitialized file variable in a
  8564.                 module. You must call the module as a parameterless
  8565.                 procedure to initialize the files.
  8566.  
  8567.  
  8568.  365            Origin Variable Contains File Cannot Initialize
  8569.  
  8570.  Code           Message
  8571. 
  8572.                 The compiler found an uninitialized file variable with the
  8573.                 ORIGIN attribute. Since ORIGIN variables are never
  8574.                 initialized, you must initialize this file yourself.
  8575.  
  8576.  
  8577.  366            UNIT Identifier Expected Skip To ;
  8578.  
  8579.                 The compiler expects, but cannot find, an identifier after
  8580.                 the keyword USES.
  8581.  
  8582.  
  8583.  367            Initialize Module To Initialize UNIT
  8584.  
  8585.                 You must call the module as a procedure in order to
  8586.                 initialize it (a USES clause triggers a unit initialization
  8587.                 call).
  8588.  
  8589.  
  8590.  368            Identifier List Too Long Extra Assumed Integer
  8591.  Code           Message
  8592. 368            Identifier List Too Long Extra Assumed Integer
  8593.  
  8594.                 In a USES clause with a list of identifiers, the compiler
  8595.                 found more identifiers in the list than are constituents of
  8596.                 the interface. The extra ones are assumed to be type
  8597.                 identifiers identical to INTEGER.
  8598.  
  8599.  
  8600.  369            End Of UNIT Identifier List Ignored
  8601.  
  8602.                 In a USES clause with a list of identifiers, the compiler
  8603.                 found fewer identifiers in the list than are constituents of
  8604.                 the interface. The remaining interface constituents are not
  8605.                 provided as part of the USES clause.
  8606.  
  8607.  
  8608.  371            UNIT Identifier Expected
  8609.  
  8610.                 An identifier is missing after the phrase "INTERFACE; UNIT."
  8611.  
  8612.  Code           Message
  8613. 
  8614.  
  8615.  372            Compiler
  8616.  
  8617.                 Compiler expects, but cannot find, the keyword UNIT in an
  8618.                 INTERFACE.
  8619.  
  8620.  
  8621.  373            Identifier In UNIT List Not Declared
  8622.  
  8623.                 One of the identifiers in the interface UNIT list was not
  8624.                 declared in the body of the interface.
  8625.  
  8626.  
  8627.  374            Program Identifier Expected
  8628.  
  8629.                 An identifier is missing after the keyword PROGRAM or
  8630.                 MODULE. This is a "panic error" from which the compiler
  8631.                 cannot recover. The rest of the file is not compiled.
  8632.  
  8633.  Code           Message
  8634. 
  8635.  
  8636.  375            UNIT Identifier Expected
  8637.  
  8638.                 The unit identifier is missing after the phrase
  8639.                 "IMPLEMENTATION OF." This is a "panic error" from which the
  8640.                 compiler cannot recover. The rest of the file is not
  8641.                 compiled.
  8642.  
  8643.  
  8644.  376            Program Not Found
  8645.  
  8646.                 The compiler expects, but cannot find, one of the reserved
  8647.                 words PROGRAM, MODULE, or IMPLEMENTATION OF. This is a
  8648.                 "panic error" from which the compiler cannot recover. The
  8649.                 rest of the file is not compiled. (This error can occur if
  8650.                 the source file is not a Microsoft Pascal compiland.)
  8651.  
  8652.  
  8653.  377            File End Expected Skip To End
  8654.  Code           Message
  8655. 377            File End Expected Skip To End
  8656.  
  8657.                 The compiler found additional source text after what
  8658.                 appeared to be the end and ignored everything after that
  8659.                 point.
  8660.  
  8661.  
  8662.  378            Program Not Found
  8663.  
  8664.                 The compiler expected, but could not find, the main body of
  8665.                 a compiland, or the final END.
  8666.  
  8667.  
  8668.  F.3  Compiler Back End Errors
  8669.  
  8670.  The following errors cause immediate termination of the compilation. No
  8671.  object file is created. The main source of these errors is user error from
  8672.  either the optimizer or the code generator.
  8673.  
  8674. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  8675.  Code           Message
  8676.  ───────────────────────────────────────────────────────────────────────────
  8677.  900            Attempt to divide by zero.
  8678.  
  8679.                 For example you attempted A DIV 0.
  8680.  
  8681.  
  8682.  901            Overflow during integer constant folding.
  8683.  
  8684.                 For example, you attempted MAXINT + A + MAXINT.
  8685.  
  8686.  
  8687.  902            Expression too complex/Too many internal labels.
  8688.  
  8689.                 Try breaking up expression with intermediate value assigns.
  8690.  
  8691.  
  8692.  903            Too many procedures and/or functions.
  8693.  
  8694.                 Try breaking up compiland into modules or units.
  8695.  
  8696.  Code           Message
  8697. 
  8698.  
  8699.  904            Range error (number too large to fit into target).
  8700.  
  8701.  
  8702.  F.4  Runtime File System Errors (1000-1199)
  8703.  
  8704.  File system error codes range from 1000 to 1199. Error codes go into
  8705.  the ERRC field of the file control block. Codes from 1000 to 1099
  8706.  designate errors (from Unit U) that are specific to your operating system,
  8707.  while those codes from 1100 to 1199 identify Pascal file system errors
  8708.  (from Unit F).
  8709.  
  8710.  File system errors all have the format
  8711.  
  8712.  error type error in file filename
  8713.  
  8714.  followed by the error code, and in some versions an error status, which is
  8715.  an operating system error return word. The error type codes, based on the
  8716.  ERRS field of the file control block, are:
  8717.  
  8718. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  8719.  Code           Message
  8720.  ───────────────────────────────────────────────────────────────────────────
  8721.  1              Hard Data
  8722.  
  8723.                 Hard data error (parity, CRC, check sum, etc.).
  8724.  
  8725.  
  8726.  2              Device Name
  8727.  
  8728.                 Invalid unit/device/volume name, format, or number.
  8729.  
  8730.  
  8731.  3              Operation
  8732.  
  8733.                 Invalid operation:  GET if EOF, RESET a printer, etc.
  8734.  
  8735.  
  8736.  4              File System
  8737.  
  8738.  Code           Message
  8739. 
  8740.                 File system internal error, ERRS > 15, etc.
  8741.  
  8742.  
  8743.  5              Device Offline
  8744.  
  8745.                 Unit/device/volume no longer available.
  8746.  
  8747.  
  8748.  6              Lost File
  8749.  
  8750.                 File itself no longer available.
  8751.  
  8752.  
  8753.  7              File Name
  8754.  
  8755.                 Invalid syntax, name too long, no temporary names, etc.
  8756.  
  8757.  
  8758.  8              Device Full
  8759.  Code           Message
  8760. 8              Device Full
  8761.  
  8762.                 Disk full, directory full, all channels allocated.
  8763.  
  8764.  
  8765.  9              Unknown Device
  8766.  
  8767.                 Unit/device/volume not found.
  8768.  
  8769.  
  8770.  10             File Not Found
  8771.  
  8772.                 File itself not found.
  8773.  
  8774.  
  8775.  11             Protected File
  8776.  
  8777.                 Duplicate filename; write-protected.
  8778.  
  8779.  
  8780.  Code           Message
  8781. 
  8782.  12             File In Use
  8783.  
  8784.                 File in use, concurrency lock, already open.
  8785.  
  8786.  
  8787.  13             File Not Open
  8788.  
  8789.                 File closed, I/O to unopen FCB.
  8790.  
  8791.  
  8792.  14             Data Format
  8793.  
  8794.                 Data format error, decode error, range error.
  8795.  
  8796.  
  8797.  15             Line Too Long
  8798.  
  8799.                 Buffer overflow, line too long.
  8800.  
  8801.  
  8802.  F.4.1  Operating System Runtime Errors (1000-1099)
  8803.  
  8804.  Errors 1000 through 1048 are specific to the MS-DOS operating system:
  8805.  
  8806. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  8807.  Code           Message
  8808.  ───────────────────────────────────────────────────────────────────────────
  8809.  1000           Write error when writing end of file
  8810.  
  8811.  1002           Filename extension with more than 3 characters.
  8812.  
  8813.  1003           Error during creation of new file (disk or directory full.)
  8814.  
  8815.  1004           Error during open of existing file (file not found.)
  8816.  
  8817.  1005           Filename with more than 8 characters, or zero characters
  8818.  
  8819.  1007           Total filename length over 21 characters.
  8820.  
  8821.  1008           Write error when advancing to next record.
  8822.  Code           Message
  8823. 1008           Write error when advancing to next record.
  8824.  
  8825.  1009           File too big (over 65535 logical sectors).
  8826.  
  8827.  1010           Write error when seeking to direct record.
  8828.  
  8829.  1011           Attempt to open a random file to a nondisk device
  8830.  
  8831.  1027           Filename error
  8832.  
  8833.  1028           Device full error
  8834.  
  8835.  1030           File system
  8836.  
  8837.  1031           Operation
  8838.  
  8839.  1032           File not found
  8840.  
  8841.  1033           File not found
  8842.  
  8843.  Code           Message
  8844. 
  8845.  1034           File system
  8846.  
  8847.  1035           Protected file
  8848.  
  8849.  1036           File system
  8850.  
  8851.  1037           File system
  8852.  
  8853.  1038           File system
  8854.  
  8855.  1039           File system
  8856.  
  8857.  1040           File system
  8858.  
  8859.  1041           Data format
  8860.  
  8861.  1042           File system
  8862.  
  8863.  1043           Data format
  8864.  Code           Message
  8865. 1043           Data format
  8866.  
  8867.  1044           File system
  8868.  
  8869.  1045           Unknown Device
  8870.  
  8871.  1046           File system
  8872.  
  8873.  1047           File system
  8874.  
  8875.  1048           File system
  8876.  
  8877.  
  8878.  F.4.2  Microsoft Pascal File System Errors (1100-1199)
  8879.  
  8880. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  8881.  Code           Message
  8882.  ───────────────────────────────────────────────────────────────────────────
  8883.  1100           ASSIGN or READFN of filename to open file
  8884.  
  8885.  Code           Message
  8886. 
  8887.                 This error is only caught for textfiles.
  8888.  
  8889.  1101           Reference to buffer variable of closed textfile
  8890.  
  8891.  1102           Textfile READ or WRITE call to closed file
  8892.  
  8893.  1103           READ when EOF is true (SEQUENTIAL mode)
  8894.  
  8895.  1104           READ to REWRITE file, or WRITE to RESET file (SEQUENTIAL
  8896.                 mode)
  8897.  
  8898.  1105           EOF call to closed file
  8899.  
  8900.  1106           GET call to closed file
  8901.  
  8902.  1107           GET call when EOF is true (SEQUENTIAL mode)
  8903.  
  8904.  1108           GET call to REWRITE file (SEQUENTIAL mode)
  8905.  
  8906.  Code           Message
  8907. 
  8908.  1109           PUT call to closed file
  8909.  
  8910.  1110           PUT call to RESET file (SEQUENTIAL mode)
  8911.  
  8912.  1111           Line too long in DIRECT textfile
  8913.  
  8914.  1112           Decode error in textfile READ BOOLEAN
  8915.  
  8916.  1113           Value out of range in textfile READ CHAR
  8917.  
  8918.  1114           Decode error in textfile READ INTEGER
  8919.  
  8920.  1115           Decode error in textfile READ SINT (integer subrange)
  8921.  
  8922.  1116           Decode error in textfile READ REAL
  8923.  
  8924.  1117           LSTRING target not big enough in READSET
  8925.  
  8926.  1118           Decode error in textfile READ WORD
  8927.  Code           Message
  8928. 1118           Decode error in textfile READ WORD
  8929.  
  8930.  1119           Decode error in textfile READ BYTE (word subrange)
  8931.  
  8932.  1120           SEEK call to closed file
  8933.  
  8934.  1121           SEEK call to file not in DIRECT mode
  8935.  
  8936.  1122           Encode error (field width > 255) in textfile WRITE BOOLEAN
  8937.  
  8938.  1123           Encode error (field width > 255) in textfile WRITE INTEGER
  8939.  
  8940.  1124           Encode error (field width > 255) in textfile WRITE REAL
  8941.  
  8942.  1125           Encode error (field width > 255) in textfile WRITE WORD
  8943.  
  8944.  1126           Decode error (field width > 255) in textfile READ INTEGER4
  8945.  
  8946.  1127           Encode error (field width > 255) in textfile WRITE INTEGER4
  8947.  
  8948.  
  8949.  F.4.3  Other Runtime Errors (2000-2999)
  8950.  
  8951.  Nonfile system error codes range from 2000 to 2999. In some cases,
  8952.  metacommands control whether or not the compiler checks for the error. In
  8953.  other cases, the compiler always checks. The list below indicates which, if
  8954.  any, metacommand controls the error checking.
  8955.  
  8956.  
  8957.  F.4.4  Memory Errors (2000-2049)
  8958.  
  8959. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  8960.  Code           Message
  8961.  ───────────────────────────────────────────────────────────────────────────
  8962.  2000           Stack Overflow
  8963.  
  8964.                 The stack (frame) ran out of memory while calling a
  8965.                 procedure or function. This condition is checked if the
  8966.                 $stackck metacommand is on, and may be checked in some other
  8967.                 cases.
  8968.  
  8969.  Code           Message
  8970. 
  8971.  
  8972.  2001           No Room In Heap
  8973.  
  8974.                 The heap ran out of room for a new variable during the NEW
  8975.                 (GETHQQ) procedure.
  8976.  
  8977.  
  8978.  2002           Heap Is Invalid
  8979.  
  8980.                 During the NEW (GETHQQ) procedure, the allocation algorithm
  8981.                 discovered the heap structure is corrupt.
  8982.  
  8983.  
  8984.  2003           Heap Allocator Interrupted
  8985.  
  8986.                 An interrupt procedure interrupted NEW (GETHQQ) and did a
  8987.                 NEW call itself. The heap allocator modifies the heap, so it
  8988.                 is a critical section. This error is not caught in this
  8989.                 version.
  8990.  Code           Message
  8991.                version.
  8992.  
  8993.  
  8994.  2004           Allocation Internal Error
  8995.  
  8996.                 There was an unexpected error return when GETHQQ was
  8997.                 requesting additional heap space from the operating system.
  8998.                 Please report occurrences of this error to Microsoft
  8999.                 Corporation.
  9000.  
  9001.  
  9002.  2031           NIL Pointer Reference
  9003.  
  9004.                 DISPOSE or $nilck+ found a pointer with a NIL (i.e., 0)
  9005.                 value.
  9006.  
  9007.  
  9008.  2032           Uninitialized Pointer
  9009.  
  9010.                 DISPOSE or $nilck+ found an uninitialized (value 1) pointer.
  9011.  Code           Message
  9012.                DISPOSE or $nilck+ found an uninitialized (value 1) pointer.
  9013.                 This occurs only if the metacommand $initck is on.
  9014.  
  9015.  
  9016.  2033           Invalid Pointer Range
  9017.  
  9018.                 DISPOSE or $nilck+ found a pointer that does not point into
  9019.                 the heap or is otherwise invalid. (It may have pointed to a
  9020.                 disposed block that was removed from the heap and given back
  9021.                 to the system.)
  9022.  
  9023.  
  9024.  2034           Pointer To Disposed Var
  9025.  
  9026.                 DISPOSE or $nilck+ found a pointer to a heap block that has
  9027.                 been disposed. Calling DISPOSE twice for the same variable
  9028.                 is invalid.
  9029.  
  9030.  
  9031.  2035           Long DISPOSE Sizes Unequal
  9032.  Code           Message
  9033. 2035           Long DISPOSE Sizes Unequal
  9034.  
  9035.                 In a long form of DISPOSE, the actual length of the variable
  9036.                 did not equal the length based on the tag values given.
  9037.  
  9038.  
  9039.  F.4.5  Ordinal Arithmetic Errors (2050-2099)
  9040.  
  9041. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  9042.  Code           Message
  9043.  ───────────────────────────────────────────────────────────────────────────
  9044.  2050           No CASE Value Matches Selector
  9045.  
  9046.                 In a CASE statement without an OTHERWISE clause, none of the
  9047.                 branch statements had a CASE constant value equal to the
  9048.                 selector expression value. This error is checked only if the
  9049.                 $rangeck metacommand is on.
  9050.  
  9051.  
  9052.  2051           Unsigned Divide By Zero
  9053.  Code           Message
  9054. 2051           Unsigned Divide By Zero
  9055.  
  9056.                 A WORD value was divided by zero. This error is checked only
  9057.                 if the $mathck metacommand is on.
  9058.  
  9059.  
  9060.  2052           Signed Divide By Zero
  9061.  
  9062.                 An INTEGER value was divided by zero. This error is checked
  9063.                 only if the $mathck metacommand is on.
  9064.  
  9065.  
  9066.  2053           Unsigned Math Overflow
  9067.  
  9068.                 A WORD result is outside the range zero to MAXWORD. This
  9069.                 error is checked only if the $mathck metacommand is on.
  9070.  
  9071.  
  9072.  2054           Signed Math Overflow
  9073.  
  9074.  Code           Message
  9075. 
  9076.                 An INTEGER result is outside the range from -MAXINT to
  9077.                 +MAXINT. This error is checked only if the $mathck
  9078.                 metacommand is on.
  9079.  
  9080.  
  9081.  2055           Unsigned Value Out Of Range
  9082.  
  9083.                 The source value for assignment or value parameter is out of
  9084.                 range for the target value. The target may be a subrange of
  9085.                 WORD (including BYTE), or CHAR, or an enumerated type. This
  9086.                 error can also occur in SUCC and PRED functions and when the
  9087.                 length of an LSTRING is assigned. All of these conditions
  9088.                 are checked if the $rangeck metacommand is on.
  9089.  
  9090.                 The error also occurs when an array index is out of bounds
  9091.                 and the array has an unsigned index type. This condition is
  9092.                 checked when the $indexck metacommand is on.
  9093.  
  9094.  
  9095.  Code           Message
  9096. 
  9097.  2056           Signed Value Out Of Range
  9098.  
  9099.                 This error is similar to message 2055, but applies to the
  9100.                 INTEGER type and its subranges.
  9101.  
  9102.  
  9103.  2057           Uninitialized 16 Bit Integer Used
  9104.  
  9105.                 Either an INTEGER or 16-bit INTEGER subrange variable is
  9106.                 used without being assigned first, or such a variable has
  9107.                 the invalid value of -32768. This condition is checked if
  9108.                 the $initck metacommand is on.
  9109.  
  9110.  
  9111.  2058           Uninitialized 8 Bit Integer Used
  9112.  
  9113.                 Either a SINT or 8-bit INTEGER subrange variable is used
  9114.                 without being assigned first, or such a variable has the
  9115.                 invalid value of -128. This condition is checked if the
  9116.  Code           Message
  9117.                invalid value of -128. This condition is checked if the
  9118.                 $initck metacommand is on.
  9119.  
  9120.  
  9121.  2084           Integer Zero To Negative Power
  9122.  
  9123.                 There was an attempt to raise zero to a negative power.
  9124.  
  9125.  
  9126.  F.4.6  Type REAL Arithmetic Errors (2100-2149)
  9127.  
  9128. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  9129.  Code           Message
  9130.  ───────────────────────────────────────────────────────────────────────────
  9131.  2100           REAL Divide By Zero
  9132.  
  9133.                 A REAL value is divided by zero.
  9134.  
  9135.  
  9136.  2101           REAL Math Overflow
  9137.  Code           Message
  9138. 2101           REAL Math Overflow
  9139.  
  9140.                 A REAL value is too large for representation.
  9141.  
  9142.  
  9143.  2102           SIN or COS Argument Range
  9144.  
  9145.                 The parameter for a SIN or COS function is too large to
  9146.                 yield a meaningful result.
  9147.  
  9148.  
  9149.  2103           EXP Argument Range
  9150.  
  9151.                 The parameter for an EXP function is too large to yield a
  9152.                 result that fits in representation.
  9153.  
  9154.  
  9155.  2104           SQRT of Negative Argument
  9156.  
  9157.                 The parameter for a square root function is less than
  9158.  Code           Message
  9159.                The parameter for a square root function is less than
  9160.                 zero.
  9161.  
  9162.  
  9163.  2105           LN of Non-Positive Argument
  9164.  
  9165.                 The parameter of a natural log function is less than or
  9166.                 equal to zero.
  9167.  
  9168.  
  9169.  2106           TRUNC/ROUND Argument Range
  9170.  
  9171.                 The REAL parameter of a TRUNC, TRUNC4, ROUND, or ROUND4
  9172.                 function is outside the range of INTEGERs.
  9173.  
  9174.  
  9175.  2131           Arctan Argument 0
  9176.  
  9177.                 The parameter for a TANRQQ function is so small that the
  9178.                 result is invalid.
  9179.  Code           Message
  9180.                result is invalid.
  9181.  
  9182.  
  9183.  2132           Arcsin or Arccos of REAL > 1.0
  9184.  
  9185.                 The parameter of an ASNRQQ or ACSRQQ function is greater
  9186.                 than one.
  9187.  
  9188.  
  9189.  2133           Negative Real To Real Power
  9190.  
  9191.                 The first argument of an PRDRQQ or PRSRQQ function is less
  9192.                 than zero.
  9193.  
  9194.  
  9195.  2134           Real Zero To Negative Power
  9196.  
  9197.                 There was an attempt to raise zero to a negative power in
  9198.                 one of the functions PISRQQ, PIDRQQ, PRDRQQ, or PRSRQQ.
  9199.  
  9200.  Code           Message
  9201. 
  9202.  
  9203.  2135           REAL Math Underflow
  9204.  
  9205.                 The significance of a REAL expression has been reduced to
  9206.                 zero.
  9207.  
  9208.  
  9209.  2136           REAL Indefinite (Uninitialized Or Previous Error)
  9210.  
  9211.                 The REAL value called "infinity" was encountered. This may
  9212.                 occur if the $initck metacommand is on and an uninitialized
  9213.                 REAL value is used, or if a previous error set a variable to
  9214.                 indefinite as part of its masked error response.
  9215.  
  9216.  
  9217.  2137           Missing Arithmetic Processor
  9218.  
  9219.                 You linked your program with the runtime library intended
  9220.                 for use with the 80287 numeric coprocessor, but there is no
  9221.  Code           Message
  9222.                for use with the 80287 numeric coprocessor, but there is no
  9223.                 coprocessor on your system. Relink your program with the
  9224.                 runtime library that emulates floating-point arithmetic.
  9225.  
  9226.  
  9227.  2138           REAL IEEE Denormal Detected
  9228.  
  9229.                 A very small real number was generated and may no longer be
  9230.                 valid due to loss of significance.
  9231.  
  9232.  
  9233.  2139           REAL Precision Loss
  9234.  
  9235.                 An arithmetic operation on the 80287 numeric coprocessor has
  9236.                 generated a loss of numeric precision in the result of an
  9237.                 operation.
  9238.  
  9239.  
  9240.  2140           REAL Arithmetic Processor Instruction Illegal Or Not
  9241.                 Emulated
  9242.  Code           Message
  9243.                Emulated
  9244.  
  9245.                 An attempt was made to execute an illegal arithmetic
  9246.                 coprocessor instruction, or the floating-point emulator
  9247.                 cannot emulate a legal coprocessor instruction.
  9248.  
  9249.  
  9250.  2145           Real Stack Overflow
  9251.  
  9252.                 Using the alternate math package and expression, too many
  9253.                 real operands were encountered.
  9254.  
  9255.  
  9256.  F.4.7  Structured Type Errors (2150-2199)
  9257.  
  9258. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  9259.  Code           Message
  9260.  ───────────────────────────────────────────────────────────────────────────
  9261.  2150           String Too Long in COPYSTR
  9262.  
  9263.  Code           Message
  9264. 
  9265.                 The source string for a COPYSTR intrinsic function is too
  9266.                 large for the target string.
  9267.  
  9268.  
  9269.  2151           Lstring Too Long In Intrinsic Procedure
  9270.  
  9271.                 The target LSTRING is too small in an INSERT, DELETE,
  9272.                 CONCAT, or COPYLST intrinsic procedure.
  9273.  
  9274.  
  9275.  2180           Set Element Greater Than 255
  9276.  
  9277.                 The value in a constructed set exceeds the maximum of 255.
  9278.  
  9279.  
  9280.  2181           Set Element Out Of Range
  9281.  
  9282.                 The value in a set assignment or set value parameter is too
  9283.                 large for the target set. This error is caught only if the
  9284.  Code           Message
  9285.                large for the target set. This error is caught only if the
  9286.                 $rangeck metacommand is on.
  9287.  
  9288.  
  9289.  F.4.8  INTEGER4 Errors (2200-2249)
  9290.  
  9291. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  9292.  Code           Message
  9293.  ───────────────────────────────────────────────────────────────────────────
  9294.  2200           Long Integer Divide By Zero
  9295.  
  9296.                 An INTEGER4 value is divided by zero.
  9297.  
  9298.  
  9299.  2201           Long Integer Math Overflow
  9300.  
  9301.                 An INTEGER4 value is too large for representation.
  9302.  
  9303.  
  9304.  2234           Long Integer Zero To Negative Power
  9305.  Code           Message
  9306. 2234           Long Integer Zero To Negative Power
  9307.  
  9308.                 There was an attempt to raise zero to a negative power.
  9309.  
  9310.  
  9311.  F.4.9  Other Errors (2400-2999)
  9312.  
  9313. ╓┌──────────────┌────────────────────────────────────────────────────────────╖
  9314.  Code           Message
  9315.  ───────────────────────────────────────────────────────────────────────────
  9316.  2450           Unit Version Number Mismatch
  9317.  
  9318.                 During unit initialization, the user (contains the USES
  9319.                 clause) and implementation of an interface were discovered
  9320.                 to have been compiled with unequal interface version
  9321.                 numbers.
  9322.  
  9323.  
  9324.  F.5  Unnumbered Error Messages
  9325.  
  9326.  Compiler Cannot Continue
  9327.  
  9328.    This error occurs under the following circumstances:
  9329.  
  9330.    ■ There are more errors than the number set by the $errors metacommand.
  9331.  
  9332.    ■ An end-of-file occurs when not expected.
  9333.  
  9334.    ■ Identifier scopes are nested too deeply.
  9335.  
  9336.    ■ The compiler cannot find the keyword PROGRAM, MODULE, or
  9337.      IMPLEMENTATION.
  9338.  
  9339.    ■ The compiler cannot find the PROGRAM, MODULE, or IMPLEMENTATION
  9340.      identifier.
  9341.  
  9342.    ■ A file system error occurs. File system error messages include the
  9343.      filename and one of the following phrases:
  9344.  
  9345.      HARD DATA     (check sum error)
  9346.      DISK FULL     (disk is full)
  9347.      FILE ACCESS   (file not found)
  9348.      FILE SYSTEM   (other or internal error)
  9349.  
  9350.  
  9351.  Error: Compiler Internal Error
  9352.  
  9353.    This error signifies a serious problem with the compiler. This message
  9354.    should never occur; if it does please report it to Microsoft Corporation.
  9355.    There isn't much you can do if this error occurs except perhaps modify
  9356.    your program near the line where the error occurred.
  9357.  
  9358.  
  9359.  Error: Compiler Out of Memory
  9360.  
  9361.    This error usually occurs when too many identifiers have been declared.
  9362.    Refer to Section 3.2, "Working With Large Programs" for suggestions on
  9363.    how to avoid this problem.
  9364.  
  9365.  
  9366.  F.6  Linker Error Messages
  9367.  
  9368.  This section lists the error messages that can occur when linking programs.
  9369.  The messages are in alphabetical order.
  9370.  
  9371.  About to generate .EXE file. Change diskette in drive A: and press ENTER.
  9372.  
  9373.    This message appears before the .EXE has been written if the /P switch is
  9374.    given. Insert diskette that the .EXE file is to be written to into the
  9375.    specified drive (Drive A, for example).
  9376.  
  9377.  
  9378.  Ambiguous switch error: 'x'
  9379.  
  9380.    You did not enter a correct switch name after the switch indicator '/'.
  9381.    For example, the command
  9382.  
  9383.    A>LINK /N main;
  9384.  
  9385.    will generate this error. LINK will abort.
  9386.  
  9387.  
  9388.  Attempt to put segment name in more than one group in file filename
  9389.  
  9390.    A segment was declared to be a member of two different groups. Correct
  9391.    the source and recreate the object files.
  9392.  
  9393.  
  9394.  Cannot find library: filename.lib. Enter new file spec:
  9395.  
  9396.    The linker cannot find filename.lib and is requesting a new file name or
  9397.    a new path specification or both. Respond to the prompt with a new
  9398.    filename or a new path specification.
  9399.  
  9400.  
  9401.  Cannot open list file
  9402.  
  9403.    The directory or disk is full. Make space on the disk or in the
  9404.    directory.
  9405.  
  9406.  
  9407.  Cannot open response file
  9408.  
  9409.    You named a response file the linker cannot open. You have probably made
  9410.    a typing mistake.
  9411.  
  9412.  
  9413.  Cannot nest response files
  9414.  
  9415.    You named another response file in the response file. Fix the file and
  9416.    relink.
  9417.  
  9418.  
  9419.  Cannot open run file
  9420.  
  9421.    The directory or disk is full. Make space on the disk or in the
  9422.    directory.
  9423.  
  9424.  
  9425.  Cannot open temporary file
  9426.  
  9427.    The directory or disk is full. Make space on the disk or in the
  9428.    directory.
  9429.  
  9430.  
  9431.  Cannot reopen list file
  9432.  
  9433.    You did not replace the original disk when prompted to. Restart the
  9434.    linker.
  9435.  
  9436.  
  9437.  Data record too large
  9438.  
  9439.    The LEDATA record (in an object module) contains more than 1024 bytes of
  9440.    data. This is a translator error. Note the translator (compiler or
  9441.    assembler) that produced the incorrect object module and the
  9442.    circumstances under which it was produced, and report the information to
  9443.    Microsoft Corporation.
  9444.  
  9445.  
  9446.  Dup record too large
  9447.  
  9448.    The LIDATA record (in an object module) contains more than 512 bytes of
  9449.    data. Most likely, an assembly module contains a struc definition that is
  9450.    very complex, or a series of deeply nested DUP statements (e.g. ARRAY db
  9451.    10 dup (11 dup (12 dup (13 dup (...))))). Simplify the module and
  9452.    reassemble it.
  9453.  
  9454.  
  9455.  filename is not a valid library
  9456.  
  9457.    The file specified as a library is invalid. LINK will abort.
  9458.  
  9459.  
  9460.  Fixup overflow near num in segment name in filename(name) offset num
  9461.  
  9462.    Some possible causes of this message are:
  9463.  
  9464.    1.  A group is larger than 64K bytes
  9465.  
  9466.    2.  Your program contains an intersegment short jump or intersegment
  9467.        short call
  9468.  
  9469.    3.  You have a data item whose name conflicts with that of a subroutine
  9470.        in a library included in the link, and
  9471.  
  9472.    4.  You have an EXTRN declaration inside the body of a segment, for
  9473.        example:
  9474.  
  9475.        CODE            segment public 'code'
  9476.        extrn           main:far
  9477.        start           proc    far
  9478.                        call    main
  9479.                        ret
  9480.        start           endp
  9481.        CODE            ends
  9482.  
  9483.        The following construction is preferred:
  9484.  
  9485.        extrn           main:far
  9486.        CODE            segment public 'code'
  9487.        start           proc    far
  9488.                        call    main
  9489.                        ret
  9490.        start           endp
  9491.        CODE            ends
  9492.  
  9493.    Revise the source and recreate the object file.
  9494.  
  9495.  
  9496.  Incorrect DOS version, use DOS 2.0 or later
  9497.  
  9498.    LINK runs only on MS-DOS Version 2.0 or higher. Restart your system
  9499.    using the correct MS-DOS version and try linking again.
  9500.  
  9501.  
  9502.  Insufficient stack space
  9503.  
  9504.    There is not enough memory to run the linker.
  9505.  
  9506.  
  9507.  Interrupt number exceeds 255
  9508.  
  9509.    You have specified a number greater than 255 after the /OVERLAYINTERRUPT
  9510.    switch. Try again with a number in the range 4 to 255.
  9511.  
  9512.  
  9513.  Invalid numeric switch specification
  9514.  
  9515.    You have probably made a typographical error when you entered a value for
  9516.    one of the linker switches, such as entering a character string for a
  9517.    switch that requires a numeric value. LINK will abort.
  9518.  
  9519.  
  9520.  Invalid object module
  9521.  
  9522.    One of the object modules is invalid. Try recompiling. If the error
  9523.    persists, contact Microsoft Corporation.
  9524.  
  9525.  
  9526.  Nested left parentheses
  9527.  
  9528.    You have probably made a typing mistake while specifying the contents of
  9529.    an overlay on the command line.
  9530.  
  9531.  
  9532.  No object modules specified
  9533.  
  9534.    You didn't give the linker an object file name.
  9535.  
  9536.  
  9537.  Out of space on list file
  9538.  
  9539.    The disk on which the list file is being written is full. Free more
  9540.    space on the disk and try again.
  9541.  
  9542.  
  9543.  Out of space on run file
  9544.  
  9545.    The disk on which the .EXE file is being written is full. Free more
  9546.    space on the disk and try again.
  9547.  
  9548.  
  9549.  Out of space on scratch file
  9550.  
  9551.    The disk in the  default drive is full. Delete some files on that disk,
  9552.    or replace with another disk, and restart the linker.
  9553.  
  9554.  
  9555.  Overlay manager symbol already defined: name
  9556.  
  9557.    You have defined a symbol name that conflicts with one of the special
  9558.    overlay manager names. Change the symbol name and relink.
  9559.  
  9560.  
  9561.  Please replace original disk in drive A: and press ENTER.
  9562.  
  9563.    This  message appears after the .EXE file has been written if the /P
  9564.    switch is used. Insert the disk with the list file so that it can be
  9565.    reopened.
  9566.  
  9567.  
  9568.  Relocation table overflow
  9569.  
  9570.    You have more than 16384 long calls, long jumps or other long pointers in
  9571.    your program. First try turning debugging off, then try rewriting the
  9572.    program, replacing long references with short references where possible.
  9573.    Then recreate the object module.
  9574.  
  9575.  
  9576.  Segment limit set too high
  9577.  
  9578.    Using the /SEGMENTS switch, you set the limit too high. LINK will abort.
  9579.  
  9580.  
  9581.  Segment limit too high
  9582.  
  9583.    There is not enough memory for the linker to allocate tables to describe
  9584.    the number of segments requested (either the value specified with
  9585.    /SEGMENTS or the default: 128). Either try the link again using
  9586.    /SEGMENTS to select a smaller number of segments (e.g. 64, if the default
  9587.    were used previously) or free some memory.
  9588.  
  9589.  
  9590.  Segment size exceeds 64K
  9591.  
  9592.    You have a small model program with more than 64K bytes of code.
  9593.  
  9594.  
  9595.  Stack size exceeds 65536 bytes
  9596.  
  9597.    The size specified for the stack with the /STACK switch is more than
  9598.    65536 bytes.
  9599.  
  9600.  
  9601.  Symbol table overflow
  9602.  
  9603.    Your program has more than 256K of symbolic information (Publics, extrns,
  9604.    segments, groups, classes, files, etc). Combine modules and/or segments
  9605.    and recreate the object files. Eliminate as many public symbols as
  9606.    possible.
  9607.  
  9608.  
  9609.  Terminated by user
  9610.  
  9611.    You entered Ctrl-C while the linker was executing.
  9612.  
  9613.  
  9614.  Too many external symbols in one module
  9615.  
  9616.    Your object module specified more than the allowed number of external
  9617.    symbols. Break up the module.
  9618.  
  9619.  
  9620.  Too many group-, segment-, and class-names in one module
  9621.  
  9622.    Your program contains too many  group,  segment,  and class names.
  9623.    Reduce the number of groups, segments, or classes and recreate the object
  9624.    files.
  9625.  
  9626.  
  9627.  Too many groups
  9628.  
  9629.    Your program defines more than nine groups. Reduce the number of groups.
  9630.  
  9631.  
  9632.  Too many GRPDEFs in one module
  9633.  
  9634.    LINK encountered more than nine GRPDEFs in a single module. Reduce the
  9635.    number of GRPDEFs or split up the module.
  9636.  
  9637.  
  9638.  Too many libraries
  9639.  
  9640.    You tried to link with more than 16 libraries. Combine libraries or link
  9641.    modules that require fewer libraries.
  9642.  
  9643.  
  9644.  Too many overlays
  9645.  
  9646.    Your program defines more than 63 overlays. Reduce the number of
  9647.    overlays.
  9648.  
  9649.  
  9650.  Too many segments
  9651.  
  9652.    Your program has too many segments. Relink using the /SEGMENTS switch
  9653.    with an appropriate number of segments specified.
  9654.  
  9655.  
  9656.  Too many segments in one module
  9657.  
  9658.    Your object module has more than 255 segments. Split the modules or
  9659.    combine segments.
  9660.  
  9661.  
  9662.  Unexpected end-of-file on library
  9663.  
  9664.    The disk containing the library has probably been removed. Try again
  9665.    after inserting the disk that contains the library.
  9666.  
  9667.  
  9668.  Unexpected end-of-file on scratch file
  9669.  
  9670.    The disk containing VM.TMP was removed. Replace it and restart the
  9671.    linker.
  9672.  
  9673.  
  9674.  Unmatched left parenthesis
  9675.  
  9676.    You have made a typing mistake while specifying the contents of an
  9677.    overlay on the command line.
  9678.  
  9679.  
  9680.  Unmatched right parenthesis
  9681.  
  9682.    You have made a typing mistake while specifying the contents of an
  9683.    overlay on the command line.
  9684.  
  9685.  
  9686.  Unrecognized switch error: 'filename'
  9687.  
  9688.    You entered an unrecognized character after the switch indicator '/',
  9689.    such as:
  9690.  
  9691.    A>LINK /ABCDEF main;
  9692.  
  9693.    LINK will abort.
  9694.  
  9695.  
  9696.  VM.TMP is an illegal file name and has been ignored
  9697.  
  9698.    You have used VM.TMP as an object file name. Rename the file and link
  9699.    again.
  9700.  
  9701.  
  9702.  Warning: no stack segment
  9703.  
  9704.    Your program contains no segment of combine-type stack.
  9705.  
  9706.  
  9707.  Warning: too many local symbols
  9708.  
  9709.    You have asked for a sorted listing of local symbols in the list file,
  9710.    but there are too many symbols to sort. The linker will produce an
  9711.    unsorted listing of the local symbols.
  9712.  
  9713.  
  9714.  Warning: too many public symbols
  9715.  
  9716.    You have asked for a sorted listing of public symbols in the list file,
  9717.    but there are too many symbols to sort. The linker will produce an
  9718.    unsorted listing of the public symbols.
  9719.  
  9720.  
  9721.  F.7  EXEPACK Error Messages
  9722.  
  9723.  filename : No such file or directory
  9724.  
  9725.    The given file can't be found.
  9726.  
  9727.  
  9728.  filename: Permission denied
  9729.  
  9730.    You tried to use the EXEPACK utility on a read-only file.
  9731.  
  9732.  
  9733.  can't change load-high program
  9734.  
  9735.    when the minimum allocation value and the maximum allocation value are
  9736.    both zero, the file cannot be compressed.
  9737.  
  9738.  
  9739.  error reading relocation table
  9740.  
  9741.    The file cannot be compressed because the relocation table cannot be
  9742.    found or is invalid.
  9743.  
  9744.  
  9745.  invalid .EXE file (actual length < reported)
  9746.  
  9747.    The second and third fields in the header indicated a file size greater
  9748.    than the actual size.
  9749.  
  9750.  
  9751.  invalid .EXE format (bad header)
  9752.  
  9753.    The given file is not an executable file or has an invalid file header.
  9754.  
  9755.  
  9756.  out of memory
  9757.  
  9758.    There is not enough memory for the EXEPACK utility to operate.
  9759.  
  9760.  
  9761.  too many segments in relocation table
  9762.  
  9763.    The given file is too large to compressed in the available system memory.
  9764.  
  9765.  
  9766.  usage: exepack infile [outfile]
  9767.  
  9768.    You mistyped the command.
  9769.  
  9770.  You may also encounter MS-DOS error messages if the EXEPACK program
  9771.  cannot read, write to, or create a file.
  9772.  
  9773.  
  9774.  F.8  EXEMOD Error Messages
  9775.  
  9776.  filename: No such file or directory
  9777.  
  9778.    The given file cannot be found.
  9779.  
  9780.  
  9781.  filename: Permission denied
  9782.  
  9783.    The given file is read-only.
  9784.  
  9785.  
  9786.  can't change load-high program
  9787.  
  9788.    When the minimum allocation value and the maximum allocation value are
  9789.    both zero, the file cannot be modified.
  9790.  
  9791.  
  9792.  file not .EXE:filename
  9793.  
  9794.    EXEMOD automatically appends the .EXE extension to any filename without
  9795.    an extension. In this case, no file with the given name and an .EXE
  9796.    extension could be found.
  9797.  
  9798.  
  9799.  invalid .EXE file (actual length < reported)
  9800.  
  9801.    The second and third fields in the file header indicate a file size
  9802.    greater than the actual size.
  9803.  
  9804.  
  9805.  invalid .EXE file (bad header)
  9806.  
  9807.    Your executable file is not in the correct format.
  9808.  
  9809.  
  9810.  min > max (correcting max)
  9811.  
  9812.    If the minimum allocation value is greater than the minimum allocation
  9813.    value, the maximum allocation value is adjusted. (Note: this is a warning
  9814.    message only; the modification is still performed.)
  9815.  
  9816.  
  9817.  min > stack (correcting min)
  9818.  
  9819.    If the minimum allocation value is not enough to accommodate the stack
  9820.    (either the original stack request or the modified request), the minimum
  9821.    allocation value is adjusted. (Note: this is a warning message only; the
  9822.    modification is still performed.)
  9823.  
  9824.  
  9825.  usage: exemod file [-/h] [-/stack n] [-/max n] [-/min n]
  9826.  
  9827.    You mistyped the command.
  9828.  
  9829.  The EXEMOD utility also produces error messages when the file header
  9830.  is not in recognizable ".EXE" format, or if errors occur in reading or
  9831.  writing to a file.
  9832.  
  9833.